diff --git a/src/Application/Common/Interfaces/IApplicationDbContext.cs b/src/Application/Common/Interfaces/IApplicationDbContext.cs index 9e35843..ef5afaa 100644 --- a/src/Application/Common/Interfaces/IApplicationDbContext.cs +++ b/src/Application/Common/Interfaces/IApplicationDbContext.cs @@ -4,11 +4,9 @@ namespace Hutopy.Application.Common.Interfaces; public interface IApplicationDbContext { - DbSet TodoLists { get; } - - DbSet TodoItems { get; } - DbSet FutureCreators { get; } + DbSet DomainUsers { get; } + Task SaveChangesAsync(CancellationToken cancellationToken); } diff --git a/src/Application/Common/Models/LookupDto.cs b/src/Application/Common/Models/LookupDto.cs deleted file mode 100644 index bde00c2..0000000 --- a/src/Application/Common/Models/LookupDto.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.Common.Models; - -public class LookupDto -{ - public int Id { get; init; } - - public string? Title { get; init; } - - private class Mapping : Profile - { - public Mapping() - { - CreateMap(); - CreateMap(); - } - } -} diff --git a/src/Application/FutureCreators/Commands/CreateFutureCreator.cs b/src/Application/FutureCreators/Commands/CreateFutureCreator.cs index d1f412e..7aa7f50 100644 --- a/src/Application/FutureCreators/Commands/CreateFutureCreator.cs +++ b/src/Application/FutureCreators/Commands/CreateFutureCreator.cs @@ -3,7 +3,7 @@ using Hutopy.Domain.Entities; namespace Hutopy.Application.FutureCreators.Commands; -public abstract record CreateFutureCreatorCommand : IRequest +public record CreateFutureCreatorCommand : IRequest { public required string FirstName { get; init; } public required string LastName { get; init; } @@ -15,9 +15,9 @@ public abstract record CreateFutureCreatorCommand : IRequest public class CreateFutureCreatorCommandHandler( IApplicationDbContext context) - : IRequestHandler + : IRequestHandler { - public async Task Handle(CreateFutureCreatorCommand request, CancellationToken cancellationToken) + public async Task Handle(CreateFutureCreatorCommand request, CancellationToken cancellationToken) { var entity = new FutureCreator { diff --git a/src/Application/FutureCreators/Queries/FutureCreatorListDto.cs b/src/Application/FutureCreators/Queries/FutureCreatorListDto.cs new file mode 100644 index 0000000..13d95ba --- /dev/null +++ b/src/Application/FutureCreators/Queries/FutureCreatorListDto.cs @@ -0,0 +1,20 @@ +using Hutopy.Domain.Entities; + +namespace Hutopy.Application.FutureCreators.Queries; + +public class FutureCreatorListDto +{ + public Guid Id { get; init; } + + public required string FirstName { get; init; } + + public required string LastName { get; init; } + + private class Mapping : Profile + { + public Mapping() + { + CreateMap(); + } + } +} diff --git a/src/Application/FutureCreators/Queries/GetFutureCreatorList.cs b/src/Application/FutureCreators/Queries/GetFutureCreatorList.cs new file mode 100644 index 0000000..e7a8128 --- /dev/null +++ b/src/Application/FutureCreators/Queries/GetFutureCreatorList.cs @@ -0,0 +1,27 @@ + +using Hutopy.Application.Common.Interfaces; +using Hutopy.Application.Common.Mappings; +using Hutopy.Application.Common.Models; + +namespace Hutopy.Application.FutureCreators.Queries; + +public record GetFutureCreatorListQuery : IRequest> +{ + public int PageNumber { get; init; } = 1; + public int PageSize { get; init; } = 10; +} + +public class GetFutureCreatorListQueryHandler( + IApplicationDbContext context, + IMapper mapper) + : IRequestHandler> +{ + public async Task> Handle(GetFutureCreatorListQuery request, CancellationToken cancellationToken) + { + Console.WriteLine(request); + return await context.FutureCreators + .OrderBy(x => x.FirstName) + .ProjectTo(mapper.ConfigurationProvider) + .PaginatedListAsync(request.PageNumber, request.PageSize); + } +} diff --git a/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItem.cs b/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItem.cs deleted file mode 100644 index c4a448a..0000000 --- a/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItem.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Hutopy.Application.Common.Interfaces; -using Hutopy.Domain.Entities; -using Hutopy.Domain.Events; - -namespace Hutopy.Application.TodoItems.Commands.CreateTodoItem; - -public record CreateTodoItemCommand : IRequest -{ - public int ListId { get; init; } - - public string? Title { get; init; } -} - -public class CreateTodoItemCommandHandler( - IApplicationDbContext context) - : IRequestHandler -{ - public async Task Handle(CreateTodoItemCommand request, CancellationToken cancellationToken) - { - var entity = new TodoItem - { - ListId = request.ListId, - Title = request.Title, - Done = false - }; - - entity.AddDomainEvent(new TodoItemCreatedEvent(entity)); - - context.TodoItems.Add(entity); - - await context.SaveChangesAsync(cancellationToken); - - return entity.Id; - } -} diff --git a/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommandValidator.cs b/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommandValidator.cs deleted file mode 100644 index e6d876a..0000000 --- a/src/Application/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommandValidator.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Hutopy.Application.TodoItems.Commands.CreateTodoItem; - -public class CreateTodoItemCommandValidator : AbstractValidator -{ - public CreateTodoItemCommandValidator() - { - RuleFor(v => v.Title) - .MaximumLength(200) - .NotEmpty(); - } -} diff --git a/src/Application/TodoItems/Commands/DeleteTodoItem/DeleteTodoItem.cs b/src/Application/TodoItems/Commands/DeleteTodoItem/DeleteTodoItem.cs deleted file mode 100644 index 3039681..0000000 --- a/src/Application/TodoItems/Commands/DeleteTodoItem/DeleteTodoItem.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Hutopy.Application.Common.Interfaces; -using Hutopy.Domain.Events; -using Hutopy.Application.Common.Security; -using Hutopy.Domain.Constants; - -namespace Hutopy.Application.TodoItems.Commands.DeleteTodoItem; - -[Authorize(Roles = Roles.Administrator)] -[Authorize(Policy = Policies.CanDelete)] -public record DeleteTodoItemCommand(int Id) : IRequest; - -public class DeleteTodoItemCommandHandler( - IApplicationDbContext context) - : IRequestHandler -{ - public async Task Handle(DeleteTodoItemCommand request, CancellationToken cancellationToken) - { - var entity = await context.TodoItems - .FindAsync(new object[] { request.Id }, cancellationToken); - - Guard.Against.NotFound(request.Id, entity); - - context.TodoItems.Remove(entity); - - entity.AddDomainEvent(new TodoItemDeletedEvent(entity)); - - await context.SaveChangesAsync(cancellationToken); - } - -} diff --git a/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItem.cs b/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItem.cs deleted file mode 100644 index 68ad4e5..0000000 --- a/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItem.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Hutopy.Application.Common.Interfaces; - -namespace Hutopy.Application.TodoItems.Commands.UpdateTodoItem; - -public record UpdateTodoItemCommand : IRequest -{ - public int Id { get; init; } - - public string? Title { get; init; } - - public bool Done { get; init; } -} - -public class UpdateTodoItemCommandHandler( - IApplicationDbContext context) - : IRequestHandler -{ - public async Task Handle(UpdateTodoItemCommand request, CancellationToken cancellationToken) - { - var entity = await context.TodoItems - .FindAsync(new object[] { request.Id }, cancellationToken); - - Guard.Against.NotFound(request.Id, entity); - - entity.Title = request.Title; - entity.Done = request.Done; - - await context.SaveChangesAsync(cancellationToken); - } -} diff --git a/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItemCommandValidator.cs b/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItemCommandValidator.cs deleted file mode 100644 index 38383c6..0000000 --- a/src/Application/TodoItems/Commands/UpdateTodoItem/UpdateTodoItemCommandValidator.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Hutopy.Application.TodoItems.Commands.UpdateTodoItem; - -public class UpdateTodoItemCommandValidator : AbstractValidator -{ - public UpdateTodoItemCommandValidator() - { - RuleFor(v => v.Title) - .MaximumLength(200) - .NotEmpty(); - } -} diff --git a/src/Application/TodoItems/Commands/UpdateTodoItemDetail/UpdateTodoItemDetail.cs b/src/Application/TodoItems/Commands/UpdateTodoItemDetail/UpdateTodoItemDetail.cs deleted file mode 100644 index 078a278..0000000 --- a/src/Application/TodoItems/Commands/UpdateTodoItemDetail/UpdateTodoItemDetail.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Hutopy.Application.Common.Interfaces; -using Hutopy.Domain.Enums; - -namespace Hutopy.Application.TodoItems.Commands.UpdateTodoItemDetail; - -public record UpdateTodoItemDetailCommand : IRequest -{ - public int Id { get; init; } - - public int ListId { get; init; } - - public PriorityLevel Priority { get; init; } - - public string? Note { get; init; } -} - -public class UpdateTodoItemDetailCommandHandler( - IApplicationDbContext context) - : IRequestHandler -{ - public async Task Handle(UpdateTodoItemDetailCommand request, CancellationToken cancellationToken) - { - var entity = await context.TodoItems - .FindAsync(new object[] { request.Id }, cancellationToken); - - Guard.Against.NotFound(request.Id, entity); - - entity.ListId = request.ListId; - entity.Priority = request.Priority; - entity.Note = request.Note; - - await context.SaveChangesAsync(cancellationToken); - } -} diff --git a/src/Application/TodoItems/EventHandlers/TodoItemCompletedEventHandler.cs b/src/Application/TodoItems/EventHandlers/TodoItemCompletedEventHandler.cs deleted file mode 100644 index b16a60d..0000000 --- a/src/Application/TodoItems/EventHandlers/TodoItemCompletedEventHandler.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Hutopy.Domain.Events; -using Microsoft.Extensions.Logging; - -namespace Hutopy.Application.TodoItems.EventHandlers; - -public class TodoItemCompletedEventHandler( - ILogger logger) - : INotificationHandler -{ - public Task Handle(TodoItemCompletedEvent notification, CancellationToken cancellationToken) - { - logger.LogInformation("Hutopy Domain Event: {DomainEvent}", notification.GetType().Name); - - return Task.CompletedTask; - } -} diff --git a/src/Application/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs b/src/Application/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs deleted file mode 100644 index 8aba373..0000000 --- a/src/Application/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Hutopy.Domain.Events; -using Microsoft.Extensions.Logging; - -namespace Hutopy.Application.TodoItems.EventHandlers; - -public class TodoItemCreatedEventHandler( - ILogger logger) - : INotificationHandler -{ - public Task Handle(TodoItemCreatedEvent notification, CancellationToken cancellationToken) - { - logger.LogInformation("Hutopy Domain Event: {DomainEvent}", notification.GetType().Name); - - return Task.CompletedTask; - } -} diff --git a/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPagination.cs b/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPagination.cs deleted file mode 100644 index b0ece59..0000000 --- a/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPagination.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Hutopy.Application.Common.Interfaces; -using Hutopy.Application.Common.Mappings; -using Hutopy.Application.Common.Models; - -namespace Hutopy.Application.TodoItems.Queries.GetTodoItemsWithPagination; - -public abstract record GetTodoItemsWithPaginationQuery : IRequest> -{ - public int ListId { get; init; } - public int PageNumber { get; init; } = 1; - public int PageSize { get; init; } = 10; -} - -public class GetTodoItemsWithPaginationQueryHandler( - IApplicationDbContext context, - IMapper mapper) - : IRequestHandler> -{ - public async Task> Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken) - { - Console.WriteLine(request); - return await context.TodoItems - .Where(x => x.ListId == request.ListId) - .OrderBy(x => x.Title) - .ProjectTo(mapper.ConfigurationProvider) - .PaginatedListAsync(request.PageNumber, request.PageSize); - } -} diff --git a/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPaginationQueryValidator.cs b/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPaginationQueryValidator.cs deleted file mode 100644 index 99bfd24..0000000 --- a/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/GetTodoItemsWithPaginationQueryValidator.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Hutopy.Application.TodoItems.Queries.GetTodoItemsWithPagination; - -public class GetTodoItemsWithPaginationQueryValidator : AbstractValidator -{ - public GetTodoItemsWithPaginationQueryValidator() - { - RuleFor(x => x.ListId) - .NotEmpty().WithMessage("ListId is required."); - - RuleFor(x => x.PageNumber) - .GreaterThanOrEqualTo(1).WithMessage("PageNumber at least greater than or equal to 1."); - - RuleFor(x => x.PageSize) - .GreaterThanOrEqualTo(1).WithMessage("PageSize at least greater than or equal to 1."); - } -} diff --git a/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/TodoItemBriefDto.cs b/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/TodoItemBriefDto.cs deleted file mode 100644 index b7c40a3..0000000 --- a/src/Application/TodoItems/Queries/GetTodoItemsWithPagination/TodoItemBriefDto.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.TodoItems.Queries.GetTodoItemsWithPagination; - -public class TodoItemBriefDto -{ - public int Id { get; init; } - - public int ListId { get; init; } - - public string? Title { get; init; } - - public bool Done { get; init; } - - private class Mapping : Profile - { - public Mapping() - { - CreateMap(); - } - } -} diff --git a/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoList.cs b/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoList.cs deleted file mode 100644 index cf95696..0000000 --- a/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoList.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Hutopy.Application.Common.Interfaces; -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.TodoLists.Commands.CreateTodoList; - -public record CreateTodoListCommand : IRequest -{ - public string? Title { get; init; } -} - -public class CreateTodoListCommandHandler( - IApplicationDbContext context) - : IRequestHandler -{ - public async Task Handle(CreateTodoListCommand request, CancellationToken cancellationToken) - { - var entity = new TodoList { Title = request.Title }; - - context.TodoLists.Add(entity); - - await context.SaveChangesAsync(cancellationToken); - - return entity.Id; - } -} diff --git a/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoListCommandValidator.cs b/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoListCommandValidator.cs deleted file mode 100644 index 4c627b4..0000000 --- a/src/Application/TodoLists/Commands/CreateTodoList/CreateTodoListCommandValidator.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Hutopy.Application.Common.Interfaces; - -namespace Hutopy.Application.TodoLists.Commands.CreateTodoList; - -public class CreateTodoListCommandValidator : AbstractValidator -{ - private readonly IApplicationDbContext _context; - - public CreateTodoListCommandValidator(IApplicationDbContext context) - { - _context = context; - - RuleFor(v => v.Title) - .NotEmpty() - .MaximumLength(200) - .MustAsync(BeUniqueTitle) - .WithMessage("'{PropertyName}' must be unique.") - .WithErrorCode("Unique"); - } - - public async Task BeUniqueTitle(string title, CancellationToken cancellationToken) - { - return await _context.TodoLists - .AllAsync(l => l.Title != title, cancellationToken); - } -} diff --git a/src/Application/TodoLists/Commands/DeleteTodoList/DeleteTodoList.cs b/src/Application/TodoLists/Commands/DeleteTodoList/DeleteTodoList.cs deleted file mode 100644 index 3339e8a..0000000 --- a/src/Application/TodoLists/Commands/DeleteTodoList/DeleteTodoList.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Hutopy.Application.Common.Interfaces; - -namespace Hutopy.Application.TodoLists.Commands.DeleteTodoList; - -public record DeleteTodoListCommand(int Id) : IRequest; - -public class DeleteTodoListCommandHandler( - IApplicationDbContext context) - : IRequestHandler -{ - public async Task Handle(DeleteTodoListCommand request, CancellationToken cancellationToken) - { - var entity = await context.TodoLists - .Where(l => l.Id == request.Id) - .SingleOrDefaultAsync(cancellationToken); - - Guard.Against.NotFound(request.Id, entity); - - context.TodoLists.Remove(entity); - - await context.SaveChangesAsync(cancellationToken); - } -} diff --git a/src/Application/TodoLists/Commands/PurgeTodoLists/PurgeTodoLists.cs b/src/Application/TodoLists/Commands/PurgeTodoLists/PurgeTodoLists.cs deleted file mode 100644 index 1e75661..0000000 --- a/src/Application/TodoLists/Commands/PurgeTodoLists/PurgeTodoLists.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Hutopy.Application.Common.Interfaces; -using Hutopy.Application.Common.Security; -using Hutopy.Domain.Constants; - -namespace Hutopy.Application.TodoLists.Commands.PurgeTodoLists; - -[Authorize(Roles = Roles.Administrator)] -[Authorize(Policy = Policies.CanPurge)] -public record PurgeTodoListsCommand : IRequest; - -public class PurgeTodoListsCommandHandler( - IApplicationDbContext context) - : IRequestHandler -{ - public async Task Handle(PurgeTodoListsCommand request, CancellationToken cancellationToken) - { - context.TodoLists.RemoveRange(context.TodoLists); - - await context.SaveChangesAsync(cancellationToken); - } -} diff --git a/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoList.cs b/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoList.cs deleted file mode 100644 index 8418030..0000000 --- a/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoList.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Hutopy.Application.Common.Interfaces; - -namespace Hutopy.Application.TodoLists.Commands.UpdateTodoList; - -public record UpdateTodoListCommand : IRequest -{ - public int Id { get; init; } - - public string? Title { get; init; } -} - -public class UpdateTodoListCommandHandler( - IApplicationDbContext context) - : IRequestHandler -{ - public async Task Handle(UpdateTodoListCommand request, CancellationToken cancellationToken) - { - var entity = await context.TodoLists - .FindAsync(new object[] { request.Id }, cancellationToken); - - Guard.Against.NotFound(request.Id, entity); - - entity.Title = request.Title; - - await context.SaveChangesAsync(cancellationToken); - - } -} diff --git a/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoListCommandValidator.cs b/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoListCommandValidator.cs deleted file mode 100644 index ba008d6..0000000 --- a/src/Application/TodoLists/Commands/UpdateTodoList/UpdateTodoListCommandValidator.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Hutopy.Application.Common.Interfaces; - -namespace Hutopy.Application.TodoLists.Commands.UpdateTodoList; - -public class UpdateTodoListCommandValidator : AbstractValidator -{ - private readonly IApplicationDbContext _context; - - public UpdateTodoListCommandValidator(IApplicationDbContext context) - { - _context = context; - - RuleFor(v => v.Title) - .NotEmpty() - .MaximumLength(200) - .MustAsync(BeUniqueTitle) - .WithMessage("'{PropertyName}' must be unique.") - .WithErrorCode("Unique"); - } - - private async Task BeUniqueTitle(UpdateTodoListCommand model, string title, CancellationToken cancellationToken) - { - return await _context.TodoLists - .Where(l => l.Id != model.Id) - .AllAsync(l => l.Title != title, cancellationToken); - } -} diff --git a/src/Application/TodoLists/Queries/GetTodos/GetTodos.cs b/src/Application/TodoLists/Queries/GetTodos/GetTodos.cs deleted file mode 100644 index 9d4d32f..0000000 --- a/src/Application/TodoLists/Queries/GetTodos/GetTodos.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Hutopy.Application.Common.Interfaces; -using Hutopy.Application.Common.Models; -using Hutopy.Application.Common.Security; -using Hutopy.Domain.Enums; - -namespace Hutopy.Application.TodoLists.Queries.GetTodos; - -[Authorize] -public record GetTodosQuery : IRequest; - -public class GetTodosQueryHandler( - IApplicationDbContext context, - IMapper mapper) - : IRequestHandler -{ - public async Task Handle(GetTodosQuery request, CancellationToken cancellationToken) - { - return new TodosVm - { - PriorityLevels = Enum.GetValues(typeof(PriorityLevel)) - .Cast() - .Select(p => new LookupDto { Id = (int)p, Title = p.ToString() }) - .ToList(), - - Lists = await context.TodoLists - .AsNoTracking() - .ProjectTo(mapper.ConfigurationProvider) - .OrderBy(t => t.Title) - .ToListAsync(cancellationToken) - }; - } -} diff --git a/src/Application/TodoLists/Queries/GetTodos/TodoItemDto.cs b/src/Application/TodoLists/Queries/GetTodos/TodoItemDto.cs deleted file mode 100644 index 18d86a3..0000000 --- a/src/Application/TodoLists/Queries/GetTodos/TodoItemDto.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.TodoLists.Queries.GetTodos; - -public class TodoItemDto -{ - public int Id { get; init; } - - public int ListId { get; init; } - - public string? Title { get; init; } - - public bool Done { get; init; } - - public int Priority { get; init; } - - public string? Note { get; init; } - - private class Mapping : Profile - { - public Mapping() - { - CreateMap().ForMember(d => d.Priority, - opt => opt.MapFrom(s => (int)s.Priority)); - } - } -} diff --git a/src/Application/TodoLists/Queries/GetTodos/TodoListDto.cs b/src/Application/TodoLists/Queries/GetTodos/TodoListDto.cs deleted file mode 100644 index c0a84dc..0000000 --- a/src/Application/TodoLists/Queries/GetTodos/TodoListDto.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.TodoLists.Queries.GetTodos; - -public class TodoListDto -{ - public int Id { get; init; } - - public string? Title { get; init; } - - public string? Colour { get; init; } - - public IReadOnlyCollection Items { get; init; } = Array.Empty(); - - private class Mapping : Profile - { - public Mapping() - { - CreateMap(); - } - } -} diff --git a/src/Application/TodoLists/Queries/GetTodos/TodosVm.cs b/src/Application/TodoLists/Queries/GetTodos/TodosVm.cs deleted file mode 100644 index 6bff5af..0000000 --- a/src/Application/TodoLists/Queries/GetTodos/TodosVm.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Hutopy.Application.Common.Models; - -namespace Hutopy.Application.TodoLists.Queries.GetTodos; - -public class TodosVm -{ - public IReadOnlyCollection PriorityLevels { get; init; } = Array.Empty(); - - public IReadOnlyCollection Lists { get; init; } = Array.Empty(); -} diff --git a/src/Application/Users/Commands/CreateUser.cs b/src/Application/Users/Commands/CreateUser.cs new file mode 100644 index 0000000..be18e30 --- /dev/null +++ b/src/Application/Users/Commands/CreateUser.cs @@ -0,0 +1,39 @@ +using Hutopy.Application.Common.Interfaces; +using Hutopy.Domain.Entities; + +namespace Hutopy.Application.Users.Commands; +public record CreateUserCommand : IRequest +{ + public required string FirstName { get; init; } + public required string LastName { get; init; } + public required string EmailAddress { get; init; } + public required string UserName { get; init; } + public required string Password { get; init; } +} + +public class CreateUserCommandHandler : IRequestHandler +{ + private readonly IApplicationDbContext _context; + + public CreateUserCommandHandler(IApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(CreateUserCommand request, CancellationToken cancellationToken) + { + var entity = new User + { + FirstName = request.FirstName, + LastName = request.LastName, + EmailAddress = request.EmailAddress, + UserName = request.UserName, + }; + + _context.DomainUsers.Add(entity); + + await _context.SaveChangesAsync(cancellationToken); + + return entity.Id; + } +} \ No newline at end of file diff --git a/src/Domain/Common/BaseEntity.cs b/src/Domain/Common/BaseEntity.cs index 388a3ce..080e1d4 100644 --- a/src/Domain/Common/BaseEntity.cs +++ b/src/Domain/Common/BaseEntity.cs @@ -6,7 +6,7 @@ public abstract class BaseEntity { // This can easily be modified to be BaseEntity and public T Id to support different key types. // Using non-generic integer types for simplicity - public int Id { get; set; } + public Guid Id { get; set; } private readonly List _domainEvents = []; diff --git a/src/Domain/Entities/TodoItem.cs b/src/Domain/Entities/TodoItem.cs deleted file mode 100644 index e10f25b..0000000 --- a/src/Domain/Entities/TodoItem.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace Hutopy.Domain.Entities; - -public class TodoItem : BaseAuditableEntity -{ - public int ListId { get; set; } - - public string? Title { get; set; } - - public string? Note { get; set; } - - public PriorityLevel Priority { get; set; } - - public DateTime? Reminder { get; set; } - - private bool _done; - public bool Done - { - get => _done; - set - { - if (value && !_done) - { - AddDomainEvent(new TodoItemCompletedEvent(this)); - } - - _done = value; - } - } - - public TodoList List { get; set; } = null!; -} diff --git a/src/Domain/Entities/TodoList.cs b/src/Domain/Entities/TodoList.cs deleted file mode 100644 index 365525e..0000000 --- a/src/Domain/Entities/TodoList.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hutopy.Domain.Entities; - -public class TodoList : BaseAuditableEntity -{ - public string? Title { get; set; } - - public Colour Colour { get; set; } = Colour.White; - - public IList Items { get; private set; } = new List(); -} diff --git a/src/Domain/Entities/User.cs b/src/Domain/Entities/User.cs new file mode 100644 index 0000000..d848021 --- /dev/null +++ b/src/Domain/Entities/User.cs @@ -0,0 +1,10 @@ +namespace Hutopy.Domain.Entities; + +public class User : BaseAuditableEntity +{ + public Guid IdentityUserId { get; set; } + public required string FirstName { get; set; } + public required string LastName { get; set; } + public required string UserName { get; set; } + public required string EmailAddress { get; set; } +} diff --git a/src/Domain/Events/TodoItemCompletedEvent.cs b/src/Domain/Events/TodoItemCompletedEvent.cs deleted file mode 100644 index 8d7cad1..0000000 --- a/src/Domain/Events/TodoItemCompletedEvent.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hutopy.Domain.Events; - -public class TodoItemCompletedEvent( - TodoItem item) - : BaseEvent -{ - public TodoItem Item { get; } = item; -} diff --git a/src/Domain/Events/TodoItemCreatedEvent.cs b/src/Domain/Events/TodoItemCreatedEvent.cs deleted file mode 100644 index 4f87e92..0000000 --- a/src/Domain/Events/TodoItemCreatedEvent.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hutopy.Domain.Events; - -public class TodoItemCreatedEvent( - TodoItem item) - : BaseEvent -{ - public TodoItem Item { get; } = item; -} diff --git a/src/Domain/Events/TodoItemDeletedEvent.cs b/src/Domain/Events/TodoItemDeletedEvent.cs deleted file mode 100644 index 1340b00..0000000 --- a/src/Domain/Events/TodoItemDeletedEvent.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hutopy.Domain.Events; - -public class TodoItemDeletedEvent( - TodoItem item) - : BaseEvent -{ - public TodoItem Item { get; } = item; -} diff --git a/src/Domain/GlobalUsings.cs b/src/Domain/GlobalUsings.cs index a15ae6d..e312629 100644 --- a/src/Domain/GlobalUsings.cs +++ b/src/Domain/GlobalUsings.cs @@ -1,6 +1,5 @@ global using Hutopy.Domain.Common; global using Hutopy.Domain.Entities; global using Hutopy.Domain.Enums; -global using Hutopy.Domain.Events; global using Hutopy.Domain.Exceptions; global using Hutopy.Domain.ValueObjects; \ No newline at end of file diff --git a/src/Domain/Interfaces/IUserService.cs b/src/Domain/Interfaces/IUserService.cs new file mode 100644 index 0000000..4048f93 --- /dev/null +++ b/src/Domain/Interfaces/IUserService.cs @@ -0,0 +1,7 @@ +namespace Hutopy.Domain.Interfaces; + +public interface IUserService +{ + Task CreateUserAsync(string email, string userName, string password); + +} diff --git a/src/Infrastructure/Data/ApplicationDbContext.cs b/src/Infrastructure/Data/ApplicationDbContext.cs index e565b11..c348dc4 100644 --- a/src/Infrastructure/Data/ApplicationDbContext.cs +++ b/src/Infrastructure/Data/ApplicationDbContext.cs @@ -11,12 +11,10 @@ public class ApplicationDbContext( DbContextOptions options) : IdentityDbContext(options), IApplicationDbContext { - public DbSet TodoLists => Set(); - - public DbSet TodoItems => Set(); - public DbSet FutureCreators => Set(); + public DbSet DomainUsers => Set(); + protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); diff --git a/src/Infrastructure/Data/ApplicationDbContextInitializer.cs b/src/Infrastructure/Data/ApplicationDbContextInitializer.cs index b595c1e..cbabbeb 100644 --- a/src/Infrastructure/Data/ApplicationDbContextInitializer.cs +++ b/src/Infrastructure/Data/ApplicationDbContextInitializer.cs @@ -73,27 +73,8 @@ public class ApplicationDbContextInitializer( await userManager.CreateAsync(administrator, "Administrator1!"); if (!string.IsNullOrWhiteSpace(administratorRole.Name)) { - await userManager.AddToRolesAsync(administrator, new [] { administratorRole.Name }); + await userManager.AddToRolesAsync(administrator, new[] { administratorRole.Name }); } } - - // Default data - // Seed, if necessary - if (!context.TodoLists.Any()) - { - context.TodoLists.Add(new TodoList - { - Title = "Todo List", - Items = - { - new TodoItem { Title = "Make a todo list 📃" }, - new TodoItem { Title = "Check off the first item ✅" }, - new TodoItem { Title = "Realise you've already done two things on the list! 🤯"}, - new TodoItem { Title = "Reward yourself with a nice, long nap 🏆" }, - } - }); - - await context.SaveChangesAsync(); - } } } diff --git a/src/Infrastructure/Data/Configurations/TodoItemConfiguration.cs b/src/Infrastructure/Data/Configurations/TodoItemConfiguration.cs deleted file mode 100644 index c6f9a2f..0000000 --- a/src/Infrastructure/Data/Configurations/TodoItemConfiguration.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Hutopy.Domain.Entities; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace Hutopy.Infrastructure.Data.Configurations; - -public class TodoItemConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.Property(t => t.Title) - .HasMaxLength(200) - .IsRequired(); - } -} diff --git a/src/Infrastructure/Data/Configurations/TodoListConfiguration.cs b/src/Infrastructure/Data/Configurations/TodoListConfiguration.cs deleted file mode 100644 index 3350621..0000000 --- a/src/Infrastructure/Data/Configurations/TodoListConfiguration.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Hutopy.Domain.Entities; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace Hutopy.Infrastructure.Data.Configurations; - -public class TodoListConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.Property(t => t.Title) - .HasMaxLength(200) - .IsRequired(); - - builder - .OwnsOne(b => b.Colour); - } -} diff --git a/src/Infrastructure/Data/Migrations/20240404013754_AddDomainUser.Designer.cs b/src/Infrastructure/Data/Migrations/20240404013754_AddDomainUser.Designer.cs new file mode 100644 index 0000000..efb1b0d --- /dev/null +++ b/src/Infrastructure/Data/Migrations/20240404013754_AddDomainUser.Designer.cs @@ -0,0 +1,492 @@ +// +using System; +using Hutopy.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Hutopy.Infrastructure.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20240404013754_AddDomainUser")] + partial class AddDomainUser + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Hutopy.Domain.Entities.FutureCreator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReasonToJoin") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SocialNetworkAccount") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FutureCreators"); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.TodoItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Done") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ListId") + .HasColumnType("int"); + + b.Property("Note") + .HasColumnType("nvarchar(max)"); + + b.Property("Priority") + .HasColumnType("int"); + + b.Property("Reminder") + .HasColumnType("datetime2"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("ListId"); + + b.ToTable("TodoItems"); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.TodoList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("TodoLists"); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IdentityUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("DomainUsers"); + }); + + modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.TodoItem", b => + { + b.HasOne("Hutopy.Domain.Entities.TodoList", "List") + .WithMany("Items") + .HasForeignKey("ListId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("List"); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.TodoList", b => + { + b.OwnsOne("Hutopy.Domain.ValueObjects.Colour", "Colour", b1 => + { + b1.Property("TodoListId") + .HasColumnType("int"); + + b1.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.HasKey("TodoListId"); + + b1.ToTable("TodoLists"); + + b1.WithOwner() + .HasForeignKey("TodoListId"); + }); + + b.Navigation("Colour") + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.TodoList", b => + { + b.Navigation("Items"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Data/Migrations/20240404013754_AddDomainUser.cs b/src/Infrastructure/Data/Migrations/20240404013754_AddDomainUser.cs new file mode 100644 index 0000000..c459b92 --- /dev/null +++ b/src/Infrastructure/Data/Migrations/20240404013754_AddDomainUser.cs @@ -0,0 +1,44 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Hutopy.Infrastructure.Data.Migrations +{ + /// + public partial class AddDomainUser : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DomainUsers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + IdentityUserId = table.Column(type: "uniqueidentifier", nullable: false), + FirstName = table.Column(type: "nvarchar(max)", nullable: false), + LastName = table.Column(type: "nvarchar(max)", nullable: false), + UserName = table.Column(type: "nvarchar(max)", nullable: false), + EmailAddress = table.Column(type: "nvarchar(max)", nullable: false), + Password = table.Column(type: "nvarchar(max)", nullable: false), + Created = table.Column(type: "datetimeoffset", nullable: false), + CreatedBy = table.Column(type: "nvarchar(max)", nullable: true), + LastModified = table.Column(type: "datetimeoffset", nullable: false), + LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DomainUsers", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DomainUsers"); + } + } +} diff --git a/src/Infrastructure/Data/Migrations/20240404023737_ChangeIdsToGuidsAndRemoveTodos.Designer.cs b/src/Infrastructure/Data/Migrations/20240404023737_ChangeIdsToGuidsAndRemoveTodos.Designer.cs new file mode 100644 index 0000000..4fb2eff --- /dev/null +++ b/src/Infrastructure/Data/Migrations/20240404023737_ChangeIdsToGuidsAndRemoveTodos.Designer.cs @@ -0,0 +1,372 @@ +// +using System; +using Hutopy.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Hutopy.Infrastructure.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20240404023737_ChangeIdsToGuidsAndRemoveTodos")] + partial class ChangeIdsToGuidsAndRemoveTodos + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Hutopy.Domain.Entities.FutureCreator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReasonToJoin") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SocialNetworkAccount") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FutureCreators"); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IdentityUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("DomainUsers"); + }); + + modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Data/Migrations/20240404023737_ChangeIdsToGuidsAndRemoveTodos.cs b/src/Infrastructure/Data/Migrations/20240404023737_ChangeIdsToGuidsAndRemoveTodos.cs new file mode 100644 index 0000000..6ef89a3 --- /dev/null +++ b/src/Infrastructure/Data/Migrations/20240404023737_ChangeIdsToGuidsAndRemoveTodos.cs @@ -0,0 +1,149 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Hutopy.Infrastructure.Data.Migrations +{ + /// + public partial class ChangeIdsToGuidsAndRemoveTodos : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "TodoItems"); + + migrationBuilder.DropTable( + name: "TodoLists"); + + migrationBuilder.DropPrimaryKey( + name: "PK_FuturCreators", + table: "FutureCreators"); + + migrationBuilder.DropPrimaryKey( + name: "PK_DomainUsers", + table: "DomainUsers"); + + migrationBuilder.DropColumn( + name: "Id", + table: "FutureCreators"); + + migrationBuilder.DropColumn( + name: "Id", + table: "DomainUsers"); + + migrationBuilder.AddColumn( + name: "Id", + table: "FutureCreators", + type: "uniqueidentifier", + nullable: false, + defaultValueSql: "NEWID()" + ); + + migrationBuilder.AddColumn( + name: "Id", + table: "DomainUsers", + type: "uniqueidentifier", + nullable: false, + defaultValueSql: "NEWID()" + ); + + migrationBuilder.AddPrimaryKey( + name: "PK_FutureCreators", + table: "FutureCreators", + column: "Id"); + + migrationBuilder.AddPrimaryKey( + name: "PK_DomainUsers", + table: "DomainUsers", + column: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropPrimaryKey( + name: "PK_FutureCreators", + table: "FutureCreators"); + + migrationBuilder.RenameTable( + name: "FutureCreators", + newName: "FutureCreator"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "DomainUsers", + type: "int", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uniqueidentifier") + .Annotation("SqlServer:Identity", "1, 1"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "FutureCreator", + type: "int", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uniqueidentifier") + .Annotation("SqlServer:Identity", "1, 1"); + + migrationBuilder.AddPrimaryKey( + name: "PK_FutureCreator", + table: "FutureCreator", + column: "Id"); + + migrationBuilder.CreateTable( + name: "TodoLists", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Created = table.Column(type: "datetimeoffset", nullable: false), + CreatedBy = table.Column(type: "nvarchar(max)", nullable: true), + LastModified = table.Column(type: "datetimeoffset", nullable: false), + LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true), + Title = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Colour_Code = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TodoLists", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "TodoItems", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ListId = table.Column(type: "int", nullable: false), + Created = table.Column(type: "datetimeoffset", nullable: false), + CreatedBy = table.Column(type: "nvarchar(max)", nullable: true), + Done = table.Column(type: "bit", nullable: false), + LastModified = table.Column(type: "datetimeoffset", nullable: false), + LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true), + Note = table.Column(type: "nvarchar(max)", nullable: true), + Priority = table.Column(type: "int", nullable: false), + Reminder = table.Column(type: "datetime2", nullable: true), + Title = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TodoItems", x => x.Id); + table.ForeignKey( + name: "FK_TodoItems_TodoLists_ListId", + column: x => x.ListId, + principalTable: "TodoLists", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_TodoItems_ListId", + table: "TodoItems", + column: "ListId"); + } + } +} diff --git a/src/Infrastructure/Data/Migrations/20240404030232_RemovePasswordFromDomainUser.Designer.cs b/src/Infrastructure/Data/Migrations/20240404030232_RemovePasswordFromDomainUser.Designer.cs new file mode 100644 index 0000000..a58545e --- /dev/null +++ b/src/Infrastructure/Data/Migrations/20240404030232_RemovePasswordFromDomainUser.Designer.cs @@ -0,0 +1,368 @@ +// +using System; +using Hutopy.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Hutopy.Infrastructure.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20240404030232_RemovePasswordFromDomainUser")] + partial class RemovePasswordFromDomainUser + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Hutopy.Domain.Entities.FutureCreator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReasonToJoin") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SocialNetworkAccount") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FutureCreators"); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IdentityUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("DomainUsers"); + }); + + modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Data/Migrations/20240404030232_RemovePasswordFromDomainUser.cs b/src/Infrastructure/Data/Migrations/20240404030232_RemovePasswordFromDomainUser.cs new file mode 100644 index 0000000..66d0ef3 --- /dev/null +++ b/src/Infrastructure/Data/Migrations/20240404030232_RemovePasswordFromDomainUser.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Hutopy.Infrastructure.Data.Migrations +{ + /// + public partial class RemovePasswordFromDomainUser : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Password", + table: "DomainUsers"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Password", + table: "DomainUsers", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + } + } +} diff --git a/src/Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs index 0eb80ef..0be5962 100644 --- a/src/Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -24,11 +24,9 @@ namespace Hutopy.Infrastructure.Data.Migrations modelBuilder.Entity("Hutopy.Domain.Entities.FutureCreator", b => { - b.Property("Id") + b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + .HasColumnType("uniqueidentifier"); b.Property("Created") .HasColumnType("datetimeoffset"); @@ -68,16 +66,14 @@ namespace Hutopy.Infrastructure.Data.Migrations b.HasKey("Id"); - b.ToTable("FutureCreator"); + b.ToTable("FutureCreators"); }); - modelBuilder.Entity("Hutopy.Domain.Entities.TodoItem", b => + modelBuilder.Entity("Hutopy.Domain.Entities.User", b => { - b.Property("Id") + b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + .HasColumnType("uniqueidentifier"); b.Property("Created") .HasColumnType("datetimeoffset"); @@ -85,8 +81,16 @@ namespace Hutopy.Infrastructure.Data.Migrations b.Property("CreatedBy") .HasColumnType("nvarchar(max)"); - b.Property("Done") - .HasColumnType("bit"); + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IdentityUserId") + .HasColumnType("uniqueidentifier"); b.Property("LastModified") .HasColumnType("datetimeoffset"); @@ -94,58 +98,17 @@ namespace Hutopy.Infrastructure.Data.Migrations b.Property("LastModifiedBy") .HasColumnType("nvarchar(max)"); - b.Property("ListId") - .HasColumnType("int"); - - b.Property("Note") + b.Property("LastName") + .IsRequired() .HasColumnType("nvarchar(max)"); - b.Property("Priority") - .HasColumnType("int"); - - b.Property("Reminder") - .HasColumnType("datetime2"); - - b.Property("Title") + b.Property("UserName") .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); + .HasColumnType("nvarchar(max)"); b.HasKey("Id"); - b.HasIndex("ListId"); - - b.ToTable("TodoItems"); - }); - - modelBuilder.Entity("Hutopy.Domain.Entities.TodoList", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Created") - .HasColumnType("datetimeoffset"); - - b.Property("CreatedBy") - .HasColumnType("nvarchar(max)"); - - b.Property("LastModified") - .HasColumnType("datetimeoffset"); - - b.Property("LastModifiedBy") - .HasColumnType("nvarchar(max)"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.ToTable("TodoLists"); + b.ToTable("DomainUsers"); }); modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b => @@ -346,40 +309,6 @@ namespace Hutopy.Infrastructure.Data.Migrations b.ToTable("AspNetUserTokens", (string)null); }); - modelBuilder.Entity("Hutopy.Domain.Entities.TodoItem", b => - { - b.HasOne("Hutopy.Domain.Entities.TodoList", "List") - .WithMany("Items") - .HasForeignKey("ListId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("List"); - }); - - modelBuilder.Entity("Hutopy.Domain.Entities.TodoList", b => - { - b.OwnsOne("Hutopy.Domain.ValueObjects.Colour", "Colour", b1 => - { - b1.Property("TodoListId") - .HasColumnType("int"); - - b1.Property("Code") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b1.HasKey("TodoListId"); - - b1.ToTable("TodoLists"); - - b1.WithOwner() - .HasForeignKey("TodoListId"); - }); - - b.Navigation("Colour") - .IsRequired(); - }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) @@ -430,11 +359,6 @@ namespace Hutopy.Infrastructure.Data.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - - modelBuilder.Entity("Hutopy.Domain.Entities.TodoList", b => - { - b.Navigation("Items"); - }); #pragma warning restore 612, 618 } } diff --git a/src/Infrastructure/DependencyInjection.cs b/src/Infrastructure/DependencyInjection.cs index 0651486..3aabf8c 100644 --- a/src/Infrastructure/DependencyInjection.cs +++ b/src/Infrastructure/DependencyInjection.cs @@ -1,8 +1,10 @@ using Hutopy.Application.Common.Interfaces; using Hutopy.Domain.Constants; +using Hutopy.Domain.Interfaces; using Hutopy.Infrastructure.Data; using Hutopy.Infrastructure.Data.Interceptors; using Hutopy.Infrastructure.Identity; +using Hutopy.Infrastructure.Services; using Hutopy.Infrastructure.Stripe; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; @@ -41,6 +43,8 @@ public static class DependencyInjection .AddBearerToken(IdentityConstants.BearerScheme); services.AddAuthorizationBuilder(); + services.AddScoped(); + // Might need to change and use AddIdentity() when we need to integrate connection via third party ( facebook, google ) services diff --git a/src/Infrastructure/Services/UserService.cs b/src/Infrastructure/Services/UserService.cs new file mode 100644 index 0000000..08860cc --- /dev/null +++ b/src/Infrastructure/Services/UserService.cs @@ -0,0 +1,24 @@ +using Hutopy.Domain.Interfaces; +using Hutopy.Infrastructure.Identity; +using Microsoft.AspNetCore.Identity; + +namespace Hutopy.Infrastructure.Services; + +public class UserService(UserManager userManager, SignInManager signInManager) : IUserService +{ + private readonly UserManager _userManager = userManager; + private readonly SignInManager _signInManager = signInManager; + + + public async Task CreateUserAsync(string email, string userName, string password) + { + var applicationUser = new ApplicationUser + { + UserName = userName, + Email = email, + }; + + await _userManager.CreateAsync(applicationUser, password); + } +} + diff --git a/src/Web/DependencyInjection.cs b/src/Web/DependencyInjection.cs index f8ede38..fe6aab9 100644 --- a/src/Web/DependencyInjection.cs +++ b/src/Web/DependencyInjection.cs @@ -1,6 +1,8 @@ using Azure.Identity; using Hutopy.Application.Common.Interfaces; +using Hutopy.Domain.Interfaces; using Hutopy.Infrastructure.Data; +using Hutopy.Infrastructure.Services; using Hutopy.Web.Services; using Microsoft.AspNetCore.Mvc; using NSwag; @@ -15,6 +17,8 @@ public static class DependencyInjection services.AddDatabaseDeveloperPageExceptionFilter(); services.AddScoped(); + services.AddScoped(); + services.AddHttpContextAccessor(); diff --git a/src/Web/Endpoints/JoinUs.cs b/src/Web/Endpoints/JoinUs.cs index 9cd917b..2f1d1a5 100644 --- a/src/Web/Endpoints/JoinUs.cs +++ b/src/Web/Endpoints/JoinUs.cs @@ -1,4 +1,6 @@ -using Hutopy.Application.FutureCreators.Commands; +using Hutopy.Application.Common.Models; +using Hutopy.Application.FutureCreators.Commands; +using Hutopy.Application.FutureCreators.Queries; namespace Hutopy.Web.Endpoints; @@ -7,11 +9,17 @@ public class JoinUs : EndpointGroupBase public override void Map(WebApplication app) { app.MapGroup(this) + .MapGet(GetFutureCreators) .MapPost(CreateFutureCreator); } - private static Task CreateFutureCreator(ISender sender, CreateFutureCreatorCommand command) + private static Task CreateFutureCreator(ISender sender, CreateFutureCreatorCommand command) { return sender.Send(command); } + + private static Task> GetFutureCreators(ISender sender, [AsParameters] GetFutureCreatorListQuery query) + { + return sender.Send(query); + } } diff --git a/src/Web/Endpoints/TodoItems.cs b/src/Web/Endpoints/TodoItems.cs deleted file mode 100644 index cc62ff8..0000000 --- a/src/Web/Endpoints/TodoItems.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Hutopy.Application.Common.Models; -using Hutopy.Application.TodoItems.Commands.CreateTodoItem; -using Hutopy.Application.TodoItems.Commands.DeleteTodoItem; -using Hutopy.Application.TodoItems.Commands.UpdateTodoItem; -using Hutopy.Application.TodoItems.Commands.UpdateTodoItemDetail; -using Hutopy.Application.TodoItems.Queries.GetTodoItemsWithPagination; - -namespace Hutopy.Web.Endpoints; - -public class TodoItems : EndpointGroupBase -{ - public override void Map(WebApplication app) - { - app.MapGroup(this) - .RequireAuthorization() - .MapGet(GetTodoItemsWithPagination) - .MapPost(CreateTodoItem) - .MapPut(UpdateTodoItem, "{id}") - .MapPut(UpdateTodoItemDetail, "UpdateDetail/{id}") - .MapDelete(DeleteTodoItem, "{id}"); - } - - private static Task> GetTodoItemsWithPagination(ISender sender, [AsParameters] GetTodoItemsWithPaginationQuery query) - { - return sender.Send(query); - } - - private static Task CreateTodoItem(ISender sender, CreateTodoItemCommand command) - { - return sender.Send(command); - } - - private static async Task UpdateTodoItem(ISender sender, int id, UpdateTodoItemCommand command) - { - if (id != command.Id) return Results.BadRequest(); - await sender.Send(command); - return Results.NoContent(); - } - - private static async Task UpdateTodoItemDetail(ISender sender, int id, UpdateTodoItemDetailCommand command) - { - if (id != command.Id) return Results.BadRequest(); - await sender.Send(command); - return Results.NoContent(); - } - - private static async Task DeleteTodoItem(ISender sender, int id) - { - await sender.Send(new DeleteTodoItemCommand(id)); - return Results.NoContent(); - } -} diff --git a/src/Web/Endpoints/TodoLists.cs b/src/Web/Endpoints/TodoLists.cs deleted file mode 100644 index a191421..0000000 --- a/src/Web/Endpoints/TodoLists.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Hutopy.Application.TodoLists.Commands.CreateTodoList; -using Hutopy.Application.TodoLists.Commands.DeleteTodoList; -using Hutopy.Application.TodoLists.Commands.UpdateTodoList; -using Hutopy.Application.TodoLists.Queries.GetTodos; - -namespace Hutopy.Web.Endpoints; - -public class TodoLists : EndpointGroupBase -{ - public override void Map(WebApplication app) - { - app.MapGroup(this) - .RequireAuthorization() - .MapGet(GetTodoLists) - .MapPost(CreateTodoList) - .MapPut(UpdateTodoList, "{id}") - .MapDelete(DeleteTodoList, "{id}"); - } - - private static Task GetTodoLists(ISender sender) - { - return sender.Send(new GetTodosQuery()); - } - - private static Task CreateTodoList(ISender sender, CreateTodoListCommand command) - { - return sender.Send(command); - } - - private static async Task UpdateTodoList(ISender sender, int id, UpdateTodoListCommand command) - { - if (id != command.Id) return Results.BadRequest(); - await sender.Send(command); - return Results.NoContent(); - } - - private static async Task DeleteTodoList(ISender sender, int id) - { - await sender.Send(new DeleteTodoListCommand(id)); - return Results.NoContent(); - } -} diff --git a/src/Web/Endpoints/Users.cs b/src/Web/Endpoints/Users.cs index c27114b..63749c4 100644 --- a/src/Web/Endpoints/Users.cs +++ b/src/Web/Endpoints/Users.cs @@ -1,4 +1,6 @@ -using Hutopy.Infrastructure.Identity; +using Hutopy.Application.Users.Commands; +using Hutopy.Domain.Interfaces; +using Hutopy.Infrastructure.Identity; namespace Hutopy.Web.Endpoints; @@ -7,6 +9,13 @@ public class Users : EndpointGroupBase public override void Map(WebApplication app) { app.MapGroup(this) + .MapPost(CreateUser) .MapIdentityApi(); } + + public async Task CreateUser(ISender sender, CreateUserCommand command, IUserService userService) + { + await userService.CreateUserAsync(command.EmailAddress, command.UserName, command.Password); + return await sender.Send(command); + } } diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 85dbf27..803e8f0 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -1,6 +1,8 @@ using Hutopy.Application; +using Hutopy.Domain.Interfaces; using Hutopy.Infrastructure; using Hutopy.Infrastructure.Data; +using Hutopy.Infrastructure.Services; using Hutopy.Web; var builder = WebApplication.CreateBuilder(args); @@ -22,6 +24,7 @@ builder.Services.AddApplicationServices(); builder.Services.AddInfrastructureServices(builder.Configuration); builder.Services.AddWebServices(); +builder.Services.AddScoped(); var app = builder.Build(); diff --git a/src/Web/wwwroot/api/specification.json b/src/Web/wwwroot/api/specification.json index 158be32..944608b 100644 --- a/src/Web/wwwroot/api/specification.json +++ b/src/Web/wwwroot/api/specification.json @@ -7,6 +7,46 @@ }, "paths": { "/api/JoinUs": { + "get": { + "tags": [ + "JoinUs" + ], + "operationId": "GetFutureCreators", + "parameters": [ + { + "name": "PageNumber", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + }, + "x-position": 1 + }, + { + "name": "PageSize", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + }, + "x-position": 2 + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedListOfFutureCreatorListDto" + } + } + } + } + } + }, "post": { "tags": [ "JoinUs" @@ -30,8 +70,8 @@ "content": { "application/json": { "schema": { - "type": "integer", - "format": "int32" + "type": "string", + "format": "guid" } } } @@ -71,73 +111,18 @@ } } }, - "/api/TodoItems": { - "get": { - "tags": [ - "TodoItems" - ], - "operationId": "GetTodoItemsWithPagination", - "parameters": [ - { - "name": "ListId", - "in": "query", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "x-position": 1 - }, - { - "name": "PageNumber", - "in": "query", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "x-position": 2 - }, - { - "name": "PageSize", - "in": "query", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "x-position": 3 - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PaginatedListOfTodoItemBriefDto" - } - } - } - } - }, - "security": [ - { - "JWT": [] - } - ] - }, + "/api/Users": { "post": { "tags": [ - "TodoItems" + "Users" ], - "operationId": "CreateTodoItem", + "operationId": "CreateUser", "requestBody": { "x-name": "command", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTodoItemCommand" + "$ref": "#/components/schemas/CreateUserCommand" } } }, @@ -150,261 +135,13 @@ "content": { "application/json": { "schema": { - "type": "integer", - "format": "int32" + "type": "string", + "format": "guid" } } } } - }, - "security": [ - { - "JWT": [] - } - ] - } - }, - "/api/TodoItems/{id}": { - "put": { - "tags": [ - "TodoItems" - ], - "operationId": "UpdateTodoItem", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "x-position": 1 - } - ], - "requestBody": { - "x-name": "command", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateTodoItemCommand" - } - } - }, - "required": true, - "x-position": 2 - }, - "responses": { - "200": { - "description": "" - } - }, - "security": [ - { - "JWT": [] - } - ] - }, - "delete": { - "tags": [ - "TodoItems" - ], - "operationId": "DeleteTodoItem", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "x-position": 1 - } - ], - "responses": { - "200": { - "description": "" - } - }, - "security": [ - { - "JWT": [] - } - ] - } - }, - "/api/TodoItems/UpdateDetail/{id}": { - "put": { - "tags": [ - "TodoItems" - ], - "operationId": "UpdateTodoItemDetail", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "x-position": 1 - } - ], - "requestBody": { - "x-name": "command", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateTodoItemDetailCommand" - } - } - }, - "required": true, - "x-position": 2 - }, - "responses": { - "200": { - "description": "" - } - }, - "security": [ - { - "JWT": [] - } - ] - } - }, - "/api/TodoLists": { - "get": { - "tags": [ - "TodoLists" - ], - "operationId": "GetTodoLists", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TodosVm" - } - } - } - } - }, - "security": [ - { - "JWT": [] - } - ] - }, - "post": { - "tags": [ - "TodoLists" - ], - "operationId": "CreateTodoList", - "requestBody": { - "x-name": "command", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTodoListCommand" - } - } - }, - "required": true, - "x-position": 1 - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "integer", - "format": "int32" - } - } - } - } - }, - "security": [ - { - "JWT": [] - } - ] - } - }, - "/api/TodoLists/{id}": { - "put": { - "tags": [ - "TodoLists" - ], - "operationId": "UpdateTodoList", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "x-position": 1 - } - ], - "requestBody": { - "x-name": "command", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateTodoListCommand" - } - } - }, - "required": true, - "x-position": 2 - }, - "responses": { - "200": { - "description": "" - } - }, - "security": [ - { - "JWT": [] - } - ] - }, - "delete": { - "tags": [ - "TodoLists" - ], - "operationId": "DeleteTodoList", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "x-position": 1 - } - ], - "responses": { - "200": { - "description": "" - } - }, - "security": [ - { - "JWT": [] - } - ] + } } }, "/api/Users/register": { @@ -822,6 +559,52 @@ }, "components": { "schemas": { + "PaginatedListOfFutureCreatorListDto": { + "type": "object", + "additionalProperties": false, + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FutureCreatorListDto" + } + }, + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "totalPages": { + "type": "integer", + "format": "int32" + }, + "totalCount": { + "type": "integer", + "format": "int32" + }, + "hasPreviousPage": { + "type": "boolean" + }, + "hasNextPage": { + "type": "boolean" + } + } + }, + "FutureCreatorListDto": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "format": "guid" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + } + }, "CreateFutureCreatorCommand": { "type": "object", "additionalProperties": false, @@ -848,6 +631,7 @@ }, "CreateSessionCheckoutCommand": { "type": "object", + "x-abstract": true, "additionalProperties": false, "properties": { "price": { @@ -859,231 +643,24 @@ } } }, - "PaginatedListOfTodoItemBriefDto": { + "CreateUserCommand": { "type": "object", "additionalProperties": false, "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TodoItemBriefDto" - } + "firstName": { + "type": "string" }, - "pageNumber": { - "type": "integer", - "format": "int32" + "lastName": { + "type": "string" }, - "totalPages": { - "type": "integer", - "format": "int32" + "emailAddress": { + "type": "string" }, - "totalCount": { - "type": "integer", - "format": "int32" + "userName": { + "type": "string" }, - "hasPreviousPage": { - "type": "boolean" - }, - "hasNextPage": { - "type": "boolean" - } - } - }, - "TodoItemBriefDto": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "listId": { - "type": "integer", - "format": "int32" - }, - "title": { - "type": "string", - "nullable": true - }, - "done": { - "type": "boolean" - } - } - }, - "CreateTodoItemCommand": { - "type": "object", - "additionalProperties": false, - "properties": { - "listId": { - "type": "integer", - "format": "int32" - }, - "title": { - "type": "string", - "nullable": true - } - } - }, - "UpdateTodoItemCommand": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "title": { - "type": "string", - "nullable": true - }, - "done": { - "type": "boolean" - } - } - }, - "UpdateTodoItemDetailCommand": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "listId": { - "type": "integer", - "format": "int32" - }, - "priority": { - "$ref": "#/components/schemas/PriorityLevel" - }, - "note": { - "type": "string", - "nullable": true - } - } - }, - "PriorityLevel": { - "type": "integer", - "description": "", - "x-enumNames": [ - "None", - "Low", - "Medium", - "High" - ], - "enum": [ - 0, - 1, - 2, - 3 - ] - }, - "TodosVm": { - "type": "object", - "additionalProperties": false, - "properties": { - "priorityLevels": { - "type": "array", - "items": { - "$ref": "#/components/schemas/LookupDto" - } - }, - "lists": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TodoListDto" - } - } - } - }, - "LookupDto": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "title": { - "type": "string", - "nullable": true - } - } - }, - "TodoListDto": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "title": { - "type": "string", - "nullable": true - }, - "colour": { - "type": "string", - "nullable": true - }, - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TodoItemDto" - } - } - } - }, - "TodoItemDto": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "listId": { - "type": "integer", - "format": "int32" - }, - "title": { - "type": "string", - "nullable": true - }, - "done": { - "type": "boolean" - }, - "priority": { - "type": "integer", - "format": "int32" - }, - "note": { - "type": "string", - "nullable": true - } - } - }, - "CreateTodoListCommand": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "string", - "nullable": true - } - } - }, - "UpdateTodoListCommand": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "title": { - "type": "string", - "nullable": true + "password": { + "type": "string" } } }, diff --git a/tests/Application.FunctionalTests/TodoItems/Commands/CreateTodoItemTests.cs b/tests/Application.FunctionalTests/TodoItems/Commands/CreateTodoItemTests.cs deleted file mode 100644 index b228ab0..0000000 --- a/tests/Application.FunctionalTests/TodoItems/Commands/CreateTodoItemTests.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Hutopy.Application.Common.Exceptions; -using Hutopy.Application.TodoItems.Commands.CreateTodoItem; -using Hutopy.Application.TodoLists.Commands.CreateTodoList; -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.FunctionalTests.TodoItems.Commands; - -using static Testing; - -public class CreateTodoItemTests : BaseTestFixture -{ - [Test] - public async Task ShouldRequireMinimumFields() - { - var command = new CreateTodoItemCommand(); - - await FluentActions.Invoking(() => - SendAsync(command)).Should().ThrowAsync(); - } - - [Test] - public async Task ShouldCreateTodoItem() - { - var userId = await RunAsDefaultUserAsync(); - - var listId = await SendAsync(new CreateTodoListCommand - { - Title = "New List" - }); - - var command = new CreateTodoItemCommand - { - ListId = listId, - Title = "Tasks" - }; - - var itemId = await SendAsync(command); - - var item = await FindAsync(itemId); - - item.Should().NotBeNull(); - item!.ListId.Should().Be(command.ListId); - item.Title.Should().Be(command.Title); - item.CreatedBy.Should().Be(userId); - item.Created.Should().BeCloseTo(DateTime.Now, TimeSpan.FromMilliseconds(10000)); - item.LastModifiedBy.Should().Be(userId); - item.LastModified.Should().BeCloseTo(DateTime.Now, TimeSpan.FromMilliseconds(10000)); - } -} diff --git a/tests/Application.FunctionalTests/TodoItems/Commands/DeleteTodoItemTests.cs b/tests/Application.FunctionalTests/TodoItems/Commands/DeleteTodoItemTests.cs deleted file mode 100644 index bb0e1f3..0000000 --- a/tests/Application.FunctionalTests/TodoItems/Commands/DeleteTodoItemTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Hutopy.Application.TodoItems.Commands.CreateTodoItem; -using Hutopy.Application.TodoItems.Commands.DeleteTodoItem; -using Hutopy.Application.TodoLists.Commands.CreateTodoList; -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.FunctionalTests.TodoItems.Commands; - -using static Testing; - -public class DeleteTodoItemTests : BaseTestFixture -{ - [Test] - public async Task ShouldRequireValidTodoItemId() - { - var command = new DeleteTodoItemCommand(99); - - await FluentActions.Invoking(() => - SendAsync(command)).Should().ThrowAsync(); - } - - [Test] - public async Task ShouldDeleteTodoItem() - { - var listId = await SendAsync(new CreateTodoListCommand - { - Title = "New List" - }); - - var itemId = await SendAsync(new CreateTodoItemCommand - { - ListId = listId, - Title = "New Item" - }); - - await SendAsync(new DeleteTodoItemCommand(itemId)); - - var item = await FindAsync(itemId); - - item.Should().BeNull(); - } -} diff --git a/tests/Application.FunctionalTests/TodoItems/Commands/UpdateTodoItemDetailTests.cs b/tests/Application.FunctionalTests/TodoItems/Commands/UpdateTodoItemDetailTests.cs deleted file mode 100644 index 63486bb..0000000 --- a/tests/Application.FunctionalTests/TodoItems/Commands/UpdateTodoItemDetailTests.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Hutopy.Application.TodoItems.Commands.CreateTodoItem; -using Hutopy.Application.TodoItems.Commands.UpdateTodoItem; -using Hutopy.Application.TodoItems.Commands.UpdateTodoItemDetail; -using Hutopy.Application.TodoLists.Commands.CreateTodoList; -using Hutopy.Domain.Entities; -using Hutopy.Domain.Enums; - -namespace Hutopy.Application.FunctionalTests.TodoItems.Commands; - -using static Testing; - -public class UpdateTodoItemDetailTests : BaseTestFixture -{ - [Test] - public async Task ShouldRequireValidTodoItemId() - { - var command = new UpdateTodoItemCommand { Id = 99, Title = "New Title" }; - await FluentActions.Invoking(() => SendAsync(command)).Should().ThrowAsync(); - } - - [Test] - public async Task ShouldUpdateTodoItem() - { - var userId = await RunAsDefaultUserAsync(); - - var listId = await SendAsync(new CreateTodoListCommand - { - Title = "New List" - }); - - var itemId = await SendAsync(new CreateTodoItemCommand - { - ListId = listId, - Title = "New Item" - }); - - var command = new UpdateTodoItemDetailCommand - { - Id = itemId, - ListId = listId, - Note = "This is the note.", - Priority = PriorityLevel.High - }; - - await SendAsync(command); - - var item = await FindAsync(itemId); - - item.Should().NotBeNull(); - item!.ListId.Should().Be(command.ListId); - item.Note.Should().Be(command.Note); - item.Priority.Should().Be(command.Priority); - item.LastModifiedBy.Should().NotBeNull(); - item.LastModifiedBy.Should().Be(userId); - item.LastModified.Should().BeCloseTo(DateTime.Now, TimeSpan.FromMilliseconds(10000)); - } -} diff --git a/tests/Application.FunctionalTests/TodoItems/Commands/UpdateTodoItemTests.cs b/tests/Application.FunctionalTests/TodoItems/Commands/UpdateTodoItemTests.cs deleted file mode 100644 index b3e3ebf..0000000 --- a/tests/Application.FunctionalTests/TodoItems/Commands/UpdateTodoItemTests.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Hutopy.Application.TodoItems.Commands.CreateTodoItem; -using Hutopy.Application.TodoItems.Commands.UpdateTodoItem; -using Hutopy.Application.TodoLists.Commands.CreateTodoList; -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.FunctionalTests.TodoItems.Commands; - -using static Testing; - -public class UpdateTodoItemTests : BaseTestFixture -{ - [Test] - public async Task ShouldRequireValidTodoItemId() - { - var command = new UpdateTodoItemCommand { Id = 99, Title = "New Title" }; - await FluentActions.Invoking(() => SendAsync(command)).Should().ThrowAsync(); - } - - [Test] - public async Task ShouldUpdateTodoItem() - { - var userId = await RunAsDefaultUserAsync(); - - var listId = await SendAsync(new CreateTodoListCommand - { - Title = "New List" - }); - - var itemId = await SendAsync(new CreateTodoItemCommand - { - ListId = listId, - Title = "New Item" - }); - - var command = new UpdateTodoItemCommand - { - Id = itemId, - Title = "Updated Item Title" - }; - - await SendAsync(command); - - var item = await FindAsync(itemId); - - item.Should().NotBeNull(); - item!.Title.Should().Be(command.Title); - item.LastModifiedBy.Should().NotBeNull(); - item.LastModifiedBy.Should().Be(userId); - item.LastModified.Should().BeCloseTo(DateTime.Now, TimeSpan.FromMilliseconds(10000)); - } -} diff --git a/tests/Application.FunctionalTests/TodoLists/Commands/CreateTodoListTests.cs b/tests/Application.FunctionalTests/TodoLists/Commands/CreateTodoListTests.cs deleted file mode 100644 index 2b6edab..0000000 --- a/tests/Application.FunctionalTests/TodoLists/Commands/CreateTodoListTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Hutopy.Application.Common.Exceptions; -using Hutopy.Application.TodoLists.Commands.CreateTodoList; -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.FunctionalTests.TodoLists.Commands; - -using static Testing; - -public class CreateTodoListTests : BaseTestFixture -{ - [Test] - public async Task ShouldRequireMinimumFields() - { - var command = new CreateTodoListCommand(); - await FluentActions.Invoking(() => SendAsync(command)).Should().ThrowAsync(); - } - - [Test] - public async Task ShouldRequireUniqueTitle() - { - await SendAsync(new CreateTodoListCommand - { - Title = "Shopping" - }); - - var command = new CreateTodoListCommand - { - Title = "Shopping" - }; - - await FluentActions.Invoking(() => - SendAsync(command)).Should().ThrowAsync(); - } - - [Test] - public async Task ShouldCreateTodoList() - { - var userId = await RunAsDefaultUserAsync(); - - var command = new CreateTodoListCommand - { - Title = "Tasks" - }; - - var id = await SendAsync(command); - - var list = await FindAsync(id); - - list.Should().NotBeNull(); - list!.Title.Should().Be(command.Title); - list.CreatedBy.Should().Be(userId); - list.Created.Should().BeCloseTo(DateTime.Now, TimeSpan.FromMilliseconds(10000)); - } -} diff --git a/tests/Application.FunctionalTests/TodoLists/Commands/DeleteTodoListTests.cs b/tests/Application.FunctionalTests/TodoLists/Commands/DeleteTodoListTests.cs deleted file mode 100644 index 446992c..0000000 --- a/tests/Application.FunctionalTests/TodoLists/Commands/DeleteTodoListTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Hutopy.Application.TodoLists.Commands.CreateTodoList; -using Hutopy.Application.TodoLists.Commands.DeleteTodoList; -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.FunctionalTests.TodoLists.Commands; - -using static Testing; - -public class DeleteTodoListTests : BaseTestFixture -{ - [Test] - public async Task ShouldRequireValidTodoListId() - { - var command = new DeleteTodoListCommand(99); - await FluentActions.Invoking(() => SendAsync(command)).Should().ThrowAsync(); - } - - [Test] - public async Task ShouldDeleteTodoList() - { - var listId = await SendAsync(new CreateTodoListCommand - { - Title = "New List" - }); - - await SendAsync(new DeleteTodoListCommand(listId)); - - var list = await FindAsync(listId); - - list.Should().BeNull(); - } -} diff --git a/tests/Application.FunctionalTests/TodoLists/Commands/PurgeTodoListsTests.cs b/tests/Application.FunctionalTests/TodoLists/Commands/PurgeTodoListsTests.cs deleted file mode 100644 index 7b92631..0000000 --- a/tests/Application.FunctionalTests/TodoLists/Commands/PurgeTodoListsTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Hutopy.Application.Common.Exceptions; -using Hutopy.Application.Common.Security; -using Hutopy.Application.TodoLists.Commands.CreateTodoList; -using Hutopy.Application.TodoLists.Commands.PurgeTodoLists; -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.FunctionalTests.TodoLists.Commands; - -using static Testing; - -public class PurgeTodoListsTests : BaseTestFixture -{ - [Test] - public async Task ShouldDenyAnonymousUser() - { - var command = new PurgeTodoListsCommand(); - - command.GetType().Should().BeDecoratedWith(); - - var action = () => SendAsync(command); - - await action.Should().ThrowAsync(); - } - - [Test] - public async Task ShouldDenyNonAdministrator() - { - await RunAsDefaultUserAsync(); - - var command = new PurgeTodoListsCommand(); - - var action = () => SendAsync(command); - - await action.Should().ThrowAsync(); - } - - [Test] - public async Task ShouldAllowAdministrator() - { - await RunAsAdministratorAsync(); - - var command = new PurgeTodoListsCommand(); - - var action = () => SendAsync(command); - - await action.Should().NotThrowAsync(); - } - - [Test] - public async Task ShouldDeleteAllLists() - { - await RunAsAdministratorAsync(); - - await SendAsync(new CreateTodoListCommand - { - Title = "New List #1" - }); - - await SendAsync(new CreateTodoListCommand - { - Title = "New List #2" - }); - - await SendAsync(new CreateTodoListCommand - { - Title = "New List #3" - }); - - await SendAsync(new PurgeTodoListsCommand()); - - var count = await CountAsync(); - - count.Should().Be(0); - } -} diff --git a/tests/Application.FunctionalTests/TodoLists/Commands/UpdateTodoListTests.cs b/tests/Application.FunctionalTests/TodoLists/Commands/UpdateTodoListTests.cs deleted file mode 100644 index 37d46d2..0000000 --- a/tests/Application.FunctionalTests/TodoLists/Commands/UpdateTodoListTests.cs +++ /dev/null @@ -1,70 +0,0 @@ -using Hutopy.Application.Common.Exceptions; -using Hutopy.Application.TodoLists.Commands.CreateTodoList; -using Hutopy.Application.TodoLists.Commands.UpdateTodoList; -using Hutopy.Domain.Entities; - -namespace Hutopy.Application.FunctionalTests.TodoLists.Commands; - -using static Testing; - -public class UpdateTodoListTests : BaseTestFixture -{ - [Test] - public async Task ShouldRequireValidTodoListId() - { - var command = new UpdateTodoListCommand { Id = 99, Title = "New Title" }; - await FluentActions.Invoking(() => SendAsync(command)).Should().ThrowAsync(); - } - - [Test] - public async Task ShouldRequireUniqueTitle() - { - var listId = await SendAsync(new CreateTodoListCommand - { - Title = "New List" - }); - - await SendAsync(new CreateTodoListCommand - { - Title = "Other List" - }); - - var command = new UpdateTodoListCommand - { - Id = listId, - Title = "Other List" - }; - - (await FluentActions.Invoking(() => - SendAsync(command)) - .Should().ThrowAsync().Where(ex => ex.Errors.ContainsKey("Title"))) - .And.Errors["Title"].Should().Contain("'Title' must be unique."); - } - - [Test] - public async Task ShouldUpdateTodoList() - { - var userId = await RunAsDefaultUserAsync(); - - var listId = await SendAsync(new CreateTodoListCommand - { - Title = "New List" - }); - - var command = new UpdateTodoListCommand - { - Id = listId, - Title = "Updated List Title" - }; - - await SendAsync(command); - - var list = await FindAsync(listId); - - list.Should().NotBeNull(); - list!.Title.Should().Be(command.Title); - list.LastModifiedBy.Should().NotBeNull(); - list.LastModifiedBy.Should().Be(userId); - list.LastModified.Should().BeCloseTo(DateTime.Now, TimeSpan.FromMilliseconds(10000)); - } -} diff --git a/tests/Application.FunctionalTests/TodoLists/Queries/GetTodosTests.cs b/tests/Application.FunctionalTests/TodoLists/Queries/GetTodosTests.cs deleted file mode 100644 index 2de1eda..0000000 --- a/tests/Application.FunctionalTests/TodoLists/Queries/GetTodosTests.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Hutopy.Application.TodoLists.Queries.GetTodos; -using Hutopy.Domain.Entities; -using Hutopy.Domain.ValueObjects; - -namespace Hutopy.Application.FunctionalTests.TodoLists.Queries; - -using static Testing; - -public class GetTodosTests : BaseTestFixture -{ - [Test] - public async Task ShouldReturnPriorityLevels() - { - await RunAsDefaultUserAsync(); - - var query = new GetTodosQuery(); - - var result = await SendAsync(query); - - result.PriorityLevels.Should().NotBeEmpty(); - } - - [Test] - public async Task ShouldReturnAllListsAndItems() - { - await RunAsDefaultUserAsync(); - - await AddAsync(new TodoList - { - Title = "Shopping", - Colour = Colour.Blue, - Items = - { - new TodoItem { Title = "Apples", Done = true }, - new TodoItem { Title = "Milk", Done = true }, - new TodoItem { Title = "Bread", Done = true }, - new TodoItem { Title = "Toilet paper" }, - new TodoItem { Title = "Pasta" }, - new TodoItem { Title = "Tissues" }, - new TodoItem { Title = "Tuna" } - } - }); - - var query = new GetTodosQuery(); - - var result = await SendAsync(query); - - result.Lists.Should().HaveCount(1); - result.Lists.First().Items.Should().HaveCount(7); - } - - [Test] - public async Task ShouldDenyAnonymousUser() - { - var query = new GetTodosQuery(); - - var action = () => SendAsync(query); - - await action.Should().ThrowAsync(); - } -} diff --git a/tests/Application.UnitTests/Common/Behaviours/RequestLoggerTests.cs b/tests/Application.UnitTests/Common/Behaviours/RequestLoggerTests.cs index 31ee2a5..28b4f49 100644 --- a/tests/Application.UnitTests/Common/Behaviours/RequestLoggerTests.cs +++ b/tests/Application.UnitTests/Common/Behaviours/RequestLoggerTests.cs @@ -1,6 +1,5 @@ using Hutopy.Application.Common.Behaviours; using Hutopy.Application.Common.Interfaces; -using Hutopy.Application.TodoItems.Commands.CreateTodoItem; using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; @@ -9,37 +8,13 @@ namespace Hutopy.Application.UnitTests.Common.Behaviours; public class RequestLoggerTests { - private Mock> _logger = null!; private Mock _user = null!; private Mock _identityService = null!; [SetUp] public void Setup() { - _logger = new Mock>(); _user = new Mock(); _identityService = new Mock(); } - - [Test] - public async Task ShouldCallGetUserNameAsyncOnceIfAuthenticated() - { - _user.Setup(x => x.Id).Returns(Guid.NewGuid().ToString()); - - var requestLogger = new LoggingBehaviour(_logger.Object, _user.Object, _identityService.Object); - - await requestLogger.Process(new CreateTodoItemCommand { ListId = 1, Title = "title" }, new CancellationToken()); - - _identityService.Verify(i => i.GetUserNameAsync(It.IsAny()), Times.Once); - } - - [Test] - public async Task ShouldNotCallGetUserNameAsyncOnceIfUnauthenticated() - { - var requestLogger = new LoggingBehaviour(_logger.Object, _user.Object, _identityService.Object); - - await requestLogger.Process(new CreateTodoItemCommand { ListId = 1, Title = "title" }, new CancellationToken()); - - _identityService.Verify(i => i.GetUserNameAsync(It.IsAny()), Times.Never); - } } diff --git a/tests/Application.UnitTests/Common/Mappings/MappingTests.cs b/tests/Application.UnitTests/Common/Mappings/MappingTests.cs index 70b23d6..fcd2b2a 100644 --- a/tests/Application.UnitTests/Common/Mappings/MappingTests.cs +++ b/tests/Application.UnitTests/Common/Mappings/MappingTests.cs @@ -3,8 +3,6 @@ using System.Runtime.CompilerServices; using AutoMapper; using Hutopy.Application.Common.Interfaces; using Hutopy.Application.Common.Models; -using Hutopy.Application.TodoItems.Queries.GetTodoItemsWithPagination; -using Hutopy.Application.TodoLists.Queries.GetTodos; using Hutopy.Domain.Entities; using NUnit.Framework; @@ -17,7 +15,7 @@ public class MappingTests public MappingTests() { - _configuration = new MapperConfiguration(config => + _configuration = new MapperConfiguration(config => config.AddMaps(Assembly.GetAssembly(typeof(IApplicationDbContext)))); _mapper = _configuration.CreateMapper(); @@ -29,19 +27,6 @@ public class MappingTests _configuration.AssertConfigurationIsValid(); } - [Test] - [TestCase(typeof(TodoList), typeof(TodoListDto))] - [TestCase(typeof(TodoItem), typeof(TodoItemDto))] - [TestCase(typeof(TodoList), typeof(LookupDto))] - [TestCase(typeof(TodoItem), typeof(LookupDto))] - [TestCase(typeof(TodoItem), typeof(TodoItemBriefDto))] - public void ShouldSupportMappingFromSourceToDestination(Type source, Type destination) - { - var instance = GetInstanceOf(source); - - _mapper.Map(instance, source, destination); - } - private object GetInstanceOf(Type type) { if (type.GetConstructor(Type.EmptyTypes) != null)