From 2f859d0bee86c59c767f338087b01b1983d53b1a Mon Sep 17 00:00:00 2001 From: Lankiman Date: Fri, 28 Feb 2025 20:25:46 +0100 Subject: [PATCH 01/15] feat(admin):major - add endpoints to retrieve user-owned and affiliated organizations - Added endpoint to get organizations owned by a user - Added endpoint to get organizations a user belongs to - Implemented query handlers for fetching organizations based on user ID - Integrated MediatR for handling queries efficiently - Improved response structure for paginated organization data --- .../SuperAdmin/Dto/OrganizationDto.cs | 31 +++++++++++ ...MemberOrganizationsByUserIdQueryHandler.cs | 49 +++++++++++++++++ ...sOwnedOrganizationsByUserIdQueryHandler.cs | 51 ++++++++++++++++++ .../Mappers/AdminUsersMappingProfile.cs | 1 + ...GetUsersMemberOrganizationByUserIdQuery.cs | 18 +++++++ ...GetUsersOwnedOrganizationsByUserIdQuery.cs | 18 +++++++ .../Repository/Interface/IRepository.cs | 2 + .../Repository/Repository.cs | 13 +++++ src/Hng.Web/Controllers/AdminController.cs | 52 +++++++++++++++++++ 9 files changed, 235 insertions(+) create mode 100644 src/Hng.Application/Features/SuperAdmin/Dto/OrganizationDto.cs create mode 100644 src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs create mode 100644 src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs create mode 100644 src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs create mode 100644 src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs diff --git a/src/Hng.Application/Features/SuperAdmin/Dto/OrganizationDto.cs b/src/Hng.Application/Features/SuperAdmin/Dto/OrganizationDto.cs new file mode 100644 index 00000000..56544d37 --- /dev/null +++ b/src/Hng.Application/Features/SuperAdmin/Dto/OrganizationDto.cs @@ -0,0 +1,31 @@ +using System.Text.Json.Serialization; + +namespace Hng.Application.Features.SuperAdmin.Dto; + +public class OrganizationDto +{ + + [JsonPropertyName("name")] public string Name { get; set; } + + [JsonPropertyName("description")] public string Description { get; set; } + + [JsonPropertyName("slug")] public string Slug { get; set; } + + [JsonPropertyName("email")] public string Email { get; set; } + + [JsonPropertyName("industry")] public string Industry { get; set; } + + [JsonPropertyName("type")] public string Type { get; set; } + + [JsonPropertyName("country")] public string Country { get; set; } + + [JsonPropertyName("address")] public string Address { get; set; } + + [JsonPropertyName("state")] public string State { get; set; } + + [JsonPropertyName("is_active")] public bool IsActive { get; set; } + + [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } + +} + diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs new file mode 100644 index 00000000..e8beb2b4 --- /dev/null +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs @@ -0,0 +1,49 @@ +using AutoMapper; +using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Application.Features.SuperAdmin.Queries; +using Hng.Application.Shared.Dtos; +using Hng.Domain.Entities; +using Hng.Infrastructure.Repository.Interface; +using Hng.Infrastructure.Services.Interfaces; +using MediatR; + +namespace Hng.Application.Features.SuperAdmin.Handlers; + +public class GetUsersMemberOrganizationsByUserIdQueryHandler :IRequestHandler> +{ + private readonly IRepository _userRepository; + private readonly IRepository _organizationRepository; + private readonly IMapper _mapper; + private readonly IAuthenticationService _authenticationService; + + + public GetUsersMemberOrganizationsByUserIdQueryHandler(IRepository userRepository, + IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) + { + _userRepository = userRepository; + _organizationRepository = organizationRepository; + _mapper = mapper; + _authenticationService = authenticationService; + } + + + public async Task> Handle(GetUsersMemberOrganizationsByUserIdQuery request, CancellationToken cancellationToken) + { + var user =await _userRepository.GetBySpec(user => user.Id == request.UserId, user=>user.Organizations); + + if (user==null) + { + return null; + } + var userMemberOrganizations = user.Organizations.Where(org=>org.OwnerId!=user.Id).ToList(); + + + var mappedOrganizations = _mapper.Map>(userMemberOrganizations); + + // var mappedProducts = _mapper.Map>(products); + + var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, + request.UserMemberOrganizationsQueryParameter.Offset, request.UserMemberOrganizationsQueryParameter.Limit); + return organizationResult ; + } +} \ No newline at end of file diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs new file mode 100644 index 00000000..5a4faae4 --- /dev/null +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs @@ -0,0 +1,51 @@ +using AutoMapper; +using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Application.Features.SuperAdmin.Queries; +using Hng.Application.Shared.Dtos; +using Hng.Domain.Entities; +using Hng.Infrastructure.Repository.Interface; +using Hng.Infrastructure.Services.Interfaces; +using MediatR; + +namespace Hng.Application.Features.SuperAdmin.Handlers; + +public class GetUsersOwnedOrganizationsByUserIdQueryHandler:IRequestHandler> +{ + private readonly IRepository _userRepository; + private readonly IRepository _organizationRepository; + private readonly IMapper _mapper; + private readonly IAuthenticationService _authenticationService; + + public GetUsersOwnedOrganizationsByUserIdQueryHandler(IRepository userRepository, + IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) + { + _userRepository = userRepository; + _organizationRepository = organizationRepository; + _mapper = mapper; + _authenticationService = authenticationService; + } + + + public async Task> Handle( GetUsersOwnedOrganizationsByUserIdQuery request, CancellationToken cancellationToken) + { + var user =await _userRepository.GetBySpec(user => user.Id == request.UserId, user=>user.Organizations); + + Console.WriteLine(user.FirstName); + if (user==null) + { + return null; + } + var userOwnedOrganizations = user.Organizations.Where(org=>org.OwnerId==user.Id).ToList(); + + + var mappedOrganizations = _mapper.Map>(userOwnedOrganizations); + + // var mappedProducts = _mapper.Map>(products); + + var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, + request.UserOwnedOrganizationsQueryParameter.Offset, request.UserOwnedOrganizationsQueryParameter.Limit); + return organizationResult ; + } + +} + \ No newline at end of file diff --git a/src/Hng.Application/Features/SuperAdmin/Mappers/AdminUsersMappingProfile.cs b/src/Hng.Application/Features/SuperAdmin/Mappers/AdminUsersMappingProfile.cs index 5d0cbdaf..c24b2db9 100644 --- a/src/Hng.Application/Features/SuperAdmin/Mappers/AdminUsersMappingProfile.cs +++ b/src/Hng.Application/Features/SuperAdmin/Mappers/AdminUsersMappingProfile.cs @@ -8,6 +8,7 @@ public class AdminUsersMappingProfile : AutoMapper.Profile public AdminUsersMappingProfile() { CreateMap().ReverseMap(); + CreateMap().ReverseMap(); } } } diff --git a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs new file mode 100644 index 00000000..f1c56692 --- /dev/null +++ b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs @@ -0,0 +1,18 @@ +using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Application.Shared.Dtos; +using MediatR; + +namespace Hng.Application.Features.SuperAdmin.Queries; + +public class GetUsersMemberOrganizationsByUserIdQuery: IRequest> +{ + public GetUsersMemberOrganizationsByUserIdQuery(Guid userId, + BaseQueryParameters userMemberOrganizationsQueryParameter) + { + UserId = userId; + UserMemberOrganizationsQueryParameter = userMemberOrganizationsQueryParameter; + } + + public Guid UserId { get; set; } + public BaseQueryParameters UserMemberOrganizationsQueryParameter { get; set; } +} diff --git a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs new file mode 100644 index 00000000..bd388375 --- /dev/null +++ b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs @@ -0,0 +1,18 @@ +using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Application.Shared.Dtos; +using MediatR; + +namespace Hng.Application.Features.SuperAdmin.Queries; + +public class GetUsersOwnedOrganizationsByUserIdQuery : IRequest> +{ + public GetUsersOwnedOrganizationsByUserIdQuery(Guid userId, + BaseQueryParameters userOwnedOrganizationsQueryParameter) + { + UserId = userId; + UserOwnedOrganizationsQueryParameter = userOwnedOrganizationsQueryParameter; + } + + public Guid UserId { get; set; } + public BaseQueryParameters UserOwnedOrganizationsQueryParameter { get; set; } +} \ No newline at end of file diff --git a/src/Hng.Infrastructure/Repository/Interface/IRepository.cs b/src/Hng.Infrastructure/Repository/Interface/IRepository.cs index 0b68ad59..3da6b93f 100644 --- a/src/Hng.Infrastructure/Repository/Interface/IRepository.cs +++ b/src/Hng.Infrastructure/Repository/Interface/IRepository.cs @@ -8,6 +8,8 @@ public interface IRepository where T : EntityBase Task GetAsync(Guid id); Task GetBySpec(Expression> predicate, params Expression>[] includeProperties); Task> GetAllAsync(params Expression>[] includeProperties); + + IQueryable GetAllAsQueryable(params Expression>[] includeProperties); Task> GetAllBySpec(Expression> predicate, params Expression>[] includeProperties); IQueryable GetQueryableBySpec(Expression> predicate); diff --git a/src/Hng.Infrastructure/Repository/Repository.cs b/src/Hng.Infrastructure/Repository/Repository.cs index 03610ec1..976b7918 100644 --- a/src/Hng.Infrastructure/Repository/Repository.cs +++ b/src/Hng.Infrastructure/Repository/Repository.cs @@ -90,6 +90,19 @@ public IQueryable GetQueryableBySpec(Expression> predicate) { return _context.Set().AsNoTracking().Where(predicate); } + + public IQueryable GetAllAsQueryable(params Expression>[] includeProperties) + { + IQueryable query = _context.Set(); + + foreach (var includeProperty in includeProperties) + { + query = query.Include(includeProperty); + } + + return query; + } + public async Task GetBySpec(Expression> predicate, params Expression>[] includeProperties) { var entities = _context.Set().Where(predicate).AsNoTracking(); diff --git a/src/Hng.Web/Controllers/AdminController.cs b/src/Hng.Web/Controllers/AdminController.cs index 163c5d6b..c4435dde 100644 --- a/src/Hng.Web/Controllers/AdminController.cs +++ b/src/Hng.Web/Controllers/AdminController.cs @@ -29,5 +29,57 @@ public async Task GetUsersBySearch([FromQuery] UsersQueryParameter var users = await _mediator.Send(new GetUsersBySearchQuery(parameters)); return Ok(new PaginatedResponseDto> { Data = users, Metadata = users.MetaData }); } + + /// + /// Admin: Users - gets all organizations owned by a user by the user's id + /// + /// + [HttpGet("users/{id}/organizations/owned")] + [Authorize] + [ProducesResponseType(typeof(SuccessResponseDto>>), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(FailureResponseDto), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(StatusCodeResponse), StatusCodes.Status404NotFound)] + public async Task GetUserOwnedOrganizationsByUserId([FromRoute] Guid id, [FromQuery] BaseQueryParameters parameters) + { + if (!Guid.TryParse(id.ToString(), out _)) + { + return BadRequest( new FailureResponseDto{Message = "Valid user ID must be Provided"}); + } + var userOrganizations = await _mediator.Send(new GetUsersOwnedOrganizationsByUserIdQuery(id,parameters)); + + if (userOrganizations == null) + { + return NotFound(new StatusCodeResponse + { Message = "User not found", StatusCode = StatusCodes.Status404NotFound }); + } + + return Ok(new PaginatedResponseDto> { Data =userOrganizations , Metadata = userOrganizations.MetaData }); + } + + /// + /// Admin: Users - gets all organizations a user belongs by the user's id + /// + /// + [HttpGet("users/{id}/organizations/member")] + [Authorize] + [ProducesResponseType(typeof(SuccessResponseDto>>), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(FailureResponseDto), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(StatusCodeResponse), StatusCodes.Status404NotFound)] + public async Task GetUserMemberOrganizationsByUserId([FromRoute] Guid id, [FromQuery] BaseQueryParameters parameters) + { + if (!Guid.TryParse(id.ToString(), out _)) + { + return BadRequest( new FailureResponseDto{Message = "Valid user ID must be Provided"}); + } + var userOrganizations = await _mediator.Send(new GetUsersMemberOrganizationsByUserIdQuery(id,parameters)); + + if (userOrganizations == null) + { + return NotFound(new StatusCodeResponse + { Message = "User not found", StatusCode = StatusCodes.Status404NotFound }); + } + + return Ok(new PaginatedResponseDto> { Data =userOrganizations , Metadata = userOrganizations.MetaData }); + } } } From 12b8823344655f4396ff131f753e516afcc38f07 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Fri, 28 Feb 2025 21:27:34 +0100 Subject: [PATCH 02/15] chore: removed secret keys from appsettings --- ...rOrgnazationsByUserIdQueryHandlerShould.cs | 28 +++++++++++++++++++ ...OrganizationsByUserIdQueryHandlerShould.cs | 27 ++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs create mode 100644 src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs new file mode 100644 index 00000000..25b4ae88 --- /dev/null +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs @@ -0,0 +1,28 @@ + + + +using AutoMapper; +using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Domain.Entities; +using Hng.Infrastructure.Repository.Interface; +using Moq; + +public class GetUsersMemberOrganizationsByUserIdQueryHandlerShould +{ + private readonly Mock> _mockRepository; + private readonly IMapper _mapper; + public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() + { + _mockRepository = new Mock>(); + + // Set up AutoMapper with your profiles + var config = new MapperConfiguration(cfg => + { + // Add your AutoMapper profiles here + cfg.CreateMap(); + cfg.CreateMap(); + }); + + _mapper = config.CreateMapper(); + } +} \ No newline at end of file diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs new file mode 100644 index 00000000..2dbcdb7f --- /dev/null +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -0,0 +1,27 @@ +using AutoMapper; +using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Domain.Entities; +using Hng.Infrastructure.Repository.Interface; +using Moq; + +namespace Hng.Application.Test.Features.SuperAdmin; + +public class GetUsersOwnedOrganizationsByUserIdQueryHandlerShould +{ + private readonly Mock> _mockRepository; + private readonly IMapper _mapper; + public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() + { + _mockRepository = new Mock>(); + + // Set up AutoMapper with your profiles + var config = new MapperConfiguration(cfg => + { + // Add your AutoMapper profiles here + cfg.CreateMap(); + cfg.CreateMap(); + }); + + _mapper = config.CreateMapper(); + } +} \ No newline at end of file From 425e2fdc95d2b6ae283d124a73d7c32dc075f3ac Mon Sep 17 00:00:00 2001 From: Lankiman Date: Fri, 28 Feb 2025 22:15:55 +0100 Subject: [PATCH 03/15] chore:implmented test for get user owned organizations and organizations a user belongs to query handlers --- ...rOrgnazationsByUserIdQueryHandlerShould.cs | 22 +++++++++++++++ ...OrganizationsByUserIdQueryHandlerShould.cs | 28 +++++++++++++++++-- ...GetUsersOwnedOrganizationsByUserIdQuery.cs | 2 +- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs index 25b4ae88..90cbc76e 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs @@ -1,16 +1,24 @@ +using System.Linq.Expressions; using AutoMapper; using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Application.Features.SuperAdmin.Handlers; +using Hng.Application.Features.SuperAdmin.Queries; +using Hng.Application.Shared.Dtos; using Hng.Domain.Entities; using Hng.Infrastructure.Repository.Interface; using Moq; +using Xunit; public class GetUsersMemberOrganizationsByUserIdQueryHandlerShould { private readonly Mock> _mockRepository; private readonly IMapper _mapper; + private readonly Mock> mockOrganizationRepository; + private readonly IMapper mapper; + private readonly GetUsersMemberOrganizationsByUserIdQueryHandler handler; public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); @@ -25,4 +33,18 @@ public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() _mapper = config.CreateMapper(); } + + + [Fact] + public async Task ReturnNullWhenUserIsNotFound() + { + _mockRepository.Setup(repo => repo.GetBySpec( + It.IsAny>>(), + It.IsAny>[]>() + )).ReturnsAsync((User)null); + + var result = await handler.Handle(new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(),new BaseQueryParameters()), CancellationToken.None); + + Assert.Null(result); + } } \ No newline at end of file diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs index 2dbcdb7f..af33b0d2 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -1,8 +1,13 @@ +using System.Linq.Expressions; using AutoMapper; using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Application.Features.SuperAdmin.Handlers; +using Hng.Application.Features.SuperAdmin.Queries; +using Hng.Application.Shared.Dtos; using Hng.Domain.Entities; using Hng.Infrastructure.Repository.Interface; using Moq; +using Xunit; namespace Hng.Application.Test.Features.SuperAdmin; @@ -10,18 +15,35 @@ public class GetUsersOwnedOrganizationsByUserIdQueryHandlerShould { private readonly Mock> _mockRepository; private readonly IMapper _mapper; + private readonly Mock> mockOrganizationRepository; + private readonly IMapper mapper; + private readonly GetUsersOwnedOrganizationsByUserIdQueryHandler handler; public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); + mockOrganizationRepository = new Mock>(); - // Set up AutoMapper with your profiles + var config = new MapperConfiguration(cfg => { - // Add your AutoMapper profiles here + cfg.CreateMap(); cfg.CreateMap(); }); - _mapper = config.CreateMapper(); } + + + [Fact] + public async Task ReturnNullWhenUserIsNotFound() + { + _mockRepository.Setup(repo => repo.GetBySpec( + It.IsAny>>(), + It.IsAny>[]>() + )).ReturnsAsync((User)null); + + var result = await handler.Handle(new GetUsersOwnedOrganizationsByUserIdQuery(Guid.NewGuid(),new BaseQueryParameters()), CancellationToken.None); + + Assert.Null(result); + } } \ No newline at end of file diff --git a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs index bd388375..72cf29ba 100644 --- a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs +++ b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs @@ -12,7 +12,7 @@ public GetUsersOwnedOrganizationsByUserIdQuery(Guid userId, UserId = userId; UserOwnedOrganizationsQueryParameter = userOwnedOrganizationsQueryParameter; } - + public Guid UserId { get; set; } public BaseQueryParameters UserOwnedOrganizationsQueryParameter { get; set; } } \ No newline at end of file From 1c4ee4328ac403153ff3dfc6802fa874cde180c3 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Fri, 28 Feb 2025 23:37:51 +0100 Subject: [PATCH 04/15] (fix)-minor - fixed white spaceformating issue for files specified by ci --- ...sersMemberOrganizationsByUserIdQueryHandler.cs | 10 +++------- ...UsersOwnedOrganizationsByUserIdQueryHandler.cs | 15 ++++----------- .../GetUsersMemberOrganizationByUserIdQuery.cs | 6 ++---- .../GetUsersOwnedOrganizationsByUserIdQuery.cs | 4 +--- 4 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs index e8beb2b4..85e8c756 100644 --- a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs @@ -15,8 +15,6 @@ public class GetUsersMemberOrganizationsByUserIdQueryHandler :IRequestHandler _organizationRepository; private readonly IMapper _mapper; private readonly IAuthenticationService _authenticationService; - - public GetUsersMemberOrganizationsByUserIdQueryHandler(IRepository userRepository, IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) { @@ -26,7 +24,6 @@ public GetUsersMemberOrganizationsByUserIdQueryHandler(IRepository userRep _authenticationService = authenticationService; } - public async Task> Handle(GetUsersMemberOrganizationsByUserIdQuery request, CancellationToken cancellationToken) { var user =await _userRepository.GetBySpec(user => user.Id == request.UserId, user=>user.Organizations); @@ -37,13 +34,12 @@ public async Task> Handle(GetUsersMemberOrganizati } var userMemberOrganizations = user.Organizations.Where(org=>org.OwnerId!=user.Id).ToList(); - var mappedOrganizations = _mapper.Map>(userMemberOrganizations); - + // var mappedProducts = _mapper.Map>(products); - var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, - request.UserMemberOrganizationsQueryParameter.Offset, request.UserMemberOrganizationsQueryParameter.Limit); + var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserMemberOrganizationsQueryParameter.Offset, request.UserMemberOrganizationsQueryParameter.Limit); + return organizationResult ; } } \ No newline at end of file diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs index 5a4faae4..54a21dcf 100644 --- a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs @@ -15,7 +15,6 @@ public class GetUsersOwnedOrganizationsByUserIdQueryHandler:IRequestHandler _organizationRepository; private readonly IMapper _mapper; private readonly IAuthenticationService _authenticationService; - public GetUsersOwnedOrganizationsByUserIdQueryHandler(IRepository userRepository, IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) { @@ -25,27 +24,21 @@ public GetUsersOwnedOrganizationsByUserIdQueryHandler(IRepository userRepo _authenticationService = authenticationService; } - public async Task> Handle( GetUsersOwnedOrganizationsByUserIdQuery request, CancellationToken cancellationToken) { var user =await _userRepository.GetBySpec(user => user.Id == request.UserId, user=>user.Organizations); - Console.WriteLine(user.FirstName); if (user==null) { return null; } var userOwnedOrganizations = user.Organizations.Where(org=>org.OwnerId==user.Id).ToList(); - var mappedOrganizations = _mapper.Map>(userOwnedOrganizations); - - // var mappedProducts = _mapper.Map>(products); - - var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, - request.UserOwnedOrganizationsQueryParameter.Offset, request.UserOwnedOrganizationsQueryParameter.Limit); + + var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserOwnedOrganizationsQueryParameter.Offset, request.UserOwnedOrganizationsQueryParameter.Limit); + return organizationResult ; } -} - \ No newline at end of file +} \ No newline at end of file diff --git a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs index f1c56692..fa738fb6 100644 --- a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs +++ b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs @@ -6,13 +6,11 @@ namespace Hng.Application.Features.SuperAdmin.Queries; public class GetUsersMemberOrganizationsByUserIdQuery: IRequest> { - public GetUsersMemberOrganizationsByUserIdQuery(Guid userId, - BaseQueryParameters userMemberOrganizationsQueryParameter) + public GetUsersMemberOrganizationsByUserIdQuery(Guid userId, BaseQueryParameters userMemberOrganizationsQueryParameter) { UserId = userId; UserMemberOrganizationsQueryParameter = userMemberOrganizationsQueryParameter; } - public Guid UserId { get; set; } public BaseQueryParameters UserMemberOrganizationsQueryParameter { get; set; } -} +} \ No newline at end of file diff --git a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs index 72cf29ba..87f0253c 100644 --- a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs +++ b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersOwnedOrganizationsByUserIdQuery.cs @@ -6,13 +6,11 @@ namespace Hng.Application.Features.SuperAdmin.Queries; public class GetUsersOwnedOrganizationsByUserIdQuery : IRequest> { - public GetUsersOwnedOrganizationsByUserIdQuery(Guid userId, - BaseQueryParameters userOwnedOrganizationsQueryParameter) + public GetUsersOwnedOrganizationsByUserIdQuery(Guid userId, BaseQueryParameters userOwnedOrganizationsQueryParameter) { UserId = userId; UserOwnedOrganizationsQueryParameter = userOwnedOrganizationsQueryParameter; } - public Guid UserId { get; set; } public BaseQueryParameters UserOwnedOrganizationsQueryParameter { get; set; } } \ No newline at end of file From a03bf53b8704a181af3e4956486dce5e9d059db5 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Fri, 28 Feb 2025 23:38:57 +0100 Subject: [PATCH 05/15] (fix)-minor - fixed white spaceformating issue for files specified by ci --- .../GetUsersBySearchQueryHandlerShould.cs | 1 - ...emberOrgnazationsByUserIdQueryHandlerShould.cs | 13 +++---------- ...wnedOrganizationsByUserIdQueryHandlerShould.cs | 14 +++++--------- .../Repository/Interface/IRepository.cs | 3 --- src/Hng.Infrastructure/Repository/Repository.cs | 15 +-------------- 5 files changed, 9 insertions(+), 37 deletions(-) diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersBySearchQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersBySearchQueryHandlerShould.cs index ce50ed3f..1dec3d53 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersBySearchQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersBySearchQueryHandlerShould.cs @@ -156,6 +156,5 @@ public async Task ReturnUsersOnValidLastNameParameters() Assert.Equal(results.First().LastName, expectedLastName); } - } } diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs index 90cbc76e..d76680ba 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs @@ -1,6 +1,3 @@ - - - using System.Linq.Expressions; using AutoMapper; using Hng.Application.Features.SuperAdmin.Dto; @@ -22,7 +19,7 @@ public class GetUsersMemberOrganizationsByUserIdQueryHandlerShould public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); - + // Set up AutoMapper with your profiles var config = new MapperConfiguration(cfg => { @@ -34,17 +31,13 @@ public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() _mapper = config.CreateMapper(); } - [Fact] public async Task ReturnNullWhenUserIsNotFound() { - _mockRepository.Setup(repo => repo.GetBySpec( - It.IsAny>>(), - It.IsAny>[]>() - )).ReturnsAsync((User)null); + _mockRepository.Setup(repo => repo.GetBySpec(It.IsAny>>(), It.IsAny>[]>())).ReturnsAsync((User)null); var result = await handler.Handle(new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(),new BaseQueryParameters()), CancellationToken.None); - + Assert.Null(result); } } \ No newline at end of file diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs index af33b0d2..d46b108f 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -18,31 +18,27 @@ public class GetUsersOwnedOrganizationsByUserIdQueryHandlerShould private readonly Mock> mockOrganizationRepository; private readonly IMapper mapper; private readonly GetUsersOwnedOrganizationsByUserIdQueryHandler handler; + public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); mockOrganizationRepository = new Mock>(); - var config = new MapperConfiguration(cfg => { - + cfg.CreateMap(); cfg.CreateMap(); }); _mapper = config.CreateMapper(); } - - + [Fact] public async Task ReturnNullWhenUserIsNotFound() { - _mockRepository.Setup(repo => repo.GetBySpec( - It.IsAny>>(), - It.IsAny>[]>() - )).ReturnsAsync((User)null); + _mockRepository.Setup(repo => repo.GetBySpec(It.IsAny>>(),It.IsAny>[]>())).ReturnsAsync((User)null); - var result = await handler.Handle(new GetUsersOwnedOrganizationsByUserIdQuery(Guid.NewGuid(),new BaseQueryParameters()), CancellationToken.None); + var result= await handler.Handle(new GetUsersOwnedOrganizationsByUserIdQuery(Guid.NewGuid(),new BaseQueryParameters()), CancellationToken.None); Assert.Null(result); } diff --git a/src/Hng.Infrastructure/Repository/Interface/IRepository.cs b/src/Hng.Infrastructure/Repository/Interface/IRepository.cs index 3da6b93f..5dfe09c3 100644 --- a/src/Hng.Infrastructure/Repository/Interface/IRepository.cs +++ b/src/Hng.Infrastructure/Repository/Interface/IRepository.cs @@ -8,10 +8,7 @@ public interface IRepository where T : EntityBase Task GetAsync(Guid id); Task GetBySpec(Expression> predicate, params Expression>[] includeProperties); Task> GetAllAsync(params Expression>[] includeProperties); - - IQueryable GetAllAsQueryable(params Expression>[] includeProperties); Task> GetAllBySpec(Expression> predicate, params Expression>[] includeProperties); - IQueryable GetQueryableBySpec(Expression> predicate); Task AddAsync(T entity); Task AddRangeAsync(IEnumerable entities); diff --git a/src/Hng.Infrastructure/Repository/Repository.cs b/src/Hng.Infrastructure/Repository/Repository.cs index 976b7918..f60ce813 100644 --- a/src/Hng.Infrastructure/Repository/Repository.cs +++ b/src/Hng.Infrastructure/Repository/Repository.cs @@ -84,25 +84,12 @@ public async Task> GetAllBySpec(Expression> predica return await entities.ToListAsync(); } - - + public IQueryable GetQueryableBySpec(Expression> predicate) { return _context.Set().AsNoTracking().Where(predicate); } - public IQueryable GetAllAsQueryable(params Expression>[] includeProperties) - { - IQueryable query = _context.Set(); - - foreach (var includeProperty in includeProperties) - { - query = query.Include(includeProperty); - } - - return query; - } - public async Task GetBySpec(Expression> predicate, params Expression>[] includeProperties) { var entities = _context.Set().Where(predicate).AsNoTracking(); From 517bdf5ba8186b03335e448768105194a2bd37aa Mon Sep 17 00:00:00 2001 From: Lankiman Date: Fri, 28 Feb 2025 23:02:43 +0100 Subject: [PATCH 06/15] fix:minor - implmented formating rules for ci validation --- ...rOrgnazationsByUserIdQueryHandlerShould.cs | 15 ++--- ...OrganizationsByUserIdQueryHandlerShould.cs | 56 ++++++++--------- ...MemberOrganizationsByUserIdQueryHandler.cs | 61 ++++++++++--------- ...sOwnedOrganizationsByUserIdQueryHandler.cs | 60 +++++++++--------- ...GetUsersMemberOrganizationByUserIdQuery.cs | 20 +++--- src/Hng.Web/Controllers/AdminController.cs | 36 ++++++----- 6 files changed, 131 insertions(+), 117 deletions(-) diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs index d76680ba..bdd30c02 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs @@ -1,4 +1,3 @@ -using System.Linq.Expressions; using AutoMapper; using Hng.Application.Features.SuperAdmin.Dto; using Hng.Application.Features.SuperAdmin.Handlers; @@ -7,6 +6,7 @@ using Hng.Domain.Entities; using Hng.Infrastructure.Repository.Interface; using Moq; +using System.Linq.Expressions; using Xunit; public class GetUsersMemberOrganizationsByUserIdQueryHandlerShould @@ -16,10 +16,11 @@ public class GetUsersMemberOrganizationsByUserIdQueryHandlerShould private readonly Mock> mockOrganizationRepository; private readonly IMapper mapper; private readonly GetUsersMemberOrganizationsByUserIdQueryHandler handler; + public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); - + // Set up AutoMapper with your profiles var config = new MapperConfiguration(cfg => { @@ -30,14 +31,14 @@ public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() _mapper = config.CreateMapper(); } - + [Fact] public async Task ReturnNullWhenUserIsNotFound() { _mockRepository.Setup(repo => repo.GetBySpec(It.IsAny>>(), It.IsAny>[]>())).ReturnsAsync((User)null); - - var result = await handler.Handle(new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(),new BaseQueryParameters()), CancellationToken.None); - + + var result = await handler.Handle(new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), CancellationToken.None); + Assert.Null(result); } -} \ No newline at end of file +} diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs index d46b108f..b61d229e 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -1,4 +1,3 @@ -using System.Linq.Expressions; using AutoMapper; using Hng.Application.Features.SuperAdmin.Dto; using Hng.Application.Features.SuperAdmin.Handlers; @@ -7,39 +6,40 @@ using Hng.Domain.Entities; using Hng.Infrastructure.Repository.Interface; using Moq; +using System.Linq.Expressions; using Xunit; -namespace Hng.Application.Test.Features.SuperAdmin; - -public class GetUsersOwnedOrganizationsByUserIdQueryHandlerShould +namespace Hng.Application.Test.Features.SuperAdmin { - private readonly Mock> _mockRepository; - private readonly IMapper _mapper; - private readonly Mock> mockOrganizationRepository; - private readonly IMapper mapper; - private readonly GetUsersOwnedOrganizationsByUserIdQueryHandler handler; - - public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() + public class GetUsersOwnedOrganizationsByUserIdQueryHandlerShould { - _mockRepository = new Mock>(); - mockOrganizationRepository = new Mock>(); - - var config = new MapperConfiguration(cfg => + private readonly Mock> _mockRepository; + private readonly IMapper _mapper; + private readonly Mock> mockOrganizationRepository; + private readonly IMapper mapper; + private readonly GetUsersOwnedOrganizationsByUserIdQueryHandler handler; + + public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() { + _mockRepository = new Mock>(); + mockOrganizationRepository = new Mock>(); - cfg.CreateMap(); - cfg.CreateMap(); - }); - _mapper = config.CreateMapper(); - } + var config = new MapperConfiguration(cfg => + { + cfg.CreateMap(); + cfg.CreateMap(); + }); + _mapper = config.CreateMapper(); + } - [Fact] - public async Task ReturnNullWhenUserIsNotFound() - { - _mockRepository.Setup(repo => repo.GetBySpec(It.IsAny>>(),It.IsAny>[]>())).ReturnsAsync((User)null); - - var result= await handler.Handle(new GetUsersOwnedOrganizationsByUserIdQuery(Guid.NewGuid(),new BaseQueryParameters()), CancellationToken.None); + [Fact] + public async Task ReturnNullWhenUserIsNotFound() + { + _mockRepository.Setup(repo => repo.GetBySpec(It.IsAny>>(), It.IsAny>[]>())).ReturnsAsync((User)null); + + var result = await handler.Handle(new GetUsersOwnedOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), CancellationToken.None); - Assert.Null(result); + Assert.Null(result); + } } -} \ No newline at end of file +} diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs index 85e8c756..8c76f279 100644 --- a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs @@ -7,39 +7,40 @@ using Hng.Infrastructure.Services.Interfaces; using MediatR; -namespace Hng.Application.Features.SuperAdmin.Handlers; - -public class GetUsersMemberOrganizationsByUserIdQueryHandler :IRequestHandler> +namespace Hng.Application.Features.SuperAdmin.Handlers { - private readonly IRepository _userRepository; - private readonly IRepository _organizationRepository; - private readonly IMapper _mapper; - private readonly IAuthenticationService _authenticationService; - public GetUsersMemberOrganizationsByUserIdQueryHandler(IRepository userRepository, - IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) + public class GetUsersMemberOrganizationsByUserIdQueryHandler : IRequestHandler> { - _userRepository = userRepository; - _organizationRepository = organizationRepository; - _mapper = mapper; - _authenticationService = authenticationService; - } + private readonly IRepository _userRepository; + private readonly IRepository _organizationRepository; + private readonly IMapper _mapper; + private readonly IAuthenticationService _authenticationService; - public async Task> Handle(GetUsersMemberOrganizationsByUserIdQuery request, CancellationToken cancellationToken) - { - var user =await _userRepository.GetBySpec(user => user.Id == request.UserId, user=>user.Organizations); - - if (user==null) + public GetUsersMemberOrganizationsByUserIdQueryHandler(IRepository userRepository, + IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) + { + _userRepository = userRepository; + _organizationRepository = organizationRepository; + _mapper = mapper; + _authenticationService = authenticationService; + } + + public async Task> Handle(GetUsersMemberOrganizationsByUserIdQuery request, CancellationToken cancellationToken) { - return null; + var user = await _userRepository.GetBySpec(user => user.Id == request.UserId, user => user.Organizations); + + if (user == null) + { + return null; + } + + var userMemberOrganizations = user.Organizations.Where(org => org.OwnerId != user.Id).ToList(); + + var mappedOrganizations = _mapper.Map>(userMemberOrganizations); + + var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserMemberOrganizationsQueryParameter.Offset, request.UserMemberOrganizationsQueryParameter.Limit); + + return organizationResult; } - var userMemberOrganizations = user.Organizations.Where(org=>org.OwnerId!=user.Id).ToList(); - - var mappedOrganizations = _mapper.Map>(userMemberOrganizations); - - // var mappedProducts = _mapper.Map>(products); - - var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserMemberOrganizationsQueryParameter.Offset, request.UserMemberOrganizationsQueryParameter.Limit); - - return organizationResult ; } -} \ No newline at end of file +} diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs index 54a21dcf..60c88d1b 100644 --- a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs @@ -7,38 +7,40 @@ using Hng.Infrastructure.Services.Interfaces; using MediatR; -namespace Hng.Application.Features.SuperAdmin.Handlers; - -public class GetUsersOwnedOrganizationsByUserIdQueryHandler:IRequestHandler> +namespace Hng.Application.Features.SuperAdmin.Handlers { - private readonly IRepository _userRepository; - private readonly IRepository _organizationRepository; - private readonly IMapper _mapper; - private readonly IAuthenticationService _authenticationService; - public GetUsersOwnedOrganizationsByUserIdQueryHandler(IRepository userRepository, - IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) + public class GetUsersOwnedOrganizationsByUserIdQueryHandler : IRequestHandler> { - _userRepository = userRepository; - _organizationRepository = organizationRepository; - _mapper = mapper; - _authenticationService = authenticationService; - } + private readonly IRepository _userRepository; + private readonly IRepository _organizationRepository; + private readonly IMapper _mapper; + private readonly IAuthenticationService _authenticationService; - public async Task> Handle( GetUsersOwnedOrganizationsByUserIdQuery request, CancellationToken cancellationToken) - { - var user =await _userRepository.GetBySpec(user => user.Id == request.UserId, user=>user.Organizations); - - if (user==null) + public GetUsersOwnedOrganizationsByUserIdQueryHandler(IRepository userRepository, + IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) + { + _userRepository = userRepository; + _organizationRepository = organizationRepository; + _mapper = mapper; + _authenticationService = authenticationService; + } + + public async Task> Handle(GetUsersOwnedOrganizationsByUserIdQuery request, CancellationToken cancellationToken) { - return null; + var user = await _userRepository.GetBySpec(user => user.Id == request.UserId, user => user.Organizations); + + if (user == null) + { + return null; + } + + var userOwnedOrganizations = user.Organizations.Where(org => org.OwnerId == user.Id).ToList(); + + var mappedOrganizations = _mapper.Map>(userOwnedOrganizations); + + var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserOwnedOrganizationsQueryParameter.Offset, request.UserOwnedOrganizationsQueryParameter.Limit); + + return organizationResult; } - var userOwnedOrganizations = user.Organizations.Where(org=>org.OwnerId==user.Id).ToList(); - - var mappedOrganizations = _mapper.Map>(userOwnedOrganizations); - - var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserOwnedOrganizationsQueryParameter.Offset, request.UserOwnedOrganizationsQueryParameter.Limit); - - return organizationResult ; } - -} \ No newline at end of file +} diff --git a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs index fa738fb6..deeb49bb 100644 --- a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs +++ b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs @@ -2,15 +2,17 @@ using Hng.Application.Shared.Dtos; using MediatR; -namespace Hng.Application.Features.SuperAdmin.Queries; - -public class GetUsersMemberOrganizationsByUserIdQuery: IRequest> +namespace Hng.Application.Features.SuperAdmin.Queries { - public GetUsersMemberOrganizationsByUserIdQuery(Guid userId, BaseQueryParameters userMemberOrganizationsQueryParameter) + public class GetUsersMemberOrganizationsByUserIdQuery : IRequest> { - UserId = userId; - UserMemberOrganizationsQueryParameter = userMemberOrganizationsQueryParameter; + public GetUsersMemberOrganizationsByUserIdQuery(Guid userId, BaseQueryParameters userMemberOrganizationsQueryParameter) + { + UserId = userId; + UserMemberOrganizationsQueryParameter = userMemberOrganizationsQueryParameter; + } + + public Guid UserId { get; set; } + public BaseQueryParameters UserMemberOrganizationsQueryParameter { get; set; } } - public Guid UserId { get; set; } - public BaseQueryParameters UserMemberOrganizationsQueryParameter { get; set; } -} \ No newline at end of file +} diff --git a/src/Hng.Web/Controllers/AdminController.cs b/src/Hng.Web/Controllers/AdminController.cs index c4435dde..3e0be147 100644 --- a/src/Hng.Web/Controllers/AdminController.cs +++ b/src/Hng.Web/Controllers/AdminController.cs @@ -29,7 +29,7 @@ public async Task GetUsersBySearch([FromQuery] UsersQueryParameter var users = await _mediator.Send(new GetUsersBySearchQuery(parameters)); return Ok(new PaginatedResponseDto> { Data = users, Metadata = users.MetaData }); } - + /// /// Admin: Users - gets all organizations owned by a user by the user's id /// @@ -39,23 +39,27 @@ public async Task GetUsersBySearch([FromQuery] UsersQueryParameter [ProducesResponseType(typeof(SuccessResponseDto>>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(FailureResponseDto), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(StatusCodeResponse), StatusCodes.Status404NotFound)] - public async Task GetUserOwnedOrganizationsByUserId([FromRoute] Guid id, [FromQuery] BaseQueryParameters parameters) + public async Task GetUserOwnedOrganizationsByUserId([FromRoute] Guid id, [FromQuery] BaseQueryParameters parameters) { if (!Guid.TryParse(id.ToString(), out _)) { - return BadRequest( new FailureResponseDto{Message = "Valid user ID must be Provided"}); + return BadRequest(new FailureResponseDto { Message = "Valid user ID must be Provided" }); } - var userOrganizations = await _mediator.Send(new GetUsersOwnedOrganizationsByUserIdQuery(id,parameters)); + + var userOrganizations = await _mediator.Send(new GetUsersOwnedOrganizationsByUserIdQuery(id, parameters)); if (userOrganizations == null) { return NotFound(new StatusCodeResponse - { Message = "User not found", StatusCode = StatusCodes.Status404NotFound }); + { + Message = "User not found", + StatusCode = StatusCodes.Status404NotFound + }); } - - return Ok(new PaginatedResponseDto> { Data =userOrganizations , Metadata = userOrganizations.MetaData }); + + return Ok(new PaginatedResponseDto> { Data = userOrganizations, Metadata = userOrganizations.MetaData }); } - + /// /// Admin: Users - gets all organizations a user belongs by the user's id /// @@ -65,21 +69,25 @@ public async Task GetUserOwnedOrganizationsByUserId([FromRoute] Gu [ProducesResponseType(typeof(SuccessResponseDto>>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(FailureResponseDto), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(StatusCodeResponse), StatusCodes.Status404NotFound)] - public async Task GetUserMemberOrganizationsByUserId([FromRoute] Guid id, [FromQuery] BaseQueryParameters parameters) + public async Task GetUserMemberOrganizationsByUserId([FromRoute] Guid id, [FromQuery] BaseQueryParameters parameters) { if (!Guid.TryParse(id.ToString(), out _)) { - return BadRequest( new FailureResponseDto{Message = "Valid user ID must be Provided"}); + return BadRequest(new FailureResponseDto { Message = "Valid user ID must be Provided" }); } - var userOrganizations = await _mediator.Send(new GetUsersMemberOrganizationsByUserIdQuery(id,parameters)); + + var userOrganizations = await _mediator.Send(new GetUsersMemberOrganizationsByUserIdQuery(id, parameters)); if (userOrganizations == null) { return NotFound(new StatusCodeResponse - { Message = "User not found", StatusCode = StatusCodes.Status404NotFound }); + { + Message = "User not found", + StatusCode = StatusCodes.Status404NotFound + }); } - - return Ok(new PaginatedResponseDto> { Data =userOrganizations , Metadata = userOrganizations.MetaData }); + + return Ok(new PaginatedResponseDto> { Data = userOrganizations, Metadata = userOrganizations.MetaData }); } } } From 41fff18d24055210624b24d127aee5e955d08647 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Fri, 28 Feb 2025 23:07:27 +0100 Subject: [PATCH 07/15] fix: updated previos whitespacing fix --- .../Hng.Infrastructure.csproj | 78 +++++++++---------- .../Repository/Repository.cs | 15 ++-- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/src/Hng.Infrastructure/Hng.Infrastructure.csproj b/src/Hng.Infrastructure/Hng.Infrastructure.csproj index f09cf709..efdf2be4 100644 --- a/src/Hng.Infrastructure/Hng.Infrastructure.csproj +++ b/src/Hng.Infrastructure/Hng.Infrastructure.csproj @@ -1,45 +1,45 @@  - - net8.0 - enable - disable - + + net8.0 + enable + disable + - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + - - - + + + - - - Always - - + + + Always + + - \ No newline at end of file + diff --git a/src/Hng.Infrastructure/Repository/Repository.cs b/src/Hng.Infrastructure/Repository/Repository.cs index f60ce813..49614b58 100644 --- a/src/Hng.Infrastructure/Repository/Repository.cs +++ b/src/Hng.Infrastructure/Repository/Repository.cs @@ -1,8 +1,8 @@ -using System.Linq.Expressions; using Hng.Domain.Entities; using Hng.Infrastructure.Context; using Hng.Infrastructure.Repository.Interface; using Microsoft.EntityFrameworkCore; +using System.Linq.Expressions; namespace Hng.Infrastructure.Repository { @@ -84,12 +84,12 @@ public async Task> GetAllBySpec(Expression> predica return await entities.ToListAsync(); } - + public IQueryable GetQueryableBySpec(Expression> predicate) { return _context.Set().AsNoTracking().Where(predicate); } - + public async Task GetBySpec(Expression> predicate, params Expression>[] includeProperties) { var entities = _context.Set().Where(predicate).AsNoTracking(); @@ -109,12 +109,11 @@ public Task UpdateAsync(T entity) public async Task SaveChanges() { - - //Add newly registered user to the organisation if they were invited + // Add newly registered user to the organisation if they were invited var newUsers = _context.ChangeTracker.Entries() - .Where(e => e.State == EntityState.Added) - .Select(e => e.Entity) - .ToList(); + .Where(e => e.State == EntityState.Added) + .Select(e => e.Entity) + .ToList(); if (newUsers.Count != 0) { From 0855dc6964a6f4d3ff779c042ec91c3ea3429d43 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Fri, 28 Feb 2025 23:09:07 +0100 Subject: [PATCH 08/15] fix: updated previos whitespacing fix --- .../Hng.Infrastructure.csproj | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Hng.Infrastructure/Hng.Infrastructure.csproj b/src/Hng.Infrastructure/Hng.Infrastructure.csproj index efdf2be4..f09cf709 100644 --- a/src/Hng.Infrastructure/Hng.Infrastructure.csproj +++ b/src/Hng.Infrastructure/Hng.Infrastructure.csproj @@ -1,45 +1,45 @@  - - net8.0 - enable - disable - + + net8.0 + enable + disable + - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + - - - + + + - - - Always - - + + + Always + + - + \ No newline at end of file From a9d61d74a97728a8120b3021ad9e42595cff17b2 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Fri, 28 Feb 2025 23:17:27 +0100 Subject: [PATCH 09/15] fix: fixed test failure for admin user orginazation query handler --- .../GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs | 3 ++- .../GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs | 3 ++- .../GetUsersMemberOrganizationsByUserIdQueryHandler.cs | 3 +-- .../Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs | 3 +-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs index bdd30c02..18374117 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs @@ -14,12 +14,12 @@ public class GetUsersMemberOrganizationsByUserIdQueryHandlerShould private readonly Mock> _mockRepository; private readonly IMapper _mapper; private readonly Mock> mockOrganizationRepository; - private readonly IMapper mapper; private readonly GetUsersMemberOrganizationsByUserIdQueryHandler handler; public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); + mockOrganizationRepository = new Mock>(); // Set up AutoMapper with your profiles var config = new MapperConfiguration(cfg => @@ -30,6 +30,7 @@ public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() }); _mapper = config.CreateMapper(); + handler = new GetUsersMemberOrganizationsByUserIdQueryHandler(_mockRepository.Object, mockOrganizationRepository.Object, _mapper); } [Fact] diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs index b61d229e..422a5748 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -16,7 +16,6 @@ public class GetUsersOwnedOrganizationsByUserIdQueryHandlerShould private readonly Mock> _mockRepository; private readonly IMapper _mapper; private readonly Mock> mockOrganizationRepository; - private readonly IMapper mapper; private readonly GetUsersOwnedOrganizationsByUserIdQueryHandler handler; public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() @@ -30,6 +29,8 @@ public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() cfg.CreateMap(); }); _mapper = config.CreateMapper(); + + handler = new GetUsersOwnedOrganizationsByUserIdQueryHandler(_mockRepository.Object, mockOrganizationRepository.Object, _mapper); } [Fact] diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs index 8c76f279..c530d644 100644 --- a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs @@ -17,12 +17,11 @@ public class GetUsersMemberOrganizationsByUserIdQueryHandler : IRequestHandler userRepository, - IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) + IRepository organizationRepository, IMapper mapper) { _userRepository = userRepository; _organizationRepository = organizationRepository; _mapper = mapper; - _authenticationService = authenticationService; } public async Task> Handle(GetUsersMemberOrganizationsByUserIdQuery request, CancellationToken cancellationToken) diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs index 60c88d1b..7dfa7a2c 100644 --- a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs @@ -17,12 +17,11 @@ public class GetUsersOwnedOrganizationsByUserIdQueryHandler : IRequestHandler userRepository, - IRepository organizationRepository, IMapper mapper, IAuthenticationService authenticationService) + IRepository organizationRepository, IMapper mapper) { _userRepository = userRepository; _organizationRepository = organizationRepository; _mapper = mapper; - _authenticationService = authenticationService; } public async Task> Handle(GetUsersOwnedOrganizationsByUserIdQuery request, CancellationToken cancellationToken) From c2f51f318c941838bc21a229b2ab746565707435 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Sun, 2 Mar 2025 16:24:24 +0100 Subject: [PATCH 10/15] fix(source control) fix merge conflicts when trying to commit --- ...rOrgnazationsByUserIdQueryHandlerShould.cs | 6 +-- ...OrganizationsByUserIdQueryHandlerShould.cs | 6 +-- .../Authorization/IsSuperAdminHandler.cs | 54 +++++++++++++++++++ .../Authorization/IsSuperAdminRequirement.cs | 8 +++ ...MemberOrganizationsByUserIdQueryHandler.cs | 48 ++++++++--------- ...sOwnedOrganizationsByUserIdQueryHandler.cs | 49 ++++++++--------- ...GetUsersMemberOrganizationByUserIdQuery.cs | 20 ++++--- src/Hng.Web/Controllers/AdminController.cs | 16 ++---- src/Hng.Web/Hng.Web.csproj | 10 ++-- src/Hng.Web/Program.cs | 14 +++++ 10 files changed, 140 insertions(+), 91 deletions(-) create mode 100644 src/Hng.Application/Features/SuperAdmin/Authorization/IsSuperAdminHandler.cs create mode 100644 src/Hng.Application/Features/SuperAdmin/Authorization/IsSuperAdminRequirement.cs diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs index 18374117..33f6c510 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs @@ -13,14 +13,12 @@ public class GetUsersMemberOrganizationsByUserIdQueryHandlerShould { private readonly Mock> _mockRepository; private readonly IMapper _mapper; - private readonly Mock> mockOrganizationRepository; private readonly GetUsersMemberOrganizationsByUserIdQueryHandler handler; public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); - mockOrganizationRepository = new Mock>(); - + // Set up AutoMapper with your profiles var config = new MapperConfiguration(cfg => { @@ -30,7 +28,7 @@ public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() }); _mapper = config.CreateMapper(); - handler = new GetUsersMemberOrganizationsByUserIdQueryHandler(_mockRepository.Object, mockOrganizationRepository.Object, _mapper); + handler = new GetUsersMemberOrganizationsByUserIdQueryHandler(_mockRepository.Object, _mapper); } [Fact] diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs index 422a5748..c01e6a21 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -15,14 +15,12 @@ public class GetUsersOwnedOrganizationsByUserIdQueryHandlerShould { private readonly Mock> _mockRepository; private readonly IMapper _mapper; - private readonly Mock> mockOrganizationRepository; private readonly GetUsersOwnedOrganizationsByUserIdQueryHandler handler; public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); - mockOrganizationRepository = new Mock>(); - + var config = new MapperConfiguration(cfg => { cfg.CreateMap(); @@ -30,7 +28,7 @@ public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() }); _mapper = config.CreateMapper(); - handler = new GetUsersOwnedOrganizationsByUserIdQueryHandler(_mockRepository.Object, mockOrganizationRepository.Object, _mapper); + handler = new GetUsersOwnedOrganizationsByUserIdQueryHandler(_mockRepository.Object, _mapper); } [Fact] diff --git a/src/Hng.Application/Features/SuperAdmin/Authorization/IsSuperAdminHandler.cs b/src/Hng.Application/Features/SuperAdmin/Authorization/IsSuperAdminHandler.cs new file mode 100644 index 00000000..3f610ae6 --- /dev/null +++ b/src/Hng.Application/Features/SuperAdmin/Authorization/IsSuperAdminHandler.cs @@ -0,0 +1,54 @@ +using Hng.Application.Shared.Dtos; +using Hng.Domain.Entities; +using Hng.Infrastructure.Repository.Interface; +using Hng.Infrastructure.Services.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; + +namespace Hng.Application.Features.SuperAdmin.Authorization; + +public class IsSuperAdminHandler : AuthorizationHandler +{ + private readonly IRepository _userRepository; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IAuthenticationService _authenticationService; + + public IsSuperAdminHandler(IRepository userRepository, IHttpContextAccessor httpContextAccessor, IAuthenticationService authenticationService) + { + _userRepository = userRepository; + _httpContextAccessor = httpContextAccessor; + _authenticationService = authenticationService; + } + + protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, IsSuperAdminRequirement requirement) + { + + var userId = await _authenticationService.GetCurrentUserAsync(); + + if (!Guid.TryParse(userId.ToString(), out _)) + { + context.Fail(); + return; + } + + var user = await _userRepository.GetBySpec(u => u.Id == userId); + + Console.WriteLine($"This is the User : {user}"); + + if (user != null && user.IsSuperAdmin) + { + context.Succeed(requirement); + } + else + { + var response = new StatusCodeResponse() + { + StatusCode = StatusCodes.Status403Forbidden, + Message = "You are not Authorized to access this resource" + }; + _httpContextAccessor.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden; + await _httpContextAccessor.HttpContext.Response.WriteAsJsonAsync(response); + context.Fail(); + } + } +} diff --git a/src/Hng.Application/Features/SuperAdmin/Authorization/IsSuperAdminRequirement.cs b/src/Hng.Application/Features/SuperAdmin/Authorization/IsSuperAdminRequirement.cs new file mode 100644 index 00000000..646f06f7 --- /dev/null +++ b/src/Hng.Application/Features/SuperAdmin/Authorization/IsSuperAdminRequirement.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Authorization; + +namespace Hng.Application.Features.SuperAdmin.Authorization; + +public class IsSuperAdminRequirement : IAuthorizationRequirement +{ + +} \ No newline at end of file diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs index c530d644..c678bdbc 100644 --- a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersMemberOrganizationsByUserIdQueryHandler.cs @@ -7,39 +7,35 @@ using Hng.Infrastructure.Services.Interfaces; using MediatR; -namespace Hng.Application.Features.SuperAdmin.Handlers +namespace Hng.Application.Features.SuperAdmin.Handlers; + +public class GetUsersMemberOrganizationsByUserIdQueryHandler : IRequestHandler> { - public class GetUsersMemberOrganizationsByUserIdQueryHandler : IRequestHandler> + private readonly IRepository _userRepository; + private readonly IMapper _mapper; + + public GetUsersMemberOrganizationsByUserIdQueryHandler(IRepository userRepository, IMapper mapper) { - private readonly IRepository _userRepository; - private readonly IRepository _organizationRepository; - private readonly IMapper _mapper; - private readonly IAuthenticationService _authenticationService; + _userRepository = userRepository; + _mapper = mapper; + } - public GetUsersMemberOrganizationsByUserIdQueryHandler(IRepository userRepository, - IRepository organizationRepository, IMapper mapper) - { - _userRepository = userRepository; - _organizationRepository = organizationRepository; - _mapper = mapper; - } + public async Task> Handle(GetUsersMemberOrganizationsByUserIdQuery request, CancellationToken cancellationToken) + { + var user = await _userRepository.GetBySpec(user => user.Id == request.UserId, user => user.Organizations); - public async Task> Handle(GetUsersMemberOrganizationsByUserIdQuery request, CancellationToken cancellationToken) + if (user == null) { - var user = await _userRepository.GetBySpec(user => user.Id == request.UserId, user => user.Organizations); - - if (user == null) - { - return null; - } + return null; + } + var userMemberOrganizations = user.Organizations.Where(org => org.OwnerId != user.Id).ToList(); - var userMemberOrganizations = user.Organizations.Where(org => org.OwnerId != user.Id).ToList(); + var mappedOrganizations = _mapper.Map>(userMemberOrganizations); - var mappedOrganizations = _mapper.Map>(userMemberOrganizations); + // var mappedProducts = _mapper.Map>(products); - var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserMemberOrganizationsQueryParameter.Offset, request.UserMemberOrganizationsQueryParameter.Limit); + var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserMemberOrganizationsQueryParameter.Offset, request.UserMemberOrganizationsQueryParameter.Limit); - return organizationResult; - } + return organizationResult; } -} +} \ No newline at end of file diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs index 7dfa7a2c..59547303 100644 --- a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersOwnedOrganizationsByUserIdQueryHandler.cs @@ -7,39 +7,34 @@ using Hng.Infrastructure.Services.Interfaces; using MediatR; -namespace Hng.Application.Features.SuperAdmin.Handlers +namespace Hng.Application.Features.SuperAdmin.Handlers; + +public class GetUsersOwnedOrganizationsByUserIdQueryHandler : IRequestHandler> { - public class GetUsersOwnedOrganizationsByUserIdQueryHandler : IRequestHandler> + private readonly IRepository _userRepository; + private readonly IMapper _mapper; + + public GetUsersOwnedOrganizationsByUserIdQueryHandler(IRepository userRepository, IMapper mapper) { - private readonly IRepository _userRepository; - private readonly IRepository _organizationRepository; - private readonly IMapper _mapper; - private readonly IAuthenticationService _authenticationService; + _userRepository = userRepository; + _mapper = mapper; + } - public GetUsersOwnedOrganizationsByUserIdQueryHandler(IRepository userRepository, - IRepository organizationRepository, IMapper mapper) - { - _userRepository = userRepository; - _organizationRepository = organizationRepository; - _mapper = mapper; - } + public async Task> Handle(GetUsersOwnedOrganizationsByUserIdQuery request, CancellationToken cancellationToken) + { + var user = await _userRepository.GetBySpec(user => user.Id == request.UserId, user => user.Organizations); - public async Task> Handle(GetUsersOwnedOrganizationsByUserIdQuery request, CancellationToken cancellationToken) + if (user == null) { - var user = await _userRepository.GetBySpec(user => user.Id == request.UserId, user => user.Organizations); - - if (user == null) - { - return null; - } - - var userOwnedOrganizations = user.Organizations.Where(org => org.OwnerId == user.Id).ToList(); + return null; + } + var userOwnedOrganizations = user.Organizations.Where(org => org.OwnerId == user.Id).ToList(); - var mappedOrganizations = _mapper.Map>(userOwnedOrganizations); + var mappedOrganizations = _mapper.Map>(userOwnedOrganizations); - var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserOwnedOrganizationsQueryParameter.Offset, request.UserOwnedOrganizationsQueryParameter.Limit); + var organizationResult = PagedListDto.ToPagedList(mappedOrganizations, request.UserOwnedOrganizationsQueryParameter.Offset, request.UserOwnedOrganizationsQueryParameter.Limit); - return organizationResult; - } + return organizationResult; } -} + +} \ No newline at end of file diff --git a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs index deeb49bb..8b61f1f6 100644 --- a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs +++ b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersMemberOrganizationByUserIdQuery.cs @@ -2,17 +2,15 @@ using Hng.Application.Shared.Dtos; using MediatR; -namespace Hng.Application.Features.SuperAdmin.Queries +namespace Hng.Application.Features.SuperAdmin.Queries; + +public class GetUsersMemberOrganizationsByUserIdQuery : IRequest> { - public class GetUsersMemberOrganizationsByUserIdQuery : IRequest> + public GetUsersMemberOrganizationsByUserIdQuery(Guid userId, BaseQueryParameters userMemberOrganizationsQueryParameter) { - public GetUsersMemberOrganizationsByUserIdQuery(Guid userId, BaseQueryParameters userMemberOrganizationsQueryParameter) - { - UserId = userId; - UserMemberOrganizationsQueryParameter = userMemberOrganizationsQueryParameter; - } - - public Guid UserId { get; set; } - public BaseQueryParameters UserMemberOrganizationsQueryParameter { get; set; } + UserId = userId; + UserMemberOrganizationsQueryParameter = userMemberOrganizationsQueryParameter; } -} + public Guid UserId { get; set; } + public BaseQueryParameters UserMemberOrganizationsQueryParameter { get; set; } +} \ No newline at end of file diff --git a/src/Hng.Web/Controllers/AdminController.cs b/src/Hng.Web/Controllers/AdminController.cs index 3e0be147..183f730c 100644 --- a/src/Hng.Web/Controllers/AdminController.cs +++ b/src/Hng.Web/Controllers/AdminController.cs @@ -9,6 +9,7 @@ namespace Hng.Web.Controllers { [ApiController] [Route("api/v1/admin")] + [Authorize(Policy = "IsSuperAdmin")] public class AdminController : ControllerBase { private readonly IMediator _mediator; @@ -22,7 +23,6 @@ public AdminController(IMediator mediator) /// /// [HttpGet("users")] - [Authorize] [ProducesResponseType(StatusCodes.Status200OK)] public async Task GetUsersBySearch([FromQuery] UsersQueryParameters parameters) { @@ -35,7 +35,6 @@ public async Task GetUsersBySearch([FromQuery] UsersQueryParameter /// /// [HttpGet("users/{id}/organizations/owned")] - [Authorize] [ProducesResponseType(typeof(SuccessResponseDto>>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(FailureResponseDto), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(StatusCodeResponse), StatusCodes.Status404NotFound)] @@ -45,16 +44,12 @@ public async Task GetUserOwnedOrganizationsByUserId([FromRoute] Gu { return BadRequest(new FailureResponseDto { Message = "Valid user ID must be Provided" }); } - var userOrganizations = await _mediator.Send(new GetUsersOwnedOrganizationsByUserIdQuery(id, parameters)); if (userOrganizations == null) { return NotFound(new StatusCodeResponse - { - Message = "User not found", - StatusCode = StatusCodes.Status404NotFound - }); + { Message = "User not found", StatusCode = StatusCodes.Status404NotFound }); } return Ok(new PaginatedResponseDto> { Data = userOrganizations, Metadata = userOrganizations.MetaData }); @@ -65,7 +60,6 @@ public async Task GetUserOwnedOrganizationsByUserId([FromRoute] Gu /// /// [HttpGet("users/{id}/organizations/member")] - [Authorize] [ProducesResponseType(typeof(SuccessResponseDto>>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(FailureResponseDto), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(StatusCodeResponse), StatusCodes.Status404NotFound)] @@ -75,16 +69,12 @@ public async Task GetUserMemberOrganizationsByUserId([FromRoute] G { return BadRequest(new FailureResponseDto { Message = "Valid user ID must be Provided" }); } - var userOrganizations = await _mediator.Send(new GetUsersMemberOrganizationsByUserIdQuery(id, parameters)); if (userOrganizations == null) { return NotFound(new StatusCodeResponse - { - Message = "User not found", - StatusCode = StatusCodes.Status404NotFound - }); + { Message = "User not found", StatusCode = StatusCodes.Status404NotFound }); } return Ok(new PaginatedResponseDto> { Data = userOrganizations, Metadata = userOrganizations.MetaData }); diff --git a/src/Hng.Web/Hng.Web.csproj b/src/Hng.Web/Hng.Web.csproj index 8ccebcfa..84003047 100644 --- a/src/Hng.Web/Hng.Web.csproj +++ b/src/Hng.Web/Hng.Web.csproj @@ -18,12 +18,6 @@ 4 - - - - - - @@ -56,6 +50,10 @@ + + + + \ No newline at end of file diff --git a/src/Hng.Web/Program.cs b/src/Hng.Web/Program.cs index 58b04200..905aa7c7 100644 --- a/src/Hng.Web/Program.cs +++ b/src/Hng.Web/Program.cs @@ -4,11 +4,13 @@ using Hng.Application; using Hng.Infrastructure; using System.Reflection; +using Hng.Application.Features.SuperAdmin.Authorization; using Prometheus; using Hng.Web.ModelStateError; using Microsoft.AspNetCore.Mvc; using Hng.Web.Filters.Swashbuckle; using Hng.Graphql; +using Microsoft.AspNetCore.Authorization; var builder = WebApplication.CreateBuilder(args); @@ -59,6 +61,18 @@ }); }); +builder.Services.AddHttpContextAccessor(); + +//add admin authorization policy +builder.Services.AddAuthorizationBuilder() + .AddPolicy("IsSuperAdmin", policy => + { + policy.Requirements.Add(new IsSuperAdminRequirement()); + }); + +builder.Services.AddScoped(); + + var app = builder.Build(); await app.MigrateAndSeed(); From 8781fdbb13f9bef9d9fbd27701ad6119c25cb023 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Sun, 2 Mar 2025 16:30:13 +0100 Subject: [PATCH 11/15] fix(formating) - fixed whitespace formating for application test.csproj --- src/Hng.Application.Test/Hng.Application.Test.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Hng.Application.Test/Hng.Application.Test.csproj b/src/Hng.Application.Test/Hng.Application.Test.csproj index e0b8e35c..fb441858 100644 --- a/src/Hng.Application.Test/Hng.Application.Test.csproj +++ b/src/Hng.Application.Test/Hng.Application.Test.csproj @@ -17,10 +17,12 @@ + runtime; build; native; contentfiles; analyzers; buildtransitive all + From 952dfdbf6c3d6043cf1bf8e1760feccb9a82f744 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Sun, 2 Mar 2025 16:35:39 +0100 Subject: [PATCH 12/15] fix(formating)- fixed formating issue for files specified by ci --- ...MemberOrgnazationsByUserIdQueryHandlerShould.cs | 14 ++++++++++---- ...OwnedOrganizationsByUserIdQueryHandlerShould.cs | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs index 33f6c510..22d6da66 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs @@ -18,7 +18,7 @@ public class GetUsersMemberOrganizationsByUserIdQueryHandlerShould public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); - + // Set up AutoMapper with your profiles var config = new MapperConfiguration(cfg => { @@ -34,10 +34,16 @@ public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() [Fact] public async Task ReturnNullWhenUserIsNotFound() { - _mockRepository.Setup(repo => repo.GetBySpec(It.IsAny>>(), It.IsAny>[]>())).ReturnsAsync((User)null); + _mockRepository.Setup(repo => repo.GetBySpec( + It.IsAny>>(), + It.IsAny>[]>() + )).ReturnsAsync((User)null); - var result = await handler.Handle(new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), CancellationToken.None); + var result = await handler.Handle( + new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), + CancellationToken.None + ); Assert.Null(result); } -} +} \ No newline at end of file diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs index c01e6a21..08cdaed4 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -20,7 +20,7 @@ public class GetUsersOwnedOrganizationsByUserIdQueryHandlerShould public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); - + var config = new MapperConfiguration(cfg => { cfg.CreateMap(); @@ -34,11 +34,17 @@ public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() [Fact] public async Task ReturnNullWhenUserIsNotFound() { - _mockRepository.Setup(repo => repo.GetBySpec(It.IsAny>>(), It.IsAny>[]>())).ReturnsAsync((User)null); + _mockRepository.Setup(repo => repo.GetBySpec( + It.IsAny>>(), + It.IsAny>[]>() + )).ReturnsAsync((User)null); - var result = await handler.Handle(new GetUsersOwnedOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), CancellationToken.None); + var result = await handler.Handle( + new GetUsersOwnedOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), + CancellationToken.None + ); Assert.Null(result); } } -} +} \ No newline at end of file From 32c095769ebd4b5a489f69204cb91206d10cac8d Mon Sep 17 00:00:00 2001 From: Lankiman Date: Sun, 2 Mar 2025 16:38:13 +0100 Subject: [PATCH 13/15] fix(formating)- fixed formating issue for files specified by ci --- ...sersOwnedOrganizationsByUserIdQueryHandlerShould.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs index 08cdaed4..45878419 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -11,13 +11,13 @@ namespace Hng.Application.Test.Features.SuperAdmin { - public class GetUsersOwnedOrganizationsByUserIdQueryHandlerShould + public class GetUsersMemberOrganizationsByUserIdQueryHandlerShould { private readonly Mock> _mockRepository; private readonly IMapper _mapper; - private readonly GetUsersOwnedOrganizationsByUserIdQueryHandler handler; + private readonly GetUsersMemberOrganizationsByUserIdQueryHandler handler; - public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() + public GetUsersMemberOrganizationsByUserIdQueryHandlerShould() { _mockRepository = new Mock>(); @@ -28,7 +28,7 @@ public GetUsersOwnedOrganizationsByUserIdQueryHandlerShould() }); _mapper = config.CreateMapper(); - handler = new GetUsersOwnedOrganizationsByUserIdQueryHandler(_mockRepository.Object, _mapper); + handler = new GetUsersMemberOrganizationsByUserIdQueryHandler(_mockRepository.Object, _mapper); } [Fact] @@ -40,7 +40,7 @@ public async Task ReturnNullWhenUserIsNotFound() )).ReturnsAsync((User)null); var result = await handler.Handle( - new GetUsersOwnedOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), + new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), CancellationToken.None ); From 263a8a505451c082ffc3af1db5b897eccc3cfe70 Mon Sep 17 00:00:00 2001 From: Lankiman Date: Sun, 2 Mar 2025 16:40:04 +0100 Subject: [PATCH 14/15] fix(formating)- fixed formating issue for files specified by ci --- .../GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs index 45878419..1fb4af81 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -39,10 +39,7 @@ public async Task ReturnNullWhenUserIsNotFound() It.IsAny>[]>() )).ReturnsAsync((User)null); - var result = await handler.Handle( - new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), - CancellationToken.None - ); + var result = await handler.Handle(new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()),CancellationToken.None); Assert.Null(result); } From 503bbc0c926f87559ebbf61cb0b4395d4f597cac Mon Sep 17 00:00:00 2001 From: Lankiman Date: Sun, 2 Mar 2025 16:43:29 +0100 Subject: [PATCH 15/15] fix(formating)- fixed formating issue for files specified by ci --- .../GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs | 2 +- .../GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs index 22d6da66..5ff8b7ba 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersMemberOrgnazationsByUserIdQueryHandlerShould.cs @@ -40,7 +40,7 @@ public async Task ReturnNullWhenUserIsNotFound() )).ReturnsAsync((User)null); var result = await handler.Handle( - new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), + new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), CancellationToken.None ); diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs index 1fb4af81..943d2ab5 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersOwnedOrganizationsByUserIdQueryHandlerShould.cs @@ -39,7 +39,7 @@ public async Task ReturnNullWhenUserIsNotFound() It.IsAny>[]>() )).ReturnsAsync((User)null); - var result = await handler.Handle(new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()),CancellationToken.None); + var result = await handler.Handle(new GetUsersMemberOrganizationsByUserIdQuery(Guid.NewGuid(), new BaseQueryParameters()), CancellationToken.None); Assert.Null(result); }