diff --git a/Backend/backend_assessment/CineFlex/CineFlex.API/Controllers/PostController.cs b/Backend/backend_assessment/CineFlex/CineFlex.API/Controllers/PostController.cs new file mode 100644 index 000000000..8defb992a --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.API/Controllers/PostController.cs @@ -0,0 +1,49 @@ +using CineFlex.Application.Features.Posts.CQRS.Commands; +using CineFlex.Application.Features.Posts.CQRS.Queries; +using CineFlex.Application.Features.Posts.DTOs; +using Microsoft.AspNetCore.Mvc; + +namespace CineFlex.API.Controllers +{ + [ApiController] + + [Route("api/[Controller]")] + public class PostController : BaseApiController + { + [HttpGet("{id}")] + public async Task Get(int id) + { + var query = new GetPostDetailQuery { Id = id }; + var response = await Mediator.Send(query); + return HandleResult(response); + } + [HttpGet] + public async Task>> GetPosts() + { + var query = new GetPostListQuery(); + var response = await Mediator.Send(query); + return HandleResult(response); + } + [HttpPost] + public async Task Post([FromBody] CreatePostDto createPostDto) + { + var command = new CreatePostCommand { CreatePostDto = createPostDto }; + var response = await Mediator.Send(command); + return HandleResult(response); + } + [HttpPatch] + public async Task Put([FromBody] UpdatePostDto updatePostDto) + { + var command = new UpdatePostCommand { UpdatePostDto = updatePostDto }; + var response = await Mediator.Send(command); + return HandleResult(response); + } + [HttpDelete] + public async Task Delete(int Id) + { + var command = new DeletePostCommand { Id = Id }; + var response = await Mediator.Send(command); + return HandleResult(response); + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.API/Controllers/UserController.cs b/Backend/backend_assessment/CineFlex/CineFlex.API/Controllers/UserController.cs new file mode 100644 index 000000000..7a1e0ed65 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.API/Controllers/UserController.cs @@ -0,0 +1,28 @@ +using CineFlex.Application.Contracts.Identity; +using CineFlex.Application.Models.Identity; +using CineFlex.Application.Responses; +using Microsoft.AspNetCore.Mvc; + +namespace CineFlex.API.Controllers +{ + [Route("api/[Controller]")] + [ApiController] + public class UserController : BaseApiController + { + private readonly IAuthService _authenticationService; + public UserController(IAuthService authenticationService) + { + _authenticationService = authenticationService; + } + [HttpPost("login")] + public async Task>> Login(AuthRequest request) + { + return Ok(await _authenticationService.Login(request)); + } + [HttpPost("signUp")] + public async Task>> Registor(RegistrationRequest request) + { + return Ok(await _authenticationService.Registor(request)); + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.API/Program.cs b/Backend/backend_assessment/CineFlex/CineFlex.API/Program.cs index 4e1afd370..aa97cbc91 100644 --- a/Backend/backend_assessment/CineFlex/CineFlex.API/Program.cs +++ b/Backend/backend_assessment/CineFlex/CineFlex.API/Program.cs @@ -5,6 +5,17 @@ var builder = WebApplication.CreateBuilder(args); +builder.Services.Configure(options => { + options.Password.RequireDigit = true; + options.Password.RequireLowercase = false; + options.Password.RequireNonAlphanumeric = false; + options.Password.RequireUppercase = false; + options.Password.RequiredLength = 6; + options.Password.RequiredUniqueChars = 1; + + +}); + // Add services builder.Services.ConfigureApplicationServices(); builder.Services.ConfigurePersistenceServices(builder.Configuration); diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Mocks/MockPostRepository.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Mocks/MockPostRepository.cs new file mode 100644 index 000000000..b98c18c1f --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Mocks/MockPostRepository.cs @@ -0,0 +1,76 @@ +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Domain; +using Moq; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.UnitTest.Mocks +{ + public static class MockPostRepository + { + public static Mock GetPostRepository() + { + var posts = new List{ + new Post(){ + Id = 1, + Title = "This is backend assessement first", + Content = "It contain the description of assessment first", + PostUserId= 1 + } + , + new Post(){ + Id=2, + Title = "This is backend assessement second", + Content = "It contain the description of assessment second", + PostUserId = 1 + }, + new Post(){ + Id= 3, + Title= "This is backend assessement third", + Content="It contain the description of assessment third" + + } + + }; + + var mockRepo = new Mock(); + + mockRepo.Setup(r => r.Get(It.IsAny())).ReturnsAsync((int id) => + { + var post = posts.FirstOrDefault(p => p.Id == id); + return post; + }); + + mockRepo.Setup(r => r.GetAll()).ReturnsAsync(posts); + + mockRepo.Setup(r => r.Add(It.IsAny())).ReturnsAsync((Post post) => { + posts.Add(post); + return post; + }); + + mockRepo.Setup(p => p.Update(It.IsAny())).Callback((Post post) => { + var newPost = posts.FirstOrDefault(p => p.Id == post.Id); + if (newPost != null) + { + newPost.Title = post.Title; + newPost.Content = post.Content; + } + + }); + + mockRepo.Setup(p => p.Delete(It.IsAny())).Callback((Post post) => { + var newPost = posts.FirstOrDefault(p => p.Id == post.Id); + if (newPost != null) + { + posts.Remove(newPost); + } + }); + + return mockRepo; + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Mocks/MockUnitOfWork.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Mocks/MockUnitOfWork.cs new file mode 100644 index 000000000..e38722a09 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Mocks/MockUnitOfWork.cs @@ -0,0 +1,22 @@ +using CineFlex.Application.Contracts.Persistence; +using Moq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.UnitTest.Mocks +{ + public class MockUnitOfWork + { + public static Mock GetUnitOfWork() + { + var mockUow = new Mock(); + var mockPostRepository = MockPostRepository.GetPostRepository(); + + mockUow.Setup(uow => uow.PostRepository).Returns(mockPostRepository.Object); + return mockUow; + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Posts/CreatePostCommandHandlerTest.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Posts/CreatePostCommandHandlerTest.cs new file mode 100644 index 000000000..df0949a6e --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Posts/CreatePostCommandHandlerTest.cs @@ -0,0 +1,158 @@ +using AutoMapper; +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Application.Features.Posts.CQRS.Commands; +using CineFlex.Application.Features.Posts.CQRS.Handlers; +using CineFlex.Application.Features.Posts.DTOs; +using CineFlex.Application.Profiles; +using CineFlex.Application.Responses; +using CineFlex.Application.UnitTest.Mocks; +using Moq; +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace CineFlex.Application.UnitTest.Posts +{ + public class CreatePostCommandHandlerTest + { + + private readonly IMapper _mapper; + private readonly Mock _mockUow; + private readonly CreatePostCommandHandler _handler; + + public CreatePostCommandHandlerTest() + { + _mockUow = MockUnitOfWork.GetUnitOfWork(); + var mapperConfig = new MapperConfiguration(c => { c.AddProfile(); }); + _mapper = mapperConfig.CreateMapper(); + _handler = new CreatePostCommandHandler(_mockUow.Object, _mapper); + + } + [Fact] + public async Task ValidatePostCreationTest() + { + // arrange + var request = new CreatePostCommand() + { + CreatePostDto = new CreatePostDto + { + Title = "This is backend assessement firs", + Content = "It contain the description of assessment first", + PostUserId = 1 + } + }; + + + // Act + var response = await _handler.Handle(request, CancellationToken.None); + // Assert + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeTrue(); + response.Value.ShouldBe(4); + + + + } + [Fact] + public async Task InValidatePostCreationWithoutUserId() + { + + //Arrange + var request = new CreatePostCommand + { + CreatePostDto = new CreatePostDto + { + Title = "This is backend assessement nothing", + Content = "It contain the description of assessment first" + } + }; + + //Act + var response = await _handler.Handle(request, CancellationToken.None); + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeFalse(); + + } + + + [Fact] + public async Task InvalidatePostCreationWithoutTitle() + { + var request = new CreatePostCommand + { + CreatePostDto = new CreatePostDto + { + Content = "It contain the description of assessment first", + PostUserId = 1 + } + }; + + var response = await _handler.Handle(request, CancellationToken.None); + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeFalse(); + } + + [Fact] + public async Task InvalidatePostCreationWithoutContent() + { + var request = new CreatePostCommand + { + CreatePostDto = new CreatePostDto + { + Title = "This is backend assessement first", + PostUserId = 1 + } + }; + + var response = await _handler.Handle(request, CancellationToken.None); + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeFalse(); + } + + [Fact] + public async Task InvalidatePostCreationWithNullTitle() + { + var request = new CreatePostCommand + { + CreatePostDto = new CreatePostDto + { + Title = null, + Content = "It contain the description of assessment first", + PostUserId = 1 + } + }; + + var response = await _handler.Handle(request, CancellationToken.None); + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeFalse(); + } + + [Fact] + public async Task InvalidatePostCreationWithNullContent() + { + var request = new CreatePostCommand + { + CreatePostDto = new CreatePostDto + { + Title = "This is backend assessement first", + Content = null, + PostUserId = 1 + } + }; + + var response = await _handler.Handle(request, CancellationToken.None); + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeFalse(); + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Posts/DeleteCommandHandlerTest.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Posts/DeleteCommandHandlerTest.cs new file mode 100644 index 000000000..33b86ac5d --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Posts/DeleteCommandHandlerTest.cs @@ -0,0 +1,64 @@ +using AutoMapper; +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Application.Features.Posts.CQRS.Commands; +using CineFlex.Application.Features.Posts.CQRS.Handlers; +using CineFlex.Application.Profiles; +using CineFlex.Application.Responses; +using CineFlex.Application.UnitTest.Mocks; +using MediatR; +using Moq; +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace CineFlex.Application.UnitTest.Posts +{ + public class DeleteCommandHandlerTest + { + private readonly IMapper _mapper; + private readonly Mock _mockUow; + private readonly DeletePostCommandHandler _handler; + + public DeleteCommandHandlerTest() + { + _mockUow = MockUnitOfWork.GetUnitOfWork(); + var mapperConfig = new MapperConfiguration(c => { c.AddProfile(); }); + _mapper = mapperConfig.CreateMapper(); + _handler = new DeletePostCommandHandler(_mockUow.Object, _mapper); + } + + [Fact] + public async void ValidatePostDeletionTest() + { + + + var request = new DeletePostCommand { Id = 1 }; + var response = await _handler.Handle(request, CancellationToken.None); + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeTrue(); + + + + } + + [Fact] + public async void InValidatePostDeletionTest() + { + + + var request = new DeletePostCommand { Id = 5000 }; + var response = await _handler.Handle(request, CancellationToken.None); + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeFalse(); + + + + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Posts/UpdatePostCommandHandlerTest.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Posts/UpdatePostCommandHandlerTest.cs new file mode 100644 index 000000000..230c74cfd --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application.UnitTest/Posts/UpdatePostCommandHandlerTest.cs @@ -0,0 +1,106 @@ +using AutoMapper; +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Application.Features.Posts.CQRS.Commands; +using CineFlex.Application.Features.Posts.CQRS.Handlers; +using CineFlex.Application.Features.Posts.DTOs; +using CineFlex.Application.Profiles; +using CineFlex.Application.Responses; +using CineFlex.Application.UnitTest.Mocks; +using MediatR; +using Moq; +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace CineFlex.Application.UnitTest.Posts +{ + public class UpdatePostCommandHandlerTest + { + private readonly IMapper _mapper; + private readonly Mock _mockUow; + private readonly UpdatePostCommandHandler _handler; + public UpdatePostCommandHandlerTest() + { + _mockUow = MockUnitOfWork.GetUnitOfWork(); + var mapperConfig = new MapperConfiguration(c => { c.AddProfile(); }); + _mapper = mapperConfig.CreateMapper(); + _handler = new UpdatePostCommandHandler(_mockUow.Object, _mapper); + } + + [Fact] + public async Task validatePostUpdate() + { + var postUpdate = new UpdatePostDto + { + + Title = "This is backend assessement first", + Content = "It contain the description of assessment first" + }; + var response = await _handler.Handle(new UpdatePostCommand() + { + UpdatePostDto = postUpdate + }, CancellationToken.None); + + var post = await _mockUow.Object.PostRepository.Get(id: 1); + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + post.Title.ShouldBe(postUpdate.Title); + post.Content.ShouldBe(postUpdate.Content); + response.Success.ShouldBeTrue(); + } + + [Fact] + public async Task InvalidPostUpdateWithInvalidIdTest() + { + var response = await _handler.Handle(new UpdatePostCommand() + { + UpdatePostDto = new UpdatePostDto() + { + Id = 2000, + Title = "This is backend assessement second", + Content = "It contain the description of assessment second" + } + }, CancellationToken.None); + + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeFalse(); + } + + [Fact] + public async Task InvalidPostUpdateWithNullTest() + { + var response = await _handler.Handle(new UpdatePostCommand() + { + UpdatePostDto = new UpdatePostDto() + { + Id = 2, + Title = null, + Content = null + } + }, CancellationToken.None); + + response.ShouldNotBeNull(); + response.ShouldBeOfType>(); + response.Success.ShouldBeFalse(); + } + + [Fact] + public async Task InvalidReviewUpdateWithEmptyTittleTest() + { + var response = await _handler.Handle(new UpdatePostCommand() + { + UpdatePostDto = new UpdatePostDto() + { + Id = 2, + Title = "", + Content = "It contain the description of assessment third" + } + }, CancellationToken.None); + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/CineFlex.Application.csproj b/Backend/backend_assessment/CineFlex/CineFlex.Application/CineFlex.Application.csproj index 117b85cd5..751fd086c 100644 --- a/Backend/backend_assessment/CineFlex/CineFlex.Application/CineFlex.Application.csproj +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/CineFlex.Application.csproj @@ -25,7 +25,7 @@ - + diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Constants/CustomClaimTypes.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Constants/CustomClaimTypes.cs index 21d7b1737..85e177e56 100644 --- a/Backend/backend_assessment/CineFlex/CineFlex.Application/Constants/CustomClaimTypes.cs +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Constants/CustomClaimTypes.cs @@ -7,5 +7,7 @@ namespace CineFlex.Application.Constants public static class CustomClaimTypes { public const string Uid = "uid"; + + public const string postUserId = "postUserId"; } } diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Identity/IAuthService.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Identity/IAuthService.cs new file mode 100644 index 000000000..7f8e03462 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Identity/IAuthService.cs @@ -0,0 +1,16 @@ +using CineFlex.Application.Models.Identity; +using CineFlex.Application.Responses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Contracts.Identity +{ + public interface IAuthService + { + Task> Login(AuthRequest authRequest); + Task> Registor(RegistrationRequest registrationRequest); + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Identity/IUserService.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Identity/IUserService.cs new file mode 100644 index 000000000..924f46631 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Identity/IUserService.cs @@ -0,0 +1,15 @@ +using CineFlex.Application.Models.Identity; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Contracts.Identity +{ + public class IUserService + { + Task> GetBloggers(); + Task GetBlogger(string UserId); + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Persistence/IPostRepository.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Persistence/IPostRepository.cs new file mode 100644 index 000000000..8074ff7e5 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Persistence/IPostRepository.cs @@ -0,0 +1,13 @@ +using CineFlex.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Contracts.Persistence +{ + public interface IPostRepository : IGenericRepository + { + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Persistence/IUnitOfWork.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Persistence/IUnitOfWork.cs index 60a0724e4..a903d154b 100644 --- a/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Persistence/IUnitOfWork.cs +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Contracts/Persistence/IUnitOfWork.cs @@ -9,6 +9,7 @@ namespace CineFlex.Application.Contracts.Persistence { public interface IUnitOfWork : IDisposable { + IPostRepository PostRepository { get; } IMovieRepository MovieRepository { get; } ICinemaRepository CinemaRepository { get; } Task Save(); diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Commands/CreatePostCommand.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Commands/CreatePostCommand.cs new file mode 100644 index 000000000..356cd0a2e --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Commands/CreatePostCommand.cs @@ -0,0 +1,17 @@ +using CineFlex.Application.Features.Posts.DTOs; +using CineFlex.Application.Responses; +using MediatR; +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Commands +{ + public class CreatePostCommand : IRequest> + { + public CreatePostDto CreatePostDto { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Commands/DeletePostCommand.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Commands/DeletePostCommand.cs new file mode 100644 index 000000000..beb845a4d --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Commands/DeletePostCommand.cs @@ -0,0 +1,16 @@ +using CineFlex.Application.Responses; +using MediatR; +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Commands +{ + public class DeletePostCommand : IRequest> + { + public int Id { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Commands/UpdatePostCommand.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Commands/UpdatePostCommand.cs new file mode 100644 index 000000000..c84276013 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Commands/UpdatePostCommand.cs @@ -0,0 +1,16 @@ +using CineFlex.Application.Features.Posts.DTOs; +using CineFlex.Application.Responses; +using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Commands +{ + public class UpdatePostCommand : IRequest> + { + public UpdatePostDto UpdatePostDto { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/CreatePostCommandHandler.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/CreatePostCommandHandler.cs new file mode 100644 index 000000000..0e608c0ef --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/CreatePostCommandHandler.cs @@ -0,0 +1,63 @@ +using AutoMapper; +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Application.Features.Posts.CQRS.Commands; +using CineFlex.Application.Features.Posts.DTOs.Validators; +using CineFlex.Application.Responses; +using CineFlex.Domain; +using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Handlers +{ + public class CreatePostCommandHandler : IRequestHandler> + { + private readonly IUnitOfWork _unitOfWork; + private readonly IMapper _mapper; + + public CreatePostCommandHandler(IUnitOfWork unitOfWork, IMapper mapper) + { + _unitOfWork = unitOfWork; + _mapper = mapper; + } + + public async Task> Handle(CreatePostCommand request, CancellationToken cancellationToken) + { + var validator = new CreatePostDtoValidator(); + var validationResult = await validator.ValidateAsync(request.CreatePostDto); + if (validationResult.IsValid == false) + { + return new BaseCommandResponse() + { + Success = false, + Message = "Creation Failed", + Errors = validationResult.Errors.Select(r => r.ErrorMessage).ToList() + }; + } + var post = _mapper.Map(request.CreatePostDto); + await _unitOfWork.PostRepository.Add(post); + if (await _unitOfWork.Save() == 0) + { + return new BaseCommandResponse() + { + Success = false, + Message = "Server Error", + + }; + + + } + return new BaseCommandResponse() + { + Success = true, + Message = "Successfully Created", + Value = post.Id, + + }; + + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/DeletePostCommandHandler.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/DeletePostCommandHandler.cs new file mode 100644 index 000000000..8a05213ba --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/DeletePostCommandHandler.cs @@ -0,0 +1,53 @@ +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Application.Exceptions; +using CineFlex.Application.Features.Posts.CQRS.Commands; +using CineFlex.Application.Responses; +using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Handlers +{ + public class DeletePostCommandHandler : IRequestHandler> + { + private readonly IUnitOfWork _unitOfWork; + public DeletePostCommandHandler(IUnitOfWork unitOfWork, AutoMapper.IMapper _mapper) + { + _unitOfWork = unitOfWork; + } + public async Task> Handle(DeletePostCommand request, CancellationToken cancellationToken) + { + var post = await _unitOfWork.PostRepository.Get(request.Id); + if (post == null) + { + var error = new NotFoundException(nameof(post), request.Id); + return new BaseCommandResponse() + { + Success = false, + Message = "Not Exist", + Errors = new List(){ + $"{error}" + } + }; + } + await _unitOfWork.PostRepository.Delete(post); + if (await _unitOfWork.Save() == 0) + { + return new BaseCommandResponse() + { + Success = false, + Message = "Server Error" + }; + } + return new BaseCommandResponse() + { + Success = true, + Message = "Successfully Deleted" + }; + + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/GetPostDetailQueryHandler.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/GetPostDetailQueryHandler.cs new file mode 100644 index 000000000..9fc45910e --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/GetPostDetailQueryHandler.cs @@ -0,0 +1,52 @@ +using AutoMapper; +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Application.Exceptions; +using CineFlex.Application.Features.Posts.CQRS.Queries; +using CineFlex.Application.Features.Posts.DTOs; +using CineFlex.Application.Responses; +using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Handlers +{ + public class GetPostDetailQueryHandler : IRequestHandler> + { + private readonly IUnitOfWork _unitOfWork; + private readonly IMapper _mapper; + + public GetPostDetailQueryHandler(IUnitOfWork unitOfWork, IMapper mapper) + { + _unitOfWork = unitOfWork; + _mapper = mapper; + } + + public async Task> Handle(GetPostDetailQuery request, CancellationToken cancellationToken) + { + var post = await _unitOfWork.PostRepository.Get(request.Id); + if (post == null) + { + var error = new NotFoundException(nameof(post), request.Id); + return new BaseCommandResponse() + { + Success = false, + Message = "Not Exist", + Errors = new List(){ + $"{error}" + } + }; + } + return new BaseCommandResponse() + { + + Success = true, + Message = "Successfull", + Value = _mapper.Map(post) + + }; + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/GetPostListQueryHandler.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/GetPostListQueryHandler.cs new file mode 100644 index 000000000..456029843 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/GetPostListQueryHandler.cs @@ -0,0 +1,55 @@ +using AutoMapper; +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Application.Exceptions; +using CineFlex.Application.Features.Posts.CQRS.Queries; +using CineFlex.Application.Features.Posts.DTOs; +using CineFlex.Application.Responses; +using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Handlers +{ + public class GetPostListQueryHandler : IRequestHandler>> + { + private readonly IUnitOfWork _unitOfWork; + private readonly IMapper _mapper; + public GetPostListQueryHandler(IUnitOfWork unitOfWork, IMapper mapper) + { + _unitOfWork = unitOfWork; + _mapper = mapper; + } + + + + public async Task>> Handle(GetPostListQuery request, CancellationToken cancellationToken) + { + var posts = await _unitOfWork.PostRepository.GetAll(); + if (posts == null || posts.Count == 0) + { + + var error = new NotFoundException(nameof(posts), request); + return new BaseCommandResponse>() + { + + Success = false, + Message = "No Posts Exist", + Errors = new List(){ + $"{error}" + } + + }; + } + return new BaseCommandResponse>() + { + Value = _mapper.Map>(posts), + Success = true, + Message = "Successful", + + }; + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/UpdatePostCommandHandler.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/UpdatePostCommandHandler.cs new file mode 100644 index 000000000..fd63f6ea4 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Handlers/UpdatePostCommandHandler.cs @@ -0,0 +1,70 @@ +using AutoMapper; +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Application.Exceptions; +using CineFlex.Application.Features.Posts.CQRS.Commands; +using CineFlex.Application.Features.Posts.DTOs.Validators; +using CineFlex.Application.Responses; +using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Handlers +{ + public class UpdatePostCommandHandler : IRequestHandler> + { + private readonly IUnitOfWork _unitOfWork; + private readonly IMapper _mapper; + public UpdatePostCommandHandler(IUnitOfWork unitOfWork, IMapper mapper) + { + _unitOfWork = unitOfWork; + _mapper = mapper; + } + public async Task> Handle(UpdatePostCommand request, CancellationToken cancellationToken) + { + var validator = new UpdateDtoValidator(); + var validationResult = await validator.ValidateAsync(request.UpdatePostDto); + if (validationResult.IsValid == false) + { + return new BaseCommandResponse() + { + Success = false, + Message = "Failed to Update", + Errors = validationResult.Errors.Select(e => e.ErrorMessage).ToList() + }; + } + var post = await _unitOfWork.PostRepository.Get(request.UpdatePostDto.Id); + if (post == null) + { + var error = new NotFoundException(nameof(post), request.UpdatePostDto.Id); + return new BaseCommandResponse() + { + Success = false, + Message = "Not Exist", + Errors = new List(){ + $"{error}" + } + }; + + } + _mapper.Map(post, request.UpdatePostDto); + await _unitOfWork.PostRepository.Update(post); + if (await _unitOfWork.Save() == 0) + { + return new BaseCommandResponse() + { + Success = false, + Message = "Server Error" + }; + } + return new BaseCommandResponse() + { + Success = true, + Message = "Updated Successfully" + + }; + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Queries/GetPostDetailQuery.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Queries/GetPostDetailQuery.cs new file mode 100644 index 000000000..2c0322878 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Queries/GetPostDetailQuery.cs @@ -0,0 +1,16 @@ +using CineFlex.Application.Features.Posts.DTOs; +using CineFlex.Application.Responses; +using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Queries +{ + public class GetPostDetailQuery : IRequest> + { + public int Id { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Queries/GetPostListQuery.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Queries/GetPostListQuery.cs new file mode 100644 index 000000000..c2a9e0d6a --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/CQRS/Queries/GetPostListQuery.cs @@ -0,0 +1,15 @@ +using CineFlex.Application.Features.Posts.DTOs; +using CineFlex.Application.Responses; +using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.CQRS.Queries +{ + public class GetPostListQuery : IRequest>> + { + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/CreatePostDto.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/CreatePostDto.cs new file mode 100644 index 000000000..0dce5ebc8 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/CreatePostDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.DTOs +{ + public class CreatePostDto + { + public string Title { get; set; } + public string Content { get; set; } + public int PostUserId { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/IPostDto.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/IPostDto.cs new file mode 100644 index 000000000..bfcac3131 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/IPostDto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.DTOs +{ + public interface IPostDto + { + int Id { get; set; } + string Title { get; set; } + string Content { get; set; } + int PostUserId { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/PostDto.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/PostDto.cs new file mode 100644 index 000000000..58ff728b6 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/PostDto.cs @@ -0,0 +1,16 @@ +using CineFlex.Application.Features.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.DTOs +{ + public class PostDto : BaseDto, IPostDto + { + public string Title { get; set; } + public string Content { get; set; } + public int PostUserId { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/UpdatePostDto.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/UpdatePostDto.cs new file mode 100644 index 000000000..ad3ab33a5 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/UpdatePostDto.cs @@ -0,0 +1,15 @@ +using CineFlex.Application.Features.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.DTOs +{ + public class UpdatePostDto : BaseDto + { + public string Title { get; set; } + public string Content { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/Validators/CreatePostDtoValidator.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/Validators/CreatePostDtoValidator.cs new file mode 100644 index 000000000..e6ea2a82e --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/Validators/CreatePostDtoValidator.cs @@ -0,0 +1,42 @@ +using FluentValidation; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.DTOs.Validators +{ + public class CreatePostDtoValidator : AbstractValidator + { + public CreatePostDtoValidator() + { + + RuleFor(p => p.Title) + .NotNull() + .WithMessage("Post must have {PropertyName}") + .NotEmpty() + .WithMessage("Post need to have {PropertyName}") + .MaximumLength(50) + .WithMessage("{PropertyName} length should be less than {PropertyValue}"); + RuleFor(p => p.Content) + .NotNull() + .WithMessage("Post must have {PropertyName}") + .NotEmpty() + .WithMessage("Post need to have {PropertyName}") + .MaximumLength(500) + .WithMessage("{PropertyName} length should be less than {PropertyValue}"); + RuleFor(p => p.PostUserId) + .NotNull() + .WithMessage("Post must have {ProperyName}") + .NotEmpty() + .WithMessage("Post need to have {PropertyName}") + .Must(BeValidPostUserId).WithMessage("Invalid PostUserId"); + } + private bool BeValidPostUserId(int postUserId) + { + var userService = new UserService(); + return userService.Exists(postUserId); + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/Validators/UpdateDtoValidator.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/Validators/UpdateDtoValidator.cs new file mode 100644 index 000000000..641328b6f --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Features/Posts/DTOs/Validators/UpdateDtoValidator.cs @@ -0,0 +1,31 @@ +using FluentValidation; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Features.Posts.DTOs.Validators +{ + public class UpdateDtoValidator : AbstractValidator + { + public UpdateDtoValidator() + { + RuleFor(p => p.Title) + .NotNull() + .WithMessage("Post must have {PropertyName}") + .NotEmpty() + .WithMessage("Post need to have {ProperyName}") + .MaximumLength(50) + .WithMessage("{PropertyName} length should be less than {PropertyValue}"); + RuleFor(p => p.Content) + .NotNull() + .WithMessage("Post must have {PropertyName}") + .NotEmpty() + .WithMessage("Post need to have {PropertyName}") + .MaximumLength(500) + .WithMessage("{PropertyName} length is less than {PropertyValue}"); + + } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/AuthRequest.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/AuthRequest.cs new file mode 100644 index 000000000..79c9c647a --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/AuthRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Models.Identity +{ + public class AuthRequest + { + public string Email { get; set; } + public string Password { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/AuthResponse.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/AuthResponse.cs new file mode 100644 index 000000000..9b6b3f423 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/AuthResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Models.Identity +{ + public class AuthResponse + { + public string Id { get; set; } + public string UserName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Token { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/Blogger.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/Blogger.cs new file mode 100644 index 000000000..548332fe0 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/Blogger.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Models.Identity +{ + public class Blogger + { + public string Id { get; set; } + public string AppUserId { get; set; } + public string UserName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public IList Roles { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/RegistrationRequest.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/RegistrationRequest.cs new file mode 100644 index 000000000..ce387c176 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/RegistrationRequest.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Models.Identity +{ + public class RegistrationRequest + { + [Required] + public string UserName { get; set; } + [Required] + public string FirstName { get; set; } + [Required] + public string LastName { get; set; } + + [Required] + [EmailAddress] + public string Email { get; set; } + + [Required] + [MinLength(6)] + public string Password { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/RegistrationResponse.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/RegistrationResponse.cs new file mode 100644 index 000000000..614f73b47 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Models/Identity/RegistrationResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Models.Identity +{ + public class RegistrationResponse + { + public string UserId { get; set; } + public int postUserId { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Profiles/MappingProfile.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Profiles/MappingProfile.cs index 7c00bdd4c..dce01c789 100644 --- a/Backend/backend_assessment/CineFlex/CineFlex.Application/Profiles/MappingProfile.cs +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Profiles/MappingProfile.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using CineFlex.Application.Features.Posts.DTOs; namespace CineFlex.Application.Profiles { @@ -26,6 +27,11 @@ public MappingProfile() CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); + + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); } } } diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Application/Responses/Result.cs b/Backend/backend_assessment/CineFlex/CineFlex.Application/Responses/Result.cs new file mode 100644 index 000000000..89475d228 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Application/Responses/Result.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Application.Responses +{ + public class Result + { + public bool Success { get; set; } + public string Message { get; set; } + public T? Value { get; set; } + public List Errors { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Domain/Post.cs b/Backend/backend_assessment/CineFlex/CineFlex.Domain/Post.cs new file mode 100644 index 000000000..71b1d65f4 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Domain/Post.cs @@ -0,0 +1,21 @@ +using CineFlex.Domain.Common; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Domain +{ + public class Post : BaseDomainEntity + { + public string Title { get; set; } + public string Content { get; set; } + + public int PostUserId { get; set; } + + [ForeignKey("PostUserId")] + public PostUser Creator { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Domain/PostUser.cs b/Backend/backend_assessment/CineFlex/CineFlex.Domain/PostUser.cs new file mode 100644 index 000000000..8c761444d --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Domain/PostUser.cs @@ -0,0 +1,22 @@ +using CineFlex.Domain.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Domain +{ + public class PostUser: BaseDomainEntity + { + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string UserName { get; set; } + public string Password { get; set; } + public string Role { get; set; } + public string UserId { get; set; } + public ICollection Posts { get; set; } + + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/CineFlexDbContex.cs b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/CineFlexDbContex.cs index 20ccf56db..7f7427751 100644 --- a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/CineFlexDbContex.cs +++ b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/CineFlexDbContex.cs @@ -43,6 +43,7 @@ public override Task SaveChangesAsync(CancellationToken cancellationToken = public DbSet Cinemas { get; set; } public DbSet Movies { get; set; } + public DbSet Posts { get; set; } } } diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/AuthRequest.cs b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/AuthRequest.cs new file mode 100644 index 000000000..7743b6f10 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/AuthRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Persistence.Models +{ + public class AuthRequest + { + public string Email { get; set; } + public string Password { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/AuthResponse.cs b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/AuthResponse.cs new file mode 100644 index 000000000..8e3573d89 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/AuthResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Persistence.Models +{ + public class AuthResponse + { + public string Id { get; set; } + public string UserName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Token { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/Blogger.cs b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/Blogger.cs new file mode 100644 index 000000000..e725e502b --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/Blogger.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Persistence.Models +{ + public class Blogger + { + public string Id { get; set; } + public string AppUserId { get; set; } + public string UserName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public IList Roles { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/JwtSettings.cs b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/JwtSettings.cs new file mode 100644 index 000000000..8ebffc32c --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/JwtSettings.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Persistence.Models +{ + public class JwtSettings + { + public string Key { get; set; } + public string Issuer { get; set; } + public string Audience { get; set; } + public double DurationInMinutes { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/RegistrationRequest.cs b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/RegistrationRequest.cs new file mode 100644 index 000000000..bd38d61e7 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/RegistrationRequest.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Persistence.Models +{ + public class RegistrationRequest + { + [Required] + public string UserName { get; set; } + [Required] + public string FirstName { get; set; } + [Required] + public string LastName { get; set; } + + [Required] + [EmailAddress] + public string Email { get; set; } + + [Required] + [MinLength(6)] + public string Password { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/RegistrationResponse.cs b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/RegistrationResponse.cs new file mode 100644 index 000000000..d683d00a0 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Models/RegistrationResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CineFlex.Persistence.Models +{ + public class RegistrationResponse + { + public string UserId { get; set; } + public int postUserId { get; set; } + } +} diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/PersistenceServicesRegistration.cs b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/PersistenceServicesRegistration.cs index b2fba9a20..0845e0675 100644 --- a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/PersistenceServicesRegistration.cs +++ b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/PersistenceServicesRegistration.cs @@ -19,6 +19,7 @@ public static IServiceCollection ConfigurePersistenceServices(this IServiceColle opt.UseNpgsql(configuration.GetConnectionString("CineFlexConnectionString"))); services.AddScoped(); services.AddScoped(); + services.AddScoped(); return services; } } diff --git a/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Repositories/PostRepository.cs b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Repositories/PostRepository.cs new file mode 100644 index 000000000..e68ae2297 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/CineFlex.Persistence/Repositories/PostRepository.cs @@ -0,0 +1,19 @@ +using CineFlex.Application.Contracts.Persistence; +using CineFlex.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CineFlex.Persistence; + +namespace CineFlex.Persistence.Repositories +{ + public class PostRepository : GenericRepository, IPostRepository + { + public PostRepository(CineFlexDbContext dbContex) : base(dbContex) + { + + } + } +} diff --git a/Backend/backend_assessment/CineFlex/MockPostRepository.cs b/Backend/backend_assessment/CineFlex/MockPostRepository.cs new file mode 100644 index 000000000..d555ecb07 --- /dev/null +++ b/Backend/backend_assessment/CineFlex/MockPostRepository.cs @@ -0,0 +1,8 @@ +using System; + +public class Class1 +{ + public Class1() + { + } +}