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 GivenInvalidPasswordForUser_RespondsWithBadRequest()
            {
                var url = GetAuthenticateUrl();

                const string emailAddress = "*****@*****.**";
                const string password     = "******";

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

                var user = new TestUserEntityBuilder()
                           .WithEmailAddress(emailAddress)
                           .Build();

                await _userCollection.InsertOneAsync(user);

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

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

                Assert.Multiple(() =>
                {
                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Conflict));
                    Assert.That(responseData.ExceptionCode, Is.EqualTo((int)ExceptionCode.DataMismatchException));
                    Assert.That(responseData.TechnicalMessage, Is.Not.Null);
                    Assert.That(responseData.UserMessage, Is.EqualTo(ExceptionMessages.Authentication.PasswordIsIncorrect));
                });
            }
            public async Task GivenNoUserWithEmail_RespondsWithNotFound()
            {
                // Arrange
                var url = GetAuthenticateUrl();

                const string emailAddress = "*****@*****.**";
                const string password     = "******";

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

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

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

                Assert.Multiple(() =>
                {
                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
                    Assert.That(responseData.ExceptionCode, Is.EqualTo((int)ExceptionCode.EntityNotFound));
                    Assert.That(responseData.TechnicalMessage, Is.Not.Null);
                    Assert.That(responseData.UserMessage, Is.EqualTo(ExceptionMessages.User.UserNotFound));
                });
            }
            public async Task GivenNoEmailAddress_RespondsWithModelState()
            {
                var url = GetAuthenticateUrl();

                const string password = "******";

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

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

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

                Assert.Multiple(() =>
                {
                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
                    DiagnoseaAssert.Contains(
                        responseData.Errors,
                        nameof(AuthenticateRequest.EmailAddress),
                        ExceptionMessages.Interchange.Required);
                });
            }
            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 GivenNoPassword_RespondsWithModelState()
            {
                var url = GetAuthenticateUrl();

                const string emailAddress = "*****@*****.**";

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

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

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

                Assert.Multiple(() =>
                {
                    Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
                    DiagnoseaAssert.Contains(responseData.Errors, nameof(AuthenticateRequest.Password), ExceptionMessages.Interchange.Required);
                });
            }