mirror of
https://github.com/farcasclaudiu/PracticeCalendar.git
synced 2026-06-22 07:01:16 +03:00
Binary file not shown.
@@ -1,6 +1,9 @@
|
|||||||
using MapsterMapper;
|
using Mapster;
|
||||||
|
using MapsterMapper;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using PracticeCalendar.Application.PracticeEvents.Queries;
|
||||||
|
using PracticeCalendar.Domain.Entities;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace PracticeCalendar.Application
|
namespace PracticeCalendar.Application
|
||||||
@@ -9,10 +12,25 @@ namespace PracticeCalendar.Application
|
|||||||
{
|
{
|
||||||
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
|
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<IMapper>(new Mapper(new Mapster.TypeAdapterConfig()));
|
services.AddMapsterMappings();
|
||||||
services.AddMediatR(Assembly.GetExecutingAssembly());
|
services.AddMediatR(Assembly.GetExecutingAssembly());
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IServiceCollection AddMapsterMappings(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
TypeAdapterConfig.GlobalSettings.Default.MapToConstructor(true);
|
||||||
|
TypeAdapterConfig.GlobalSettings.NewConfig<PracticeEventDto, PracticeEvent>()
|
||||||
|
.ConstructUsing(src => new PracticeEvent(src.Title, src.Description, src.StartTime, src.EndTime));
|
||||||
|
|
||||||
|
var mapsterConfig = new TypeAdapterConfig();
|
||||||
|
mapsterConfig.NewConfig<PracticeEventDto, PracticeEvent>()
|
||||||
|
.MapToConstructor(true)
|
||||||
|
.ConstructUsing(src => new PracticeEvent(src.Title, src.Description, src.StartTime, src.EndTime));
|
||||||
|
services.AddSingleton<IMapper>(new Mapper(mapsterConfig));
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace PracticeCalendar.Application.PracticeEvents.Commands
|
|||||||
public async Task<PracticeEventDto> Handle(CreatePracticeEventCommand request, CancellationToken cancellationToken)
|
public async Task<PracticeEventDto> Handle(CreatePracticeEventCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var input = request.Event;
|
var input = request.Event;
|
||||||
var practiceEvent = new PracticeEvent(input.Title, input.Description);
|
var practiceEvent = new PracticeEvent(input.Title, input.Description, input.StartTime, input.EndTime);
|
||||||
foreach (var att in input.Attendees)
|
foreach (var att in input.Attendees)
|
||||||
{
|
{
|
||||||
practiceEvent.AddAttendee(new Attendee(att.Name, att.EmailAddress));
|
practiceEvent.AddAttendee(new Attendee(att.Name, att.EmailAddress));
|
||||||
|
|||||||
@@ -11,12 +11,14 @@ namespace PracticeCalendar.Domain.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class PracticeEvent : EntityBase, IAggregateRoot
|
public class PracticeEvent : EntityBase, IAggregateRoot
|
||||||
{
|
{
|
||||||
public PracticeEvent(string title, string description)
|
public PracticeEvent(string title, string description, DateTime startTime, DateTime endTime)
|
||||||
{
|
{
|
||||||
Guard.Against.NullOrEmpty(title, nameof(title));
|
Guard.Against.NullOrEmpty(title, nameof(title));
|
||||||
Guard.Against.NullOrEmpty(description, nameof(description));
|
Guard.Against.NullOrEmpty(description, nameof(description));
|
||||||
this.Title = title;
|
this.Title = title;
|
||||||
this.Description = description;
|
this.Description = description;
|
||||||
|
this.StartTime = startTime;
|
||||||
|
this.EndTime = endTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Title { get; private set; } = string.Empty;
|
public string Title { get; private set; } = string.Empty;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace PracticeCalendar.Infrastructure
|
|||||||
|
|
||||||
services.AddDbContext(connectionString);
|
services.AddDbContext(connectionString);
|
||||||
services.AddTransient<IEmailSender, FileEmailSender>();
|
services.AddTransient<IEmailSender, FileEmailSender>();
|
||||||
services.AddTransient<IDomainEventService, DomainEventService>();
|
services.AddSingleton<IDomainEventService, DomainEventService>();
|
||||||
|
|
||||||
services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));
|
services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,9 @@ namespace PracticeCalendar.Infrastructure.Persistence
|
|||||||
// Seed, if necessary
|
// Seed, if necessary
|
||||||
if (!context.PracticeEvents.Any())
|
if (!context.PracticeEvents.Any())
|
||||||
{
|
{
|
||||||
context.PracticeEvents.Add(new PracticeEvent("Event 1", "Event 1 desc"));
|
context.PracticeEvents.Add(new PracticeEvent("Event 1", "Event 1 desc",
|
||||||
|
DateTime.Now.AddHours(-1),
|
||||||
|
DateTime.Now.AddHours(1)));
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
using FluentAssertions;
|
||||||
|
using Mapster;
|
||||||
|
using PracticeCalendar.Application.PracticeEvents.Queries;
|
||||||
|
using PracticeCalendar.Domain.Entities;
|
||||||
|
|
||||||
|
namespace PracticeCalendar.UnitTests.Application.Mapping
|
||||||
|
{
|
||||||
|
public class PracticeEventMappingTests
|
||||||
|
{
|
||||||
|
readonly string _eventTitle = "Event1";
|
||||||
|
readonly string _eventDescription = "Description";
|
||||||
|
readonly string _attendeeName = "Claudiu Farcas";
|
||||||
|
readonly string _attendeeEmail = "claudiu.farcas@testingbee.com";
|
||||||
|
readonly DateTime _eventStartTime = new DateTime(2022, 10, 10, 10, 25, 35);
|
||||||
|
readonly DateTime _eventEndTime = new DateTime(2022, 10, 12, 9, 15, 00);
|
||||||
|
|
||||||
|
public PracticeEventMappingTests()
|
||||||
|
{
|
||||||
|
TypeAdapterConfig.GlobalSettings.Default.MapToConstructor(true);
|
||||||
|
TypeAdapterConfig.GlobalSettings.NewConfig<PracticeEventDto, PracticeEvent>()
|
||||||
|
.ConstructUsing(src => new PracticeEvent(src.Title, src.Description, src.StartTime, src.EndTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PracticeEvent_to_PracticeEventDto()
|
||||||
|
{
|
||||||
|
var practiceEvent = new PracticeEvent(_eventTitle, _eventDescription, _eventStartTime, _eventEndTime);
|
||||||
|
var testAttendee = new Attendee(_attendeeName, _attendeeEmail);
|
||||||
|
practiceEvent.AddAttendee(testAttendee);
|
||||||
|
|
||||||
|
var dto = practiceEvent.Adapt<PracticeEventDto>();
|
||||||
|
|
||||||
|
dto.Should().NotBeNull();
|
||||||
|
dto.Title.Should().Be(_eventTitle);
|
||||||
|
dto.Description.Should().Be(_eventDescription);
|
||||||
|
dto.StartTime.Should().Be(_eventStartTime);
|
||||||
|
dto.EndTime.Should().Be(_eventEndTime);
|
||||||
|
dto.Attendees.Should().HaveCount(1);
|
||||||
|
dto.Attendees[0].Name.Should().Be(_attendeeName);
|
||||||
|
dto.Attendees[0].EmailAddress.Should().Be(_attendeeEmail);
|
||||||
|
dto.Attendees[0].IsAttending.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PracticeEventDto_to_PracticeEvent()
|
||||||
|
{
|
||||||
|
var practiceEventDto = new PracticeEventDto
|
||||||
|
{
|
||||||
|
Title = _eventTitle,
|
||||||
|
Description = _eventDescription,
|
||||||
|
StartTime = _eventStartTime,
|
||||||
|
EndTime = _eventEndTime
|
||||||
|
};
|
||||||
|
var attendeeDto = new AttendeeDto
|
||||||
|
{
|
||||||
|
Name = _attendeeName,
|
||||||
|
EmailAddress = _attendeeEmail
|
||||||
|
};
|
||||||
|
practiceEventDto.Attendees.Add(attendeeDto);
|
||||||
|
|
||||||
|
var entity = practiceEventDto.Adapt<PracticeEvent>();
|
||||||
|
|
||||||
|
entity.Should().NotBeNull();
|
||||||
|
entity.Title.Should().Be(_eventTitle);
|
||||||
|
entity.Description.Should().Be(_eventDescription);
|
||||||
|
entity.StartTime.Should().Be(_eventStartTime);
|
||||||
|
entity.EndTime.Should().Be(_eventEndTime);
|
||||||
|
entity.Attendees.Should().HaveCount(1);
|
||||||
|
entity.Attendees[0].Name.Should().Be(_attendeeName);
|
||||||
|
entity.Attendees[0].EmailAddress.Should().Be(_attendeeEmail);
|
||||||
|
entity.Attendees[0].IsAttending.Should().BeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
using FluentAssertions.Common;
|
||||||
using PracticeCalendar.Domain.Entities;
|
using PracticeCalendar.Domain.Entities;
|
||||||
|
|
||||||
namespace PracticeCalendar.UnitTests.Domain
|
namespace PracticeCalendar.UnitTests.Domain
|
||||||
@@ -13,7 +14,7 @@ namespace PracticeCalendar.UnitTests.Domain
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void InitializeProperties()
|
public void InitializeProperties()
|
||||||
{
|
{
|
||||||
var practiceEvent = new PracticeEvent(_eventTitle, _eventDescription);
|
var practiceEvent = new PracticeEvent(_eventTitle, _eventDescription, DateTime.Now, DateTime.Now);
|
||||||
practiceEvent.Title.Should().Be(_eventTitle);
|
practiceEvent.Title.Should().Be(_eventTitle);
|
||||||
practiceEvent.Description.Should().Be(_eventDescription);
|
practiceEvent.Description.Should().Be(_eventDescription);
|
||||||
practiceEvent.Attendees.Should().HaveCount(0);
|
practiceEvent.Attendees.Should().HaveCount(0);
|
||||||
@@ -24,25 +25,25 @@ namespace PracticeCalendar.UnitTests.Domain
|
|||||||
{
|
{
|
||||||
Action act = () =>
|
Action act = () =>
|
||||||
{
|
{
|
||||||
var practiceEvent = new PracticeEvent(null!, _eventDescription);
|
var practiceEvent = new PracticeEvent(null!, _eventDescription, DateTime.Now, DateTime.Now);
|
||||||
};
|
};
|
||||||
act.Should().Throw<ArgumentNullException>();
|
act.Should().Throw<ArgumentNullException>();
|
||||||
|
|
||||||
act = () =>
|
act = () =>
|
||||||
{
|
{
|
||||||
var practiceEvent = new PracticeEvent(_eventTitle, null!);
|
var practiceEvent = new PracticeEvent(_eventTitle, null!, DateTime.Now, DateTime.Now);
|
||||||
};
|
};
|
||||||
act.Should().Throw<ArgumentNullException>();
|
act.Should().Throw<ArgumentNullException>();
|
||||||
|
|
||||||
act = () =>
|
act = () =>
|
||||||
{
|
{
|
||||||
var practiceEvent = new PracticeEvent(string.Empty, _eventDescription);
|
var practiceEvent = new PracticeEvent(string.Empty, _eventDescription, DateTime.Now, DateTime.Now);
|
||||||
};
|
};
|
||||||
act.Should().Throw<ArgumentException>();
|
act.Should().Throw<ArgumentException>();
|
||||||
|
|
||||||
act = () =>
|
act = () =>
|
||||||
{
|
{
|
||||||
var practiceEvent = new PracticeEvent(_eventTitle, string.Empty);
|
var practiceEvent = new PracticeEvent(_eventTitle, string.Empty, DateTime.Now, DateTime.Now);
|
||||||
};
|
};
|
||||||
act.Should().Throw<ArgumentException>();
|
act.Should().Throw<ArgumentException>();
|
||||||
}
|
}
|
||||||
@@ -50,7 +51,7 @@ namespace PracticeCalendar.UnitTests.Domain
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void AddAttendeeToEvent()
|
public void AddAttendeeToEvent()
|
||||||
{
|
{
|
||||||
var practiceEvent = new PracticeEvent(_eventTitle, _eventDescription);
|
var practiceEvent = new PracticeEvent(_eventTitle, _eventDescription, DateTime.Now, DateTime.Now);
|
||||||
var testAttendee = new Attendee(_attendeeName, _atendeeEmail);
|
var testAttendee = new Attendee(_attendeeName, _atendeeEmail);
|
||||||
practiceEvent.AddAttendee(testAttendee);
|
practiceEvent.AddAttendee(testAttendee);
|
||||||
practiceEvent.Attendees.Should().HaveCount(1);
|
practiceEvent.Attendees.Should().HaveCount(1);
|
||||||
|
|||||||
@@ -3,12 +3,21 @@ using Microsoft.AspNetCore.Mvc.Testing;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
|
using PracticeCalendar.Domain.Common.Interfaces;
|
||||||
using PracticeCalendar.Infrastructure.Persistence;
|
using PracticeCalendar.Infrastructure.Persistence;
|
||||||
|
using PracticeCalendar.Infrastructure.Services;
|
||||||
|
|
||||||
namespace PracticeCalendar.UnitTests.Integration
|
namespace PracticeCalendar.UnitTests.Integration
|
||||||
{
|
{
|
||||||
public class CustomWebApplicationFactory : WebApplicationFactory<Program>
|
public class CustomWebApplicationFactory : WebApplicationFactory<Program>
|
||||||
{
|
{
|
||||||
|
private readonly Action<IServiceCollection> configServices;
|
||||||
|
|
||||||
|
public CustomWebApplicationFactory(Action<IServiceCollection> configServices)
|
||||||
|
{
|
||||||
|
this.configServices = configServices;
|
||||||
|
}
|
||||||
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||||
{
|
{
|
||||||
builder.ConfigureAppConfiguration(configurationBuilder =>
|
builder.ConfigureAppConfiguration(configurationBuilder =>
|
||||||
@@ -27,7 +36,10 @@ namespace PracticeCalendar.UnitTests.Integration
|
|||||||
services.AddDbContext<ApplicationDbContext>(options =>
|
services.AddDbContext<ApplicationDbContext>(options =>
|
||||||
options.UseInMemoryDatabase("InMemoryDbForTesting")
|
options.UseInMemoryDatabase("InMemoryDbForTesting")
|
||||||
);
|
);
|
||||||
|
configServices(services);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
using PracticeCalendar.Application.PracticeEvents.Commands;
|
using PracticeCalendar.Application.PracticeEvents.Commands;
|
||||||
using PracticeCalendar.Application.PracticeEvents.Queries;
|
using PracticeCalendar.Application.PracticeEvents.Queries;
|
||||||
|
using PracticeCalendar.Domain.Common;
|
||||||
using static PracticeCalendar.UnitTests.Integration.Testing;
|
using static PracticeCalendar.UnitTests.Integration.Testing;
|
||||||
|
|
||||||
namespace PracticeCalendar.UnitTests.Integration.PracticeEvents
|
namespace PracticeCalendar.UnitTests.Integration.PracticeEvents
|
||||||
@@ -38,6 +39,9 @@ namespace PracticeCalendar.UnitTests.Integration.PracticeEvents
|
|||||||
result.Should().NotBeNull();
|
result.Should().NotBeNull();
|
||||||
result.Id.Should().NotBe(0);
|
result.Id.Should().NotBe(0);
|
||||||
result.Attendees.Count.Should().Be(2);
|
result.Attendees.Count.Should().Be(2);
|
||||||
|
|
||||||
|
//check domain events count
|
||||||
|
domainEventServiceMock.Verify(x=>x.Publish(It.IsAny<DomainEventBase>()), Times.Exactly(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ namespace PracticeCalendar.UnitTests.Integration.PracticeEvents
|
|||||||
{
|
{
|
||||||
await RunBeforeAnyTests();
|
await RunBeforeAnyTests();
|
||||||
|
|
||||||
await AddAsync(new PracticeEvent("Test Event", "Event description")
|
await AddAsync(new PracticeEvent("Test Event", "Event description",
|
||||||
|
DateTime.Now.AddHours(-1), DateTime.Now.AddHours(1))
|
||||||
{
|
{
|
||||||
Id = 1,
|
Id = 1,
|
||||||
Attendees = {
|
Attendees = {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using PracticeCalendar.Infrastructure.Persistence;
|
using PracticeCalendar.Infrastructure.Persistence;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using PracticeCalendar.Domain.Entities;
|
using PracticeCalendar.Domain.Entities;
|
||||||
|
using PracticeCalendar.Domain.Common.Interfaces;
|
||||||
|
using Moq;
|
||||||
|
|
||||||
namespace PracticeCalendar.UnitTests.Integration
|
namespace PracticeCalendar.UnitTests.Integration
|
||||||
{
|
{
|
||||||
@@ -14,9 +16,17 @@ namespace PracticeCalendar.UnitTests.Integration
|
|||||||
private static IConfiguration _configuration = null!;
|
private static IConfiguration _configuration = null!;
|
||||||
private static IServiceScopeFactory _scopeFactory = null!;
|
private static IServiceScopeFactory _scopeFactory = null!;
|
||||||
|
|
||||||
|
public static Mock<IDomainEventService> domainEventServiceMock = null!;
|
||||||
|
|
||||||
public static async Task RunBeforeAnyTests()
|
public static async Task RunBeforeAnyTests()
|
||||||
{
|
{
|
||||||
_factory = new CustomWebApplicationFactory();
|
domainEventServiceMock = new Mock<IDomainEventService>();
|
||||||
|
|
||||||
|
_factory = new CustomWebApplicationFactory(cfg =>
|
||||||
|
{
|
||||||
|
cfg.AddSingleton(svc => domainEventServiceMock.Object);
|
||||||
|
});
|
||||||
|
|
||||||
_scopeFactory = _factory.Services.GetRequiredService<IServiceScopeFactory>();
|
_scopeFactory = _factory.Services.GetRequiredService<IServiceScopeFactory>();
|
||||||
_configuration = _factory.Services.GetRequiredService<IConfiguration>();
|
_configuration = _factory.Services.GetRequiredService<IConfiguration>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,10 +41,6 @@
|
|||||||
<ProjectReference Include="..\PracticeCalendar.Api\PracticeCalendar.API.csproj" />
|
<ProjectReference Include="..\PracticeCalendar.Api\PracticeCalendar.API.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Application\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="xunit.runner.json">
|
<None Update="xunit.runner.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
|||||||
Reference in New Issue
Block a user