diff --git a/TickAPI/TickAPI.Tests/Categories/Controllers/CategoryControllerTests.cs b/TickAPI/TickAPI.Tests/Categories/Controllers/CategoryControllerTests.cs new file mode 100644 index 0000000..fdce5df --- /dev/null +++ b/TickAPI/TickAPI.Tests/Categories/Controllers/CategoryControllerTests.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Mvc; +using Moq; +using TickAPI.Categories.Abstractions; +using TickAPI.Categories.Controllers; +using TickAPI.Categories.DTOs.Response; +using TickAPI.Common.Pagination.Responses; +using TickAPI.Common.Results; +using TickAPI.Common.Results.Generic; +using TickAPI.Events.DTOs.Response; + +namespace TickAPI.Tests.Categories.Controllers; + +public class CategoryControllerTests +{ + [Fact] + + public async Task GetCategories_WhenDataIsValid_ShouldReturnOk() + { + //arrange + int pageSize = 20; + int pageNumber = 0; + var categoryServiceMock = new Mock(); + categoryServiceMock.Setup(m => m.GetCategoriesResponsesAsync(pageSize, pageNumber)).ReturnsAsync( + Result>.Success(new PaginatedData(new List(), pageNumber, pageSize, true, true, + new PaginationDetails(0, 0)))); + + var sut = new CategoryController(categoryServiceMock.Object); + + //act + var res = await sut.GetCategories(pageSize, pageNumber); + + //assert + var result = Assert.IsType>>(res); + var objectResult = Assert.IsType(result.Result); + Assert.Equal(200, objectResult.StatusCode); + Assert.NotNull(objectResult.Value); + } + +} \ No newline at end of file diff --git a/TickAPI/TickAPI.Tests/Categories/Services/CategoryServiceTests.cs b/TickAPI/TickAPI.Tests/Categories/Services/CategoryServiceTests.cs new file mode 100644 index 0000000..0b43f6d --- /dev/null +++ b/TickAPI/TickAPI.Tests/Categories/Services/CategoryServiceTests.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Mvc; +using Moq; +using TickAPI.Categories.Abstractions; +using TickAPI.Categories.DTOs.Response; +using TickAPI.Categories.Models; +using TickAPI.Categories.Services; +using TickAPI.Common.Pagination.Abstractions; +using TickAPI.Common.Pagination.Responses; +using TickAPI.Common.Results; +using TickAPI.Common.Results.Generic; + +namespace TickAPI.Tests.Categories.Services; + +public class CategoryServiceTests +{ + [Fact] + + public async Task GetCategories_WhenDataIsValid_ShouldReturnOk() + { + //arrange + int pageSize = 10; + int page = 0; + var categoryRepositoryMock = new Mock(); + categoryRepositoryMock.Setup(repo => repo.GetCategoriesAsync()) + .ReturnsAsync(new List()); + + var paginationServiceMock = new Mock(); + paginationServiceMock.Setup(p => p.Paginate(new List(), pageSize, page)).Returns( + Result>.Success(new PaginatedData(new List(), page, pageSize, + false, false, new PaginationDetails(0, 0))) + ); + + var sut = new CategoryService(categoryRepositoryMock.Object, paginationServiceMock.Object); + + //act + var res = await sut.GetCategoriesResponsesAsync(pageSize, page); + + //assert + var result = Assert.IsType>>(res); + Assert.True(result.IsSuccess); + } +} \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs b/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs new file mode 100644 index 0000000..5b6254f --- /dev/null +++ b/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs @@ -0,0 +1,9 @@ +using TickAPI.Categories.Models; +using TickAPI.Common.Results.Generic; + +namespace TickAPI.Categories.Abstractions; + +public interface ICategoryRepository +{ + public Task> GetCategoriesAsync(); +} \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/Abstractions/ICategoryService.cs b/TickAPI/TickAPI/Categories/Abstractions/ICategoryService.cs new file mode 100644 index 0000000..37e0f24 --- /dev/null +++ b/TickAPI/TickAPI/Categories/Abstractions/ICategoryService.cs @@ -0,0 +1,11 @@ +using TickAPI.Categories.DTOs.Response; +using TickAPI.Categories.Models; +using TickAPI.Common.Pagination.Responses; +using TickAPI.Common.Results.Generic; + +namespace TickAPI.Categories.Abstractions; + +public interface ICategoryService +{ + public Task>> GetCategoriesResponsesAsync(int pageSize, int page); +} \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/Controllers/CategoryController.cs b/TickAPI/TickAPI/Categories/Controllers/CategoryController.cs new file mode 100644 index 0000000..20f4d94 --- /dev/null +++ b/TickAPI/TickAPI/Categories/Controllers/CategoryController.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Mvc; +using TickAPI.Categories.Abstractions; +using TickAPI.Categories.DTOs.Response; +using TickAPI.Common.Auth.Attributes; +using TickAPI.Common.Auth.Enums; +using TickAPI.Common.Pagination.Responses; + + +namespace TickAPI.Categories.Controllers; + +[ApiController] +[Route("api/[controller]")] + +public class CategoryController : Controller +{ + + private readonly ICategoryService _categoryService; + + public CategoryController(ICategoryService categoryService) + { + _categoryService = categoryService; + } + + [AuthorizeWithPolicy(AuthPolicies.VerifiedUserPolicy)] + [HttpPost("get-categories")] + public async Task>> GetCategories([FromQuery] int pageSize, [FromQuery] int page) + { + var res = await _categoryService.GetCategoriesResponsesAsync(pageSize, page); + if (!res.IsSuccess) + { + return StatusCode(StatusCodes.Status500InternalServerError, res.ErrorMsg); + } + return Ok(res.Value); + } +} \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/DTOs/Response/GetCategoryResponseDto.cs b/TickAPI/TickAPI/Categories/DTOs/Response/GetCategoryResponseDto.cs new file mode 100644 index 0000000..9ece0df --- /dev/null +++ b/TickAPI/TickAPI/Categories/DTOs/Response/GetCategoryResponseDto.cs @@ -0,0 +1,7 @@ +using TickAPI.Common.Pagination.Responses; + +namespace TickAPI.Categories.DTOs.Response; + +public record GetCategoryResponseDto( + string CategoryName +); \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs b/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs new file mode 100644 index 0000000..9cba1d3 --- /dev/null +++ b/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore; +using TickAPI.Categories.Abstractions; +using TickAPI.Categories.Models; +using TickAPI.Common.Results.Generic; +using TickAPI.Common.TickApiDbContext; +namespace TickAPI.Categories.Respositories; + +public class CategoryRepository : ICategoryRepository +{ + private readonly TickApiDbContext _tickApiDbContext; + + public CategoryRepository(TickApiDbContext tickApiDbContext) + { + _tickApiDbContext = tickApiDbContext; + } + + public async Task> GetCategoriesAsync() + { + var list = await _tickApiDbContext.Categories.ToListAsync(); + return list; + } +} \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/Services/CategoryService.cs b/TickAPI/TickAPI/Categories/Services/CategoryService.cs new file mode 100644 index 0000000..dbbfcd8 --- /dev/null +++ b/TickAPI/TickAPI/Categories/Services/CategoryService.cs @@ -0,0 +1,40 @@ +using TickAPI.Categories.Abstractions; +using TickAPI.Categories.DTOs.Response; +using TickAPI.Categories.Models; +using TickAPI.Common.Pagination.Abstractions; +using TickAPI.Common.Pagination.Responses; +using TickAPI.Common.Results.Generic; + +namespace TickAPI.Categories.Services; + +public class CategoryService : ICategoryService +{ + private readonly ICategoryRepository _categoryRepository; + private readonly IPaginationService _paginationService; + + public CategoryService(ICategoryRepository categoryRepository, IPaginationService paginationService) + { + _categoryRepository = categoryRepository; + _paginationService = paginationService; + } + + public async Task>> GetCategoriesResponsesAsync(int pageSize, int page) + { + var categoriesAllResponse = await _categoryRepository.GetCategoriesAsync(); + List categories = new List(); + var categoriesPaginated = _paginationService.Paginate(categoriesAllResponse, pageSize, page); + if (!categoriesPaginated.IsSuccess) + { + return Result>.PropagateError(categoriesPaginated); + } + + foreach (var category in categoriesPaginated.Value.Data) + { + categories.Add(new GetCategoryResponseDto(category.CategoryName)); + } + + return Result>.Success(new PaginatedData(categories, categoriesPaginated.Value.PageNumber + ,categoriesPaginated.Value.PageSize, categoriesPaginated.Value.HasNextPage, categoriesPaginated.Value.HasPreviousPage, + categoriesPaginated.Value.PaginationDetails)); + } +} \ No newline at end of file diff --git a/TickAPI/TickAPI/Common/Auth/Enums/AuthPolicies.cs b/TickAPI/TickAPI/Common/Auth/Enums/AuthPolicies.cs index 33bf3d0..5c9f52a 100644 --- a/TickAPI/TickAPI/Common/Auth/Enums/AuthPolicies.cs +++ b/TickAPI/TickAPI/Common/Auth/Enums/AuthPolicies.cs @@ -7,4 +7,5 @@ public enum AuthPolicies CustomerPolicy, NewOrganizerPolicy, CreatedOrganizerPolicy, + VerifiedUserPolicy, } \ No newline at end of file diff --git a/TickAPI/TickAPI/Program.cs b/TickAPI/TickAPI/Program.cs index 0c56ab6..08779cd 100644 --- a/TickAPI/TickAPI/Program.cs +++ b/TickAPI/TickAPI/Program.cs @@ -30,6 +30,9 @@ using TickAPI.Addresses.Abstractions; using TickAPI.Addresses.Repositories; using TickAPI.Addresses.Services; +using TickAPI.Categories.Abstractions; +using TickAPI.Categories.Respositories; +using TickAPI.Categories.Services; using TickAPI.Common.Claims.Abstractions; using TickAPI.Common.Claims.Services; @@ -75,6 +78,7 @@ options.AddPolicy(AuthPolicies.NewOrganizerPolicy.ToString(), policy => policy.RequireRole(UserRole.NewOrganizer.ToString())); options.AddPolicy(AuthPolicies.CreatedOrganizerPolicy.ToString(), policy => policy.RequireRole(UserRole.UnverifiedOrganizer.ToString(), UserRole.Organizer.ToString())); + options.AddPolicy(AuthPolicies.VerifiedUserPolicy.ToString(), policy => policy.RequireRole(UserRole.Admin.ToString(), UserRole.Organizer.ToString(), UserRole.Customer.ToString())); }); // Add admin services. @@ -101,6 +105,10 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); +// Add category services. +builder.Services.AddScoped(); +builder.Services.AddScoped(); + // Add common services. builder.Services.AddScoped(); builder.Services.AddScoped();