| { | { | ||||
| Task<bool> ValidateCustomer(string username, string password); | Task<bool> ValidateCustomer(string username, string password); | ||||
| Task<string?> GenerateToken(); | Task<string?> GenerateToken(); | ||||
| Task<Customer> GetByUserName(string username); | |||||
| } | } | ||||
| } | } |
| namespace Diligent.WebAPI.Business.Interfaces | namespace Diligent.WebAPI.Business.Interfaces | ||||
| { | { | ||||
| public interface ICustomerService | |||||
| public interface ICustomerRepository | |||||
| { | { | ||||
| Task<Customer> GetCustomer(string username); | Task<Customer> GetCustomer(string username); | ||||
| using Microsoft.AspNetCore.Identity; | using Microsoft.AspNetCore.Identity; | ||||
| using Microsoft.Extensions.Configuration; | using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.IdentityModel.Tokens; | using Microsoft.IdentityModel.Tokens; | ||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.IdentityModel.Tokens.Jwt; | using System.IdentityModel.Tokens.Jwt; | ||||
| using System.Linq; | |||||
| using System.Security.Claims; | using System.Security.Claims; | ||||
| using System.Text; | using System.Text; | ||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Business.Services | namespace Diligent.WebAPI.Business.Services | ||||
| { | { | ||||
| public class AuthenticationService:IAuthenticationService | |||||
| public class AuthenticationService : IAuthenticationService | |||||
| { | { | ||||
| private readonly UserManager<Customer> _customerManager; | private readonly UserManager<Customer> _customerManager; | ||||
| private readonly IConfiguration _configuration; | private readonly IConfiguration _configuration; | ||||
| private Customer _customer; | private Customer _customer; | ||||
| public AuthenticationService(UserManager<Customer> customerManager,IConfiguration configuration) | |||||
| public AuthenticationService(UserManager<Customer> customerManager, IConfiguration configuration) | |||||
| { | { | ||||
| _customerManager = customerManager; | _customerManager = customerManager; | ||||
| _configuration = configuration; | _configuration = configuration; | ||||
| } | } | ||||
| public async Task<bool> ValidateCustomer(string username,string password) | |||||
| public async Task<bool> ValidateCustomer(string username, string password) | |||||
| { | { | ||||
| _customer = await _customerManager.FindByNameAsync(username); | _customer = await _customerManager.FindByNameAsync(username); | ||||
| return (_customer != null && await _customerManager.CheckPasswordAsync | return (_customer != null && await _customerManager.CheckPasswordAsync | ||||
| private async Task<List<Claim>> GetClaims() | private async Task<List<Claim>> GetClaims() | ||||
| { | { | ||||
| //method creates a list of claims with the user name inside and all the roles the user belongs to. | //method creates a list of claims with the user name inside and all the roles the user belongs to. | ||||
| Claim claim = new (ClaimTypes.Name, _customer.UserName); | |||||
| Claim claim = new(ClaimTypes.Name, _customer.UserName); | |||||
| var claims = new List<Claim> | var claims = new List<Claim> | ||||
| { | { | ||||
| return new SigningCredentials(secret, SecurityAlgorithms.HmacSha256); | return new SigningCredentials(secret, SecurityAlgorithms.HmacSha256); | ||||
| } | } | ||||
| public async Task<Customer> GetByUserName(string username) | |||||
| { | |||||
| return await _customerManager.FindByNameAsync(username); | |||||
| } | |||||
| private JwtSecurityToken GenerateTokenOptions(SigningCredentials | private JwtSecurityToken GenerateTokenOptions(SigningCredentials | ||||
| signingCredentials, List<Claim> claims) | signingCredentials, List<Claim> claims) | ||||
| { | { |
| using Diligent.WebAPI.Business.MongoServices; | |||||
| using Diligent.WebAPI.Data; | |||||
| using Diligent.WebAPI.Data.Entities; | |||||
| using Microsoft.Extensions.Options; | |||||
| using MongoDB.Driver; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Diagnostics.CodeAnalysis; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| [ExcludeFromCodeCoverage] | |||||
| public class AuthorizationService : BaseMongo<Customer> | |||||
| { | |||||
| public AuthorizationService(IOptions<WebApiDatabaseSettings> webApiDatabaseSettings) : | |||||
| base(webApiDatabaseSettings, "Customer") | |||||
| { } | |||||
| public async Task<Customer> GetByUserName(string username) | |||||
| { | |||||
| return await _mongoCollection.Find(c => c.UserName == username).FirstOrDefaultAsync(); | |||||
| } | |||||
| } | |||||
| } |
| using Diligent.WebAPI.Business.Interfaces; | using Diligent.WebAPI.Business.Interfaces; | ||||
| using Diligent.WebAPI.Data.Entities; | using Diligent.WebAPI.Data.Entities; | ||||
| using Microsoft.AspNetCore.Identity; | using Microsoft.AspNetCore.Identity; | ||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Diagnostics.CodeAnalysis; | using System.Diagnostics.CodeAnalysis; | ||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Business.Services | namespace Diligent.WebAPI.Business.Services | ||||
| { | { | ||||
| [ExcludeFromCodeCoverage] | [ExcludeFromCodeCoverage] | ||||
| public class CustomerService : ICustomerService | |||||
| public class CustomerRepository : ICustomerRepository | |||||
| { | { | ||||
| private readonly UserManager<Customer> _customerManager; | private readonly UserManager<Customer> _customerManager; | ||||
| public CustomerService(UserManager<Customer> customerManager) | |||||
| public CustomerRepository(UserManager<Customer> customerManager) | |||||
| { | { | ||||
| _customerManager = customerManager; | _customerManager = customerManager; | ||||
| } | } |
| builder.Services.AddScoped<IRoomRepository, RoomRepository>(); | builder.Services.AddScoped<IRoomRepository, RoomRepository>(); | ||||
| builder.Services.AddScoped<IMongoDBContext, MongoDBContext>(); | builder.Services.AddScoped<IMongoDBContext, MongoDBContext>(); | ||||
| builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); | builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); | ||||
| builder.Services.AddScoped<ICustomerService, CustomerService>(); | |||||
| builder.Services.AddSingleton<AuthorizationService>(); | |||||
| builder.Services.AddScoped<ICustomerRepository, CustomerRepository>(); | |||||
| builder.Services.AddMediatR(Assembly.GetExecutingAssembly()); | builder.Services.AddMediatR(Assembly.GetExecutingAssembly()); | ||||
| builder.Services.AddSignalR(options => | builder.Services.AddSignalR(options => |
| private readonly UserManager<Customer> _customerManager; | private readonly UserManager<Customer> _customerManager; | ||||
| private readonly IAuthenticationService _authenticationService; | private readonly IAuthenticationService _authenticationService; | ||||
| private readonly IMapper _mapper; | private readonly IMapper _mapper; | ||||
| private readonly ICustomerService _customerService; | |||||
| private readonly ICustomerRepository _customerRepository; | |||||
| public LoginUserHandler(UserManager<Customer> customerManager, IAuthenticationService authenticationService, | public LoginUserHandler(UserManager<Customer> customerManager, IAuthenticationService authenticationService, | ||||
| IMapper mapper, ICustomerService customerService) | |||||
| IMapper mapper, ICustomerRepository customerService) | |||||
| { | { | ||||
| _customerManager = customerManager; | _customerManager = customerManager; | ||||
| _authenticationService = authenticationService; | _authenticationService = authenticationService; | ||||
| _mapper = mapper; | _mapper = mapper; | ||||
| _customerService = customerService; | |||||
| _customerRepository = customerService; | |||||
| } | } | ||||
| public async Task<CustomerReadDTO> Handle(LoginUserQuery request, CancellationToken cancellationToken) | public async Task<CustomerReadDTO> Handle(LoginUserQuery request, CancellationToken cancellationToken) | ||||
| { | { | ||||
| if (!await _authenticationService.ValidateCustomer(customerLoginDTO.Username, customerLoginDTO.Password)) | if (!await _authenticationService.ValidateCustomer(customerLoginDTO.Username, customerLoginDTO.Password)) | ||||
| throw new BadHttpRequestException("Authentication failed.Wrong Username or password"); | throw new BadHttpRequestException("Authentication failed.Wrong Username or password"); | ||||
| Customer customer = await _customerService.GetCustomer(customerLoginDTO.Username); | |||||
| Customer customer = await _customerRepository.GetCustomer(customerLoginDTO.Username); | |||||
| var customerReadDTO = _mapper.Map<CustomerReadDTO>(customer); | var customerReadDTO = _mapper.Map<CustomerReadDTO>(customer); | ||||
| customerReadDTO.Token = await _authenticationService.GenerateToken() ?? ""; | customerReadDTO.Token = await _authenticationService.GenerateToken() ?? ""; | ||||
| customerReadDTO.Roles = (List<string>)await _customerManager.GetRolesAsync(customer); | customerReadDTO.Roles = (List<string>)await _customerManager.GetRolesAsync(customer); |
| { | { | ||||
| public class AddNotificationHandler : IRequestHandler<AddNotificationCommand, Unit> | public class AddNotificationHandler : IRequestHandler<AddNotificationCommand, Unit> | ||||
| { | { | ||||
| private readonly ICustomerService _customerService; | |||||
| private readonly ICustomerRepository _customerService; | |||||
| public AddNotificationHandler(ICustomerService customerService) | |||||
| public AddNotificationHandler(ICustomerRepository customerRepository) | |||||
| { | { | ||||
| _customerService = customerService; | |||||
| _customerService = customerRepository; | |||||
| } | } | ||||
| public async Task<Unit> Handle(AddNotificationCommand request, CancellationToken cancellationToken) | public async Task<Unit> Handle(AddNotificationCommand request, CancellationToken cancellationToken) |
| { | { | ||||
| public class DeleteNotificationHandler : IRequestHandler<DeleteNotificationCommand, Unit> | public class DeleteNotificationHandler : IRequestHandler<DeleteNotificationCommand, Unit> | ||||
| { | { | ||||
| private readonly ICustomerService _customerService; | |||||
| private readonly ICustomerRepository _customerRepository; | |||||
| public DeleteNotificationHandler(ICustomerService customerService) | |||||
| public DeleteNotificationHandler(ICustomerRepository customerRepository) | |||||
| { | { | ||||
| _customerService = customerService; | |||||
| _customerRepository = customerRepository; | |||||
| } | } | ||||
| public async Task<Unit> Handle(DeleteNotificationCommand request, CancellationToken cancellationToken) | public async Task<Unit> Handle(DeleteNotificationCommand request, CancellationToken cancellationToken) | ||||
| { | { | ||||
| var user = await _customerService.GetCustomerById(request.NotificationData.UserId); | |||||
| var user = await _customerRepository.GetCustomerById(request.NotificationData.UserId); | |||||
| if (user == null) | if (user == null) | ||||
| { | { | ||||
| throw new NotFoundException(); | throw new NotFoundException(); | ||||
| } | } | ||||
| await _customerService.DeleteNotification(user, notification); | |||||
| await _customerRepository.DeleteNotification(user, notification); | |||||
| return new Unit(); | return new Unit(); | ||||
| } | } |
| { | { | ||||
| public class GetNotificationsHandler : IRequestHandler<GetNotificationsQuery, List<NotificationReadDTO>> | public class GetNotificationsHandler : IRequestHandler<GetNotificationsQuery, List<NotificationReadDTO>> | ||||
| { | { | ||||
| private readonly ICustomerService _customerService; | |||||
| private readonly ICustomerRepository _customerRepository; | |||||
| private readonly IMapper _mapper; | private readonly IMapper _mapper; | ||||
| public GetNotificationsHandler(ICustomerService customerService, IMapper mapper) | |||||
| public GetNotificationsHandler(ICustomerRepository customerRepository, IMapper mapper) | |||||
| { | { | ||||
| _customerService = customerService; | |||||
| _customerRepository = customerRepository; | |||||
| _mapper = mapper; | _mapper = mapper; | ||||
| } | } | ||||
| public async Task<List<NotificationReadDTO>> Handle(GetNotificationsQuery request, CancellationToken cancellationToken) | public async Task<List<NotificationReadDTO>> Handle(GetNotificationsQuery request, CancellationToken cancellationToken) | ||||
| { | { | ||||
| return _mapper.Map<List<NotificationReadDTO>>(await _customerService.ReadNotifications(request.UserId)); | |||||
| return _mapper.Map<List<NotificationReadDTO>>(await _customerRepository.ReadNotifications(request.UserId)); | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Business.Interfaces; | |||||
| using Microsoft.AspNetCore.SignalR; | using Microsoft.AspNetCore.SignalR; | ||||
| using Microsoft.IdentityModel.Tokens; | using Microsoft.IdentityModel.Tokens; | ||||
| using System.Diagnostics.CodeAnalysis; | |||||
| using System.IdentityModel.Tokens.Jwt; | using System.IdentityModel.Tokens.Jwt; | ||||
| using System.Net; | using System.Net; | ||||
| using System.Reflection; | |||||
| using System.Text; | using System.Text; | ||||
| using System.Web.Http; | using System.Web.Http; | ||||
| public class AuthorizationHubFilter : Attribute, IHubFilter | public class AuthorizationHubFilter : Attribute, IHubFilter | ||||
| { | { | ||||
| public string Roles; | public string Roles; | ||||
| private JwtSecurityToken _token; | |||||
| public async ValueTask<object> InvokeMethodAsync( | public async ValueTask<object> InvokeMethodAsync( | ||||
| HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object>> next) | HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object>> next) | ||||
| { | { | ||||
| Type type = typeof(AuthorizationHubFilter); | Type type = typeof(AuthorizationHubFilter); | ||||
| var arguments = Attribute.GetCustomAttributes(invocationContext.HubMethod).Where(k => k.TypeId.ToString() == type.ToString()).ToList(); | |||||
| var arguments = GetCustomAttributes(invocationContext.HubMethod) | |||||
| .Where(k => k.TypeId.ToString() == type.ToString()) | |||||
| .ToList(); | |||||
| // there is no custom attributes, so the filter does not need to perform authorization | // there is no custom attributes, so the filter does not need to perform authorization | ||||
| if (!arguments.Any()) | if (!arguments.Any()) | ||||
| return await next(invocationContext); | return await next(invocationContext); | ||||
| // get filter attribute | // get filter attribute | ||||
| var roles = Attribute.GetCustomAttribute(invocationContext.HubMethod, arguments[0].GetType()); | |||||
| var roles = GetCustomAttribute(invocationContext.HubMethod, arguments[0].GetType()); | |||||
| if (roles is null) | if (roles is null) | ||||
| throw new NullReferenceException(); | throw new NullReferenceException(); | ||||
| // get roles from filter attribute and split roles into an array | // get roles from filter attribute and split roles into an array | ||||
| var arrayOfRoles = ((AuthorizationHubFilter)roles).Roles.Split(","); | var arrayOfRoles = ((AuthorizationHubFilter)roles).Roles.Split(","); | ||||
| var context = invocationContext.Context.GetHttpContext(); | |||||
| var context = GetHttpContext(invocationContext); | |||||
| if (context is null) | if (context is null) | ||||
| throw new NullReferenceException(); | throw new NullReferenceException(); | ||||
| return await next(invocationContext); | return await next(invocationContext); | ||||
| } | } | ||||
| private static async Task AttachUserToContext(HttpContext context, string token, string[] roles) | |||||
| public async Task AttachUserToContext(HttpContext context, string token, string[] roles) | |||||
| { | { | ||||
| bool contain = false; | bool contain = false; | ||||
| try | try | ||||
| { | { | ||||
| var authorizationService = context.RequestServices.GetService(typeof(AuthorizationService)); | |||||
| var authorizationService = context.RequestServices.GetService(typeof(IAuthenticationService)); | |||||
| var configuration = context.RequestServices.GetService(typeof(IConfiguration)); | var configuration = context.RequestServices.GetService(typeof(IConfiguration)); | ||||
| if (authorizationService is null || configuration is null) | if (authorizationService is null || configuration is null) | ||||
| var audience = jwtSettings["validAudience"]; | var audience = jwtSettings["validAudience"]; | ||||
| var key = Encoding.UTF8.GetBytes(jwtSettings["jwtSecret"]); | var key = Encoding.UTF8.GetBytes(jwtSettings["jwtSecret"]); | ||||
| tokenHandler.ValidateToken(token, new TokenValidationParameters | |||||
| { | |||||
| ValidateIssuerSigningKey = true, | |||||
| IssuerSigningKey = new SymmetricSecurityKey(key), | |||||
| ValidIssuer = issuer, | |||||
| ValidAudience = audience, | |||||
| ValidateIssuer = true, | |||||
| ValidateAudience = true, | |||||
| ValidateLifetime = true, | |||||
| }, out SecurityToken validatedToken); | |||||
| var jwtToken = (JwtSecurityToken)validatedToken; | |||||
| var userName = jwtToken.Payload["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"].ToString(); | |||||
| var rl = (jwtToken.Payload["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"]).ToString(); | |||||
| SetToken(tokenHandler, token, audience, issuer, key); | |||||
| var userName = ReturnTokenPayload(_token, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"); | |||||
| var rl = ReturnTokenPayload(_token, "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"); | |||||
| if (rl is null) | if (rl is null) | ||||
| throw new Exception(); | throw new Exception(); | ||||
| if (!contain) | if (!contain) | ||||
| { | { | ||||
| contain = true; | |||||
| throw new Exception(); | throw new Exception(); | ||||
| } | } | ||||
| // attach user to context on successful jwt validation | // attach user to context on successful jwt validation | ||||
| if (userName != null) | if (userName != null) | ||||
| { | { | ||||
| context.Items["User"] = await ((AuthorizationService)authorizationService).GetByUserName(userName); | |||||
| context.Items["User"] = await ((IAuthenticationService)authorizationService).GetByUserName(userName); | |||||
| } | } | ||||
| } | } | ||||
| throw new UnauthorizedAccessException(); | throw new UnauthorizedAccessException(); | ||||
| } | } | ||||
| } | } | ||||
| [ExcludeFromCodeCoverage] | |||||
| public new virtual Attribute? GetCustomAttribute(MemberInfo element, Type attributeType) | |||||
| { | |||||
| return Attribute.GetCustomAttribute(element, attributeType); | |||||
| } | |||||
| [ExcludeFromCodeCoverage] | |||||
| public new virtual Attribute[] GetCustomAttributes(MemberInfo element) | |||||
| { | |||||
| return Attribute.GetCustomAttributes(element); | |||||
| } | |||||
| [ExcludeFromCodeCoverage] | |||||
| public virtual HttpContext? GetHttpContext(HubInvocationContext invocationContext) | |||||
| { | |||||
| return invocationContext.Context.GetHttpContext(); | |||||
| } | |||||
| [ExcludeFromCodeCoverage] | |||||
| public virtual void SetToken(JwtSecurityTokenHandler tokenHandler, string token, string audience, string issuer, byte[] key) | |||||
| { | |||||
| tokenHandler.ValidateToken(token, new TokenValidationParameters | |||||
| { | |||||
| ValidateIssuerSigningKey = true, | |||||
| IssuerSigningKey = new SymmetricSecurityKey(key), | |||||
| ValidIssuer = issuer, | |||||
| ValidAudience = audience, | |||||
| ValidateIssuer = true, | |||||
| ValidateAudience = true, | |||||
| ValidateLifetime = true, | |||||
| }, out SecurityToken validatedToken); | |||||
| _token = (JwtSecurityToken)validatedToken; | |||||
| } | |||||
| [ExcludeFromCodeCoverage] | |||||
| public virtual string? ReturnTokenPayload(JwtSecurityToken token, string payload) | |||||
| { | |||||
| return _token.Payload[payload].ToString(); | |||||
| } | |||||
| } | } | ||||
| } | } |
| using AutoMapper; | |||||
| using Diligent.WebAPI.Business.Interfaces; | |||||
| using Diligent.WebAPI.Data.Entities; | |||||
| using Diligent.WebAPI.Host.DTOs.Customer; | |||||
| using Diligent.WebAPI.Host.Mapper; | |||||
| using Diligent.WebAPI.Host.Mediator.Authentication.Commands; | |||||
| using Diligent.WebAPI.Host.Mediator.Authentication.Handlers; | |||||
| using Diligent.WebAPI.Host.Mediator.Authentication.Queries; | |||||
| using Microsoft.AspNetCore.Http; | |||||
| using Microsoft.AspNetCore.Identity; | |||||
| using Moq; | |||||
| namespace Tests | |||||
| { | |||||
| [TestFixture] | |||||
| public class AuthenticationHandlerTests | |||||
| { | |||||
| private Mock<IAuthenticationService> _authenticationServiceMock; | |||||
| private IMapper _mapper; | |||||
| private Mock<ICustomerRepository> _customerServiceMock; | |||||
| private Mock<UserManager<Customer>> _userManagerMock; | |||||
| private readonly Customer _customer = new() | |||||
| { | |||||
| Id = Guid.NewGuid(), | |||||
| Email = "user@gmail.com", | |||||
| FirstName = "User", | |||||
| LastName = "User", | |||||
| Notifications = new List<Notification>(), | |||||
| Roles = new List<Guid> { Guid.NewGuid() }, | |||||
| UserName = "user12" | |||||
| }; | |||||
| private readonly CustomerCreateDTO _customerCreateDTO = new() | |||||
| { | |||||
| Email = "user@gmail.com", | |||||
| FirstName = "User", | |||||
| LastName = "User", | |||||
| Username = "user12" | |||||
| }; | |||||
| [SetUp] | |||||
| public void Setup() | |||||
| { | |||||
| _authenticationServiceMock = new Mock<IAuthenticationService>(); | |||||
| _customerServiceMock = new Mock<ICustomerRepository>(); | |||||
| _userManagerMock = new Mock<UserManager<Customer>>(Mock.Of<IUserStore<Customer>>(), null, null, null, null, null, null, null, null); | |||||
| var configuration = new MapperConfiguration(cfg => cfg.AddProfile(new CustomerMappingProfile())); | |||||
| _mapper = new Mapper(configuration); | |||||
| } | |||||
| [Test] | |||||
| public void LoginUser_UserIsNotAuthenticated_ThrowBadHttpRequestException() | |||||
| { | |||||
| _authenticationServiceMock.Setup(a => a.ValidateCustomer(It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(false)); | |||||
| var query = new LoginUserQuery(new CustomerLoginDTO { Username = "user1", Password = "somePassword" }); | |||||
| var handler = new LoginUserHandler(_userManagerMock.Object, _authenticationServiceMock.Object, _mapper, _customerServiceMock.Object); | |||||
| Assert.That(async () => await handler.Handle(query, new CancellationToken()), Throws.Exception.TypeOf<BadHttpRequestException>()); | |||||
| } | |||||
| [Test] | |||||
| public async Task LoginUser_UserIsAuthenticated_ReturnUserObject() | |||||
| { | |||||
| var list = new List<string> { "Customer" }; | |||||
| _authenticationServiceMock.Setup(a => a.ValidateCustomer(It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(true)); | |||||
| _authenticationServiceMock.Setup(a => a.GenerateToken()).Returns(Task.FromResult("someToken")); | |||||
| _customerServiceMock.Setup(c => c.GetCustomer(It.IsAny<string>())).Returns(Task.FromResult(_customer)); | |||||
| _userManagerMock.Setup(u => u.GetRolesAsync(It.IsAny<Customer>())).Returns(Task.FromResult((IList<string>)list)); | |||||
| var query = new LoginUserQuery(new CustomerLoginDTO { Username = "user1", Password = "somePassword" }); | |||||
| var handler = new LoginUserHandler(_userManagerMock.Object, _authenticationServiceMock.Object, _mapper, _customerServiceMock.Object); | |||||
| var result = await handler.Handle(query, new CancellationToken()); | |||||
| Assert.That(result.Id, Is.EqualTo(_customer.Id.ToString())); | |||||
| } | |||||
| [Test] | |||||
| public void RegisterUser_ErrorWhenCreatingUser_ThrowBadHttpRequestException() | |||||
| { | |||||
| _userManagerMock.Setup(u => u.CreateAsync(It.IsAny<Customer>(), It.IsAny<string>())).ReturnsAsync(() => IdentityResult.Failed()); | |||||
| var command = new RegisterUserCommand(_customerCreateDTO); | |||||
| var handler = new RegisterUserHandler(_userManagerMock.Object, _authenticationServiceMock.Object, _mapper); | |||||
| Assert.That(() => handler.Handle(command, new CancellationToken()), Throws.Exception.TypeOf<BadHttpRequestException>()); | |||||
| } | |||||
| [Test] | |||||
| public async Task RegisterUser_ThereIsNoError_ReturnObject() | |||||
| { | |||||
| _userManagerMock.Setup(u => u.CreateAsync(It.IsAny<Customer>(), It.IsAny<string>())).ReturnsAsync(() => IdentityResult.Success); | |||||
| _userManagerMock.Setup(u => u.AddToRoleAsync(It.IsAny<Customer>(), It.IsAny<string>())).ReturnsAsync(() => IdentityResult.Success); | |||||
| _authenticationServiceMock.Setup(u => u.ValidateCustomer(It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(true)); | |||||
| _authenticationServiceMock.Setup(u => u.GenerateToken()).Returns(Task.FromResult("dasdada")); | |||||
| _userManagerMock.Setup(u => u.GetRolesAsync(It.IsAny<Customer>())).Returns(Task.FromResult((IList<string>)new List<string> { "role" })); | |||||
| var command = new RegisterUserCommand(_customerCreateDTO); | |||||
| var handler = new RegisterUserHandler(_userManagerMock.Object, _authenticationServiceMock.Object, _mapper); | |||||
| var result = await handler.Handle(command, new CancellationToken()); | |||||
| Assert.That(result, Is.Not.Null); | |||||
| } | |||||
| } | |||||
| } |
| using AutoMapper; | |||||
| using Diligent.WebAPI.Business.Interfaces; | |||||
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Data.Entities; | |||||
| using Diligent.WebAPI.Host.Mapper; | |||||
| using Microsoft.AspNetCore.Identity; | |||||
| using Microsoft.Extensions.Configuration; | |||||
| using Moq; | |||||
| namespace Tests | |||||
| { | |||||
| public class AuthenticationServiceTests | |||||
| { | |||||
| private Mock<IAuthenticationService> _authenticationServiceMock; | |||||
| private IAuthenticationService _authenticationService; | |||||
| private IConfiguration _configuration; | |||||
| private Mock<UserManager<Customer>> _userManagerMock; | |||||
| private readonly Customer _customer = new() | |||||
| { | |||||
| Id = Guid.NewGuid(), | |||||
| Email = "user@gmail.com", | |||||
| FirstName = "User", | |||||
| LastName = "User", | |||||
| Notifications = new List<Notification>(), | |||||
| Roles = new List<Guid> { Guid.NewGuid() }, | |||||
| UserName = "user12" | |||||
| }; | |||||
| [SetUp] | |||||
| public void Setup() | |||||
| { | |||||
| var inMemorySettings = new Dictionary<string, string> { | |||||
| {"JwtSettings:jwtSecret", "Ovo je neka sifra koja treba biti tajna"}, | |||||
| {"JwtSettings:validIssuer", "http://localhost:5116"}, | |||||
| {"JwtSettings:validAudience", "http://localhost:3000"}, | |||||
| }; | |||||
| _configuration = new ConfigurationBuilder() | |||||
| .AddInMemoryCollection(inMemorySettings) | |||||
| .Build(); | |||||
| _authenticationServiceMock = new Mock<IAuthenticationService>(); | |||||
| _userManagerMock = new Mock<UserManager<Customer>>(Mock.Of<IUserStore<Customer>>(), null, null, null, null, null, null, null, null); | |||||
| _authenticationService = new AuthenticationService(_userManagerMock.Object, _configuration); | |||||
| var configuration = new MapperConfiguration(cfg => cfg.AddProfile(new CustomerMappingProfile())); | |||||
| } | |||||
| [Test] | |||||
| public async Task ValidateCustomer_CustomerIsNull_CustomerIsNotValid() | |||||
| { | |||||
| _userManagerMock.Setup(u => u.FindByNameAsync(It.IsAny<string>())).Returns(Task.FromResult<Customer>(null)); | |||||
| await _authenticationServiceMock.Object.ValidateCustomer("dasdas", "dasdasd"); | |||||
| var result = await _authenticationService.ValidateCustomer(It.IsAny<string>(), It.IsAny<string>()); | |||||
| Assert.That(result, Is.False); | |||||
| } | |||||
| [Test] | |||||
| public async Task ValidateCustomer_CustomerIsNotNullAndUserCredentialsAreNotValid_CustomerIsNotValid() | |||||
| { | |||||
| _userManagerMock.Setup(u => u.FindByNameAsync(It.IsAny<string>())).Returns(Task.FromResult(_customer)); | |||||
| _userManagerMock.Setup(u => u.CheckPasswordAsync(It.IsAny<Customer>(), It.IsAny<string>())).Returns(Task.FromResult(false)); | |||||
| await _authenticationServiceMock.Object.ValidateCustomer("dasdas", "dasdasd"); | |||||
| var result = await _authenticationService.ValidateCustomer(It.IsAny<string>(), It.IsAny<string>()); | |||||
| Assert.That(result, Is.False); | |||||
| } | |||||
| [Test] | |||||
| public async Task ValidateCustomer_CustomerIsNotNullAndUserCredentialsAreValid_CustomerIsValid() | |||||
| { | |||||
| _userManagerMock.Setup(u => u.FindByNameAsync(It.IsAny<string>())).Returns(Task.FromResult(_customer)); | |||||
| _userManagerMock.Setup(u => u.CheckPasswordAsync(It.IsAny<Customer>(), It.IsAny<string>())).Returns(Task.FromResult(true)); | |||||
| var result = await _authenticationService.ValidateCustomer("dasdasd", "dasdasd"); | |||||
| Assert.That(result, Is.True); | |||||
| } | |||||
| [Test] | |||||
| public async Task GenerateToken_UserIsNotValid_ReturnNull() | |||||
| { | |||||
| _userManagerMock.Setup(u => u.GetRolesAsync(It.IsAny<Customer>())).ReturnsAsync((IList<string>)new List<string> { "roles" }); | |||||
| var result = await _authenticationService.GenerateToken(); | |||||
| Assert.That(result, Is.Null); | |||||
| } | |||||
| [Test] | |||||
| public async Task GenerateToken_UserIsValid_ReturnToken() | |||||
| { | |||||
| _userManagerMock.Setup(u => u.GetRolesAsync(It.IsAny<Customer>())).ReturnsAsync((IList<string>)new List<string> { "roles" }); | |||||
| _userManagerMock.Setup(u => u.FindByNameAsync(It.IsAny<string>())).Returns(Task.FromResult(_customer)); | |||||
| _userManagerMock.Setup(u => u.CheckPasswordAsync(It.IsAny<Customer>(), It.IsAny<string>())).Returns(Task.FromResult(true)); | |||||
| await _authenticationService.ValidateCustomer("dasdas", "dasd"); //user must be first valid and then we generate token for him | |||||
| var result = await _authenticationService.GenerateToken(); | |||||
| Assert.That(result, Is.Not.Null); | |||||
| } | |||||
| } | |||||
| } |
| private IAuthenticationService _authenticationService; | private IAuthenticationService _authenticationService; | ||||
| private IMapper _mapper; | private IMapper _mapper; | ||||
| private IConfiguration _configuration; | private IConfiguration _configuration; | ||||
| private Mock<ICustomerService> _customerServiceMock; | |||||
| private Mock<ICustomerRepository> _customerServiceMock; | |||||
| private Mock<UserManager<Customer>> _userManagerMock; | private Mock<UserManager<Customer>> _userManagerMock; | ||||
| private readonly Customer _customer = new() | private readonly Customer _customer = new() | ||||
| { | { | ||||
| .AddInMemoryCollection(inMemorySettings) | .AddInMemoryCollection(inMemorySettings) | ||||
| .Build(); | .Build(); | ||||
| _authenticationServiceMock = new Mock<IAuthenticationService>(); | _authenticationServiceMock = new Mock<IAuthenticationService>(); | ||||
| _customerServiceMock = new Mock<ICustomerService>(); | |||||
| _customerServiceMock = new Mock<ICustomerRepository>(); | |||||
| _userManagerMock = new Mock<UserManager<Customer>>(Mock.Of<IUserStore<Customer>>(), null, null, null, null, null, null, null, null); | _userManagerMock = new Mock<UserManager<Customer>>(Mock.Of<IUserStore<Customer>>(), null, null, null, null, null, null, null, null); | ||||
| _authenticationService = new AuthenticationService(_userManagerMock.Object, _configuration); | _authenticationService = new AuthenticationService(_userManagerMock.Object, _configuration); | ||||
| var configuration = new MapperConfiguration(cfg => cfg.AddProfile(new CustomerMappingProfile())); | var configuration = new MapperConfiguration(cfg => cfg.AddProfile(new CustomerMappingProfile())); |
| using AutoMapper; | |||||
| using Diligent.WebAPI.Business.Interfaces; | |||||
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Data.Entities; | |||||
| using Diligent.WebAPI.Host.Mapper; | |||||
| using Diligent.WebAPI.Host.Middlewares; | |||||
| using Microsoft.AspNetCore.Http; | |||||
| using Microsoft.AspNetCore.Identity; | |||||
| using Microsoft.AspNetCore.SignalR; | |||||
| using Microsoft.Extensions.Configuration; | |||||
| using Moq; | |||||
| using System.IdentityModel.Tokens.Jwt; | |||||
| using System.Reflection; | |||||
| using System.Web.Http; | |||||
| namespace Tests | |||||
| { | |||||
| public class AuthorizationHubFilterTests | |||||
| { | |||||
| private IAuthenticationService _authenticationService; | |||||
| private Mock<IAuthenticationService> _authenticationServiceMock; | |||||
| private IConfiguration _configuration; | |||||
| private Mock<UserManager<Customer>> _userManagerMock; | |||||
| private readonly Customer _customer = new() | |||||
| { | |||||
| Id = Guid.NewGuid(), | |||||
| Email = "user@gmail.com", | |||||
| FirstName = "User", | |||||
| LastName = "User", | |||||
| Notifications = new List<Notification>(), | |||||
| Roles = new List<Guid> { Guid.NewGuid() }, | |||||
| UserName = "user12" | |||||
| }; | |||||
| private Mock<AuthorizationHubFilter> _authorizationHubFilterMock; | |||||
| private AuthorizationHubFilter _authorizationHubFilter; | |||||
| private HubInvocationContext _hubInvocationContext; | |||||
| private Mock<Func<HubInvocationContext, ValueTask<object>>> _hubInvocationContextFuncMock; | |||||
| private Mock<HttpContext> _httpContextMock; | |||||
| [SetUp] | |||||
| public void Setup() | |||||
| { | |||||
| var inMemorySettings = new Dictionary<string, string> { | |||||
| {"JwtSettings:jwtSecret", "Ovo je neka sifra koja treba biti tajna"}, | |||||
| {"JwtSettings:validIssuer", "http://localhost:5116"}, | |||||
| {"JwtSettings:validAudience", "http://localhost:3000"}, | |||||
| }; | |||||
| _configuration = new ConfigurationBuilder() | |||||
| .AddInMemoryCollection(inMemorySettings) | |||||
| .Build(); | |||||
| _userManagerMock = new Mock<UserManager<Customer>>(Mock.Of<IUserStore<Customer>>(), null, null, null, null, null, null, null, null); | |||||
| _authenticationService = new AuthenticationService(_userManagerMock.Object, _configuration); | |||||
| _authenticationServiceMock = new Mock<IAuthenticationService>(); | |||||
| var configuration = new MapperConfiguration(cfg => cfg.AddProfile(new CustomerMappingProfile())); | |||||
| _authorizationHubFilterMock = new Mock<AuthorizationHubFilter>(); | |||||
| _authorizationHubFilter = new AuthorizationHubFilter(); | |||||
| var hubCallerContext = new Mock<HubCallerContext>(); | |||||
| var serviceProvider = new Mock<IServiceProvider>(); | |||||
| var hub = new Mock<Hub>(); | |||||
| var methodInfo = new Mock<MethodInfo>(); | |||||
| _hubInvocationContext = new HubInvocationContext(hubCallerContext.Object, serviceProvider.Object, hub.Object, methodInfo.Object, null); | |||||
| _hubInvocationContextFuncMock = new Mock<Func<HubInvocationContext, ValueTask<object>>>(); | |||||
| _httpContextMock = new Mock<HttpContext>(); | |||||
| } | |||||
| [Test] | |||||
| public async Task InvokeMethodAsync_ThereIsNoCustomAttributes_SkipFurtherExcecutionOfFilter() | |||||
| { | |||||
| _authorizationHubFilterMock.Setup(k => k.GetCustomAttributes(It.IsAny<MemberInfo>())).Returns(Array.Empty<Attribute>()); | |||||
| var result = await _authorizationHubFilterMock.Object.InvokeMethodAsync(_hubInvocationContext, _hubInvocationContextFuncMock.Object); | |||||
| Assert.That(result, Is.Null); | |||||
| } | |||||
| [Test] | |||||
| public void InvokeMethodAsync_ThereIsCustomAttributeButNoRoles_ThrowNullReferenceException() | |||||
| { | |||||
| _authorizationHubFilterMock.Setup(k => k.GetCustomAttributes(It.IsAny<MemberInfo>())) | |||||
| .Returns(new Attribute[1] { new AuthorizationHubFilter() }); | |||||
| _authorizationHubFilterMock.Setup(k => k.GetCustomAttribute(It.IsAny<MemberInfo>(), It.IsAny<Type>())).Returns((Attribute)null); | |||||
| Assert.That(() => _authorizationHubFilterMock.Object.InvokeMethodAsync(_hubInvocationContext, _hubInvocationContextFuncMock.Object), | |||||
| Throws.Exception.TypeOf<NullReferenceException>()); | |||||
| } | |||||
| [Test] | |||||
| public void InvokeMethodAsync_ThereIsCustomAttributeAndRolesAndHttpContextIsNull_ThrowNullReferenceException() | |||||
| { | |||||
| var filter = new AuthorizationHubFilter { Roles = "Customer,Support" }; | |||||
| _authorizationHubFilterMock.Setup(k => k.GetCustomAttributes(It.IsAny<MemberInfo>())).Returns(new Attribute[1] { filter }); | |||||
| _authorizationHubFilterMock.Setup(k => k.GetCustomAttribute(It.IsAny<MemberInfo>(), It.IsAny<Type>())).Returns(filter); | |||||
| _authorizationHubFilterMock.Setup(k => k.GetHttpContext(It.IsAny<HubInvocationContext>())).Returns((HttpContext)null); | |||||
| Assert.That(() => _authorizationHubFilterMock.Object.InvokeMethodAsync(_hubInvocationContext, _hubInvocationContextFuncMock.Object), | |||||
| Throws.Exception.TypeOf<NullReferenceException>()); | |||||
| } | |||||
| [Test] | |||||
| public async Task InvokeMethodAsync_ThereIsCustomAttributeAndRolesAndHttpContextIsNotNull_nextIsCalled() | |||||
| { | |||||
| var filter = new AuthorizationHubFilter { Roles = "Customer,Support" }; | |||||
| _httpContextMock.Setup(k => k.Request.Query[It.IsAny<string>()]).Returns("someToken"); | |||||
| //Optimization of this tests is to mock AttachToUser function but there is problem because that function is not virtual and if it were a virtual method there would be problems with other tests | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IAuthenticationService))).Returns(_authenticationServiceMock.Object); | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IConfiguration))).Returns(_configuration); | |||||
| _httpContextMock.Setup(k => k.Items[It.IsAny<string>()]).Returns(Task.CompletedTask); | |||||
| _authorizationHubFilterMock.Setup(k => k.ReturnTokenPayload(It.IsAny<JwtSecurityToken>(), It.IsAny<string>())) | |||||
| .Returns("Customer"); | |||||
| _authorizationHubFilterMock.Setup(k => k.GetCustomAttributes(It.IsAny<MemberInfo>())).Returns(new Attribute[1] { filter }); | |||||
| _authorizationHubFilterMock.Setup(k => k.GetCustomAttribute(It.IsAny<MemberInfo>(), It.IsAny<Type>())).Returns(filter); | |||||
| _authorizationHubFilterMock.Setup(k => k.GetHttpContext(It.IsAny<HubInvocationContext>())).Returns(_httpContextMock.Object); | |||||
| await _authorizationHubFilterMock.Object.InvokeMethodAsync(_hubInvocationContext, _hubInvocationContextFuncMock.Object); | |||||
| _hubInvocationContextFuncMock.Verify(k => k.Invoke(It.IsAny<HubInvocationContext>()), Times.Once); | |||||
| } | |||||
| [Test] | |||||
| public void AttachUserToContext_AuthorizationServiceIsNull_ThrowHttpResponseException() | |||||
| { | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IAuthenticationService))).Returns(null); | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IConfiguration))).Returns(_configuration); | |||||
| Assert.That(() => _authorizationHubFilter.AttachUserToContext(_httpContextMock.Object, "1", new string[1] { "1" }), | |||||
| Throws.Exception.TypeOf<HttpResponseException>()); | |||||
| } | |||||
| [Test] | |||||
| public void AttachUserToContext_IConfigurationIsNull_ThrowHttpResponseException() | |||||
| { | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IAuthenticationService))).Returns(_authenticationService); | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IConfiguration))).Returns(null); | |||||
| Assert.That(() => _authorizationHubFilter.AttachUserToContext(_httpContextMock.Object, "1", new string[1] { "1" }), | |||||
| Throws.Exception.TypeOf<HttpResponseException>()); | |||||
| } | |||||
| [Test] | |||||
| public void AttachUserToContext_ThereAreNoRolesForUser_ThrowHttpResponseException() | |||||
| { | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IAuthenticationService))).Returns(_authenticationService); | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IConfiguration))).Returns(_configuration); | |||||
| //_authorizationHubFilterMock.Setup(k => k.Proba(It.IsAny<JwtSecurityTokenHandler>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<byte[]>())); | |||||
| _authorizationHubFilterMock.Setup(k => k.ReturnTokenPayload(It.IsAny<JwtSecurityToken>(), It.IsAny<string>())) | |||||
| .Returns((string)null); | |||||
| Assert.That(() => _authorizationHubFilterMock.Object.AttachUserToContext(_httpContextMock.Object, "1", new string[1] { "1" }), | |||||
| Throws.Exception.TypeOf<HttpResponseException>()); | |||||
| } | |||||
| [Test] | |||||
| public void AttachUserToContext_RolesIsNotNullButUserIsNotAuthorized_ThrowUnauthorizedAccessException() | |||||
| { | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IAuthenticationService))).Returns(_authenticationService); | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IConfiguration))).Returns(_configuration); | |||||
| _authorizationHubFilterMock.Setup(k => k.ReturnTokenPayload(It.IsAny<JwtSecurityToken>(), It.IsAny<string>())) | |||||
| .Returns("Support"); | |||||
| Assert.That(() => _authorizationHubFilterMock.Object.AttachUserToContext(_httpContextMock.Object, "1", new string[1] { "Customer" }), | |||||
| Throws.Exception.TypeOf<UnauthorizedAccessException>()); | |||||
| } | |||||
| [Test] | |||||
| public async Task AttachUserToContext_RolesIsNotNullAndUserIAuthorized_GetByUsernameIsCalled() | |||||
| { | |||||
| _authenticationServiceMock.Setup(k => k.GetByUserName(It.IsAny<string>())).Returns(Task.FromResult(_customer)); | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IAuthenticationService))).Returns(_authenticationServiceMock.Object); | |||||
| _httpContextMock.Setup(k => k.RequestServices.GetService(typeof(IConfiguration))).Returns(_configuration); | |||||
| _httpContextMock.Setup(k => k.Items[It.IsAny<string>()]).Returns(Task.CompletedTask); | |||||
| _authorizationHubFilterMock.Setup(k => k.ReturnTokenPayload(It.IsAny<JwtSecurityToken>(), It.IsAny<string>())) | |||||
| .Returns("Customer"); | |||||
| await _authorizationHubFilterMock.Object.AttachUserToContext(_httpContextMock.Object, "1", new string[1] { "Customer" }); | |||||
| _authenticationServiceMock.Verify(k => k.GetByUserName(It.IsAny<string>()), Times.Once); | |||||
| } | |||||
| } | |||||
| } |
| [TestFixture] | [TestFixture] | ||||
| public class NotificationTests | public class NotificationTests | ||||
| { | { | ||||
| private Mock<ICustomerService> _customerServiceMock; | |||||
| private Mock<ICustomerRepository> _customerRepositoryMock; | |||||
| [SetUp] | [SetUp] | ||||
| public void Setup() | public void Setup() | ||||
| { | { | ||||
| _customerServiceMock = new Mock<ICustomerService>(); | |||||
| _customerRepositoryMock = new Mock<ICustomerRepository>(); | |||||
| } | } | ||||
| [Test] | [Test] | ||||
| public async Task DeleteNotification_CustomerIsNull_ThrowNotFoundException() | public async Task DeleteNotification_CustomerIsNull_ThrowNotFoundException() | ||||
| { | { | ||||
| _customerServiceMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| _customerRepositoryMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| .ReturnsAsync((Customer)null); | .ReturnsAsync((Customer)null); | ||||
| var deleteNotificationCommand = new DeleteNotificationCommand(new NotificationDeleteDTO | var deleteNotificationCommand = new DeleteNotificationCommand(new NotificationDeleteDTO | ||||
| RoomId = "1" | RoomId = "1" | ||||
| }); | }); | ||||
| var deleteNotificationHandler = new DeleteNotificationHandler(_customerServiceMock.Object); | |||||
| var deleteNotificationHandler = new DeleteNotificationHandler(_customerRepositoryMock.Object); | |||||
| Assert.That(async () => await deleteNotificationHandler.Handle(deleteNotificationCommand, new CancellationToken()), Throws.Exception.TypeOf<NotFoundException>()); | Assert.That(async () => await deleteNotificationHandler.Handle(deleteNotificationCommand, new CancellationToken()), Throws.Exception.TypeOf<NotFoundException>()); | ||||
| } | } | ||||
| [Test] | [Test] | ||||
| public async Task DeleteNotification_UserNotificationIsNull_ThrowNotFoundException() | public async Task DeleteNotification_UserNotificationIsNull_ThrowNotFoundException() | ||||
| { | { | ||||
| _customerServiceMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| _customerRepositoryMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| .ReturnsAsync(new Customer | .ReturnsAsync(new Customer | ||||
| { | { | ||||
| FirstName = "Dzenis", | FirstName = "Dzenis", | ||||
| RoomId = "3" | RoomId = "3" | ||||
| }); | }); | ||||
| var deleteNotificationHandler = new DeleteNotificationHandler(_customerServiceMock.Object); | |||||
| var deleteNotificationHandler = new DeleteNotificationHandler(_customerRepositoryMock.Object); | |||||
| Assert.That(async () => await deleteNotificationHandler.Handle(deleteNotificationCommand, new CancellationToken()), Throws.Exception.TypeOf<NotFoundException>()); | Assert.That(async () => await deleteNotificationHandler.Handle(deleteNotificationCommand, new CancellationToken()), Throws.Exception.TypeOf<NotFoundException>()); | ||||
| } | } | ||||
| } | } | ||||
| }; | }; | ||||
| _customerServiceMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| _customerRepositoryMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| .ReturnsAsync(customer); | .ReturnsAsync(customer); | ||||
| var deleteNotificationCommand = new DeleteNotificationCommand(new NotificationDeleteDTO | var deleteNotificationCommand = new DeleteNotificationCommand(new NotificationDeleteDTO | ||||
| RoomId = "2" | RoomId = "2" | ||||
| }); | }); | ||||
| var deleteNotificationHandler = new DeleteNotificationHandler(_customerServiceMock.Object); | |||||
| var deleteNotificationHandler = new DeleteNotificationHandler(_customerRepositoryMock.Object); | |||||
| await deleteNotificationHandler.Handle(deleteNotificationCommand, new CancellationToken()); | await deleteNotificationHandler.Handle(deleteNotificationCommand, new CancellationToken()); | ||||
| _customerServiceMock.Verify(mock => mock.DeleteNotification(customer, customer.Notifications[1])); | |||||
| _customerRepositoryMock.Verify(mock => mock.DeleteNotification(customer, customer.Notifications[1])); | |||||
| } | } | ||||
| [Test] | [Test] | ||||
| public async Task AddNotification_ReceiverIsNull_ThrowsNotFoundException() | public async Task AddNotification_ReceiverIsNull_ThrowsNotFoundException() | ||||
| { | { | ||||
| _customerServiceMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| _customerRepositoryMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| .ReturnsAsync((Customer)null); | .ReturnsAsync((Customer)null); | ||||
| var command = new AddNotificationCommand(new NotificationSaveDTO | var command = new AddNotificationCommand(new NotificationSaveDTO | ||||
| { | { | ||||
| ReceiverId = "1", | ReceiverId = "1", | ||||
| RoomId = "1" | RoomId = "1" | ||||
| }); | }); | ||||
| var handler = new AddNotificationHandler(_customerServiceMock.Object); | |||||
| var handler = new AddNotificationHandler(_customerRepositoryMock.Object); | |||||
| Assert.That(async () => await handler.Handle(command, new CancellationToken()), Throws.Exception.TypeOf<NotFoundException>()); | Assert.That(async () => await handler.Handle(command, new CancellationToken()), Throws.Exception.TypeOf<NotFoundException>()); | ||||
| } | } | ||||
| } | } | ||||
| }; | }; | ||||
| _customerServiceMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| _customerRepositoryMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| .ReturnsAsync(customer); | .ReturnsAsync(customer); | ||||
| var command = new AddNotificationCommand(new NotificationSaveDTO | var command = new AddNotificationCommand(new NotificationSaveDTO | ||||
| { | { | ||||
| ReceiverId = "1", | ReceiverId = "1", | ||||
| RoomId = "3" | RoomId = "3" | ||||
| }); | }); | ||||
| var handler = new AddNotificationHandler(_customerServiceMock.Object); | |||||
| var handler = new AddNotificationHandler(_customerRepositoryMock.Object); | |||||
| await handler.Handle(command, new CancellationToken()); | await handler.Handle(command, new CancellationToken()); | ||||
| _customerServiceMock.Verify(mock => mock.AddNotification(customer)); | |||||
| _customerRepositoryMock.Verify(mock => mock.AddNotification(customer)); | |||||
| } | } | ||||
| [Test] | [Test] | ||||
| } | } | ||||
| }; | }; | ||||
| _customerServiceMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| _customerRepositoryMock.Setup(x => x.GetCustomerById(It.IsAny<string>())) | |||||
| .ReturnsAsync(customer); | .ReturnsAsync(customer); | ||||
| var command = new AddNotificationCommand(new NotificationSaveDTO | var command = new AddNotificationCommand(new NotificationSaveDTO | ||||
| { | { | ||||
| ReceiverId = "1", | ReceiverId = "1", | ||||
| RoomId = "2" | RoomId = "2" | ||||
| }); | }); | ||||
| var handler = new AddNotificationHandler(_customerServiceMock.Object); | |||||
| var handler = new AddNotificationHandler(_customerRepositoryMock.Object); | |||||
| await handler.Handle(command, new CancellationToken()); | await handler.Handle(command, new CancellationToken()); | ||||
| _customerServiceMock.Verify(mock => mock.AddNotification(customer)); | |||||
| _customerRepositoryMock.Verify(mock => mock.AddNotification(customer)); | |||||
| } | } | ||||
| } | } | ||||
| } | } |