public async Task GivenValidCredentials_RespondsWithBearerTokenWithRolesClaim()
            {
                // Arrange
                var url = GetAuthenticateUrl();

                var          userId             = Guid.NewGuid();
                const string emailAddress       = "*****@*****.**";
                const string password           = "******";
                const string productKey         = "This is a product key";
                const string testProductOneName = "Test Product One Name";
                const string testProductTwoName = "Test product Two Name";

                var hashedPassword = BCrypt.Net.BCrypt.HashPassword(password);

                var authenticate = new TestAuthenticateRequestBuilder()
                                   .WithEmailAddress(emailAddress)
                                   .WithPassword(password)
                                   .Build();

                var user = new TestUserEntityBuilder()
                           .WithId(userId)
                           .WithEmailAddress(emailAddress)
                           .WithPassword(hashedPassword)
                           .WithRole(UserRole.Administrator)
                           .Build();

                await _userCollection.InsertOneAsync(user);

                var license = new TestLicenseEntityBuilder()
                              .WithUserId(userId)
                              .WithKey(productKey)
                              .WithProduct(new TestLicenseProductEntityBuilder()
                                           .WithName(testProductOneName)
                                           .Build())
                              .WithProduct(new TestLicenseProductEntityBuilder()
                                           .WithName(testProductTwoName)
                                           .Build())
                              .Build();

                await _licenseCollection.InsertOneAsync(license);

                // Act
                var response = await HttpClient.PostAsJsonAsync(url, authenticate);

                // Assert
                var responseData = await response.Content.ReadFromJsonAsync <AuthenticatedResponse>();

                var jwtSecurityTokenHander = new JwtSecurityTokenHandler();
                var securityToken          = jwtSecurityTokenHander.ReadJwtToken(responseData.BearerToken);

                Assert.Multiple(() =>
                {
                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));

                    var roleClaims             = securityToken.Claims.Where(x => x.Type == SubmarineRegisteredClaimNames.Roles);
                    var administratorRoleClaim = roleClaims.FirstOrDefault(x => x.Value == UserRole.Administrator.ToString());

                    Assert.That(administratorRoleClaim, Is.Not.Null);
                });
            }
            public async Task GivenValidCredentials_RespondsWithBearerTokenWithAudienceClaim()
            {
                // Arrange
                var url = GetAuthenticateUrl();

                var          userId             = Guid.NewGuid();
                const string emailAddress       = "*****@*****.**";
                const string password           = "******";
                const string productKey         = "This is a product key";
                const string testProductOneName = "Test Product One Name";
                const string testProductTwoName = "Test product Two Name";

                var hashedPassword = BCrypt.Net.BCrypt.HashPassword(password);

                var authenticate = new TestAuthenticateRequestBuilder()
                                   .WithEmailAddress(emailAddress)
                                   .WithPassword(password)
                                   .Build();

                var user = new TestUserEntityBuilder()
                           .WithId(userId)
                           .WithEmailAddress(emailAddress)
                           .WithPassword(hashedPassword)
                           .Build();

                await _userCollection.InsertOneAsync(user);

                var license = new TestLicenseEntityBuilder()
                              .WithUserId(userId)
                              .WithKey(productKey)
                              .WithProduct(new TestLicenseProductEntityBuilder()
                                           .WithName(testProductOneName)
                                           .Build())
                              .WithProduct(new TestLicenseProductEntityBuilder()
                                           .WithName(testProductTwoName)
                                           .Build())
                              .Build();

                await _licenseCollection.InsertOneAsync(license);

                // Act
                var response = await HttpClient.PostAsJsonAsync(url, authenticate);

                // Assert
                var responseData = await response.Content.ReadFromJsonAsync <AuthenticatedResponse>();

                var jwtSecurityTokenHander = new JwtSecurityTokenHandler();
                var securityToken          = jwtSecurityTokenHander.ReadJwtToken(responseData.BearerToken);

                Assert.Multiple(() =>
                {
                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
                    Assert.That(securityToken.Audiences.Contains(license.Key));
                });
            }
            public async Task GivenValidCredentials_ReturnsBearerToken()
            {
                // Arrange
                var          userId            = Guid.NewGuid();
                const string emailAddress      = "This is an email address";
                const string plainTextPassword = "******";
                const string licenseKey        = "This is a license key";

                var authentication = new TestAuthenticationDtoBuilder()
                                     .WithEmailAddress(emailAddress)
                                     .WithPlainTextPassword(plainTextPassword)
                                     .Build();

                var user = new TestUserEntityBuilder()
                           .WithId(userId)
                           .WithEmailAddress(emailAddress)
                           .WithRole(UserRole.Standard)
                           .Build();

                const bool isPasswordValid = true;

                var unexpiredProduct = new TestLicenseProductEntityBuilder()
                                       .WithName("Unexpired Product Name")
                                       .WithExpiration(DateTime.UtcNow.AddDays(1))
                                       .Build();

                var expiredProduct = new TestLicenseProductEntityBuilder()
                                     .WithName("Expired Product Name")
                                     .WithExpiration(DateTime.UtcNow.AddDays(-2))
                                     .Build();

                var license = new TestLicenseEntityBuilder()
                              .WithKey(licenseKey)
                              .WithProduct(unexpiredProduct)
                              .WithProduct(expiredProduct)
                              .Build();

                const string bearerToken = "This is a bearer token";

                _mediator.SetupHandler <GetUserByEmailQuery, UserEntity>().ReturnsAsync(user);
                _mediator.SetupHandler <CompareHashTextQuery, bool>().ReturnsAsync(isPasswordValid);
                _mediator.SetupHandler <GetLicenseByUserIdQuery, LicenseEntity>().ReturnsAsync(license);
                _mediator.SetupHandler <GenerateBearerTokenQuery, string>().ReturnsAsync(bearerToken);

                // Act
                var result = await _classUnderTest.AuthenticateAsync(authentication, CancellationToken.None);

                // Assert
                Assert.That(result.BearerToken, Is.EqualTo(bearerToken));

                _mediator.VerifyHandler <GetUserByEmailQuery, UserEntity>(query => query.EmailAddress == emailAddress, Times.Once());
                _mediator.VerifyHandler <CompareHashTextQuery, bool>(query => query.Hash == user.Password && query.Text == plainTextPassword, Times.Once());
                _mediator.VerifyHandler <GenerateBearerTokenQuery, string>(query => ValidateGenerateBearerTokenQuery(query, user, licenseKey), Times.Once());
            }