public async Task GetTermsOfServiceAsync_WithTestGuid_ReturnsCorrectResult()
        {
            // Arrange
            var testGuid = Guid.NewGuid();
            var testName = "TestTermsOfServiceName";

            termsOfServiceService.GetByIdAsync(testGuid, true).Returns(new TermsOfService {
                Uuid = testGuid, AgreementName = testName
            });

            var controller = new TermsOfServiceController(termsOfServiceService, orderByHelper, paginationHelper, mapper);

            // Act
            IActionResult actionResult = await controller.GetTermsOfServiceAsync(testGuid);

            // Assert
            var okResult = actionResult as OkObjectResult;

            Assert.NotNull(okResult);

            var termsOfService = okResult.Value as TermsOfService;

            Assert.NotNull(termsOfService);
            Assert.True(termsOfService.Uuid == testGuid, $"Retrieved Id {termsOfService.Uuid} not the same as sample id {testGuid}.");
            Assert.True(termsOfService.AgreementName == testName, $"Retrieved Name {termsOfService.AgreementName} not the same as sample id {testName}.");
        }
        public async Task CreateTermsOfServiceAsync_WithTestTermsOfService_ReturnsCreatedTermsOfService()
        {
            // Arrange
            var termsOfServiceService = Substitute.For <ITermsOfServiceService>();
            var inputModel            = new TermsOfServiceSubmit()
            {
                Uuid          = Guid.NewGuid(),
                AgreementName = "Test TermsOfService Name"
            };

            termsOfServiceService.CreateAsync(inputModel, Arg.Any <Guid>())
            .Returns(new TermsOfService()
            {
                Uuid          = inputModel.Uuid,
                AgreementName = inputModel.AgreementName
            }
                     );

            var controller = new TermsOfServiceController(termsOfServiceService, orderByHelper, paginationHelper, mapper);

            // Act
            IActionResult actionResult = await controller.CreateTermsOfServiceAsync(inputModel);

            // Assert
            var okResult = actionResult as OkObjectResult;

            Assert.NotNull(okResult);

            var termsOfService = okResult.Value as TermsOfService;

            Assert.NotNull(termsOfService);
            Assert.True(termsOfService.Uuid == inputModel.Uuid, $"Retrieved Id {termsOfService.Uuid} not the same as sample id {inputModel.Uuid}.");
            Assert.True(termsOfService.AgreementName == inputModel.AgreementName, $"Retrieved Name {termsOfService.AgreementName} not the same as sample Name {inputModel.AgreementName}.");
        }
        public async Task Index_ExecutedWithNoOutstandingAgreementsAndNoContextWithNonLocalRedirectUrl_ThrowsException()
        {
            //Arrange
            var id = Guid.NewGuid().ToString();

            using var termsOfServiceController = new TermsOfServiceController(fakeUserManager, termsOfServiceRepository, mockConfiguration, mockIdentityServerInteractionService,
                                                                              mockEventService, mockClientStore, fakeSignInManager)
                  {
                      ControllerContext = new ControllerContext()
                      {
                          HttpContext = new DefaultHttpContext()
                          {
                              User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
                        {
                            new Claim(ClaimTypes.Name, "example name"),
                            new Claim(ClaimTypes.NameIdentifier, id),
                            new Claim("sub", id),
                            new Claim("custom-claim", "example claim value"),
                        }, "mock")),
                          }
                      }
                  };

            fakeUserManager.SetUserModel(userModel);
            termsOfServiceRepository.GetAllOutstandingAgreementsByUserAsync(Arg.Any <Guid>()).Returns(new List <Guid>());

            var builder = new ConfigurationBuilder()
                          .SetBasePath(Directory.GetCurrentDirectory())
                          .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                          .AddEnvironmentVariables();

            var config = builder.Build();

            config.GetSection("TwoFactorAuthentication")["OrganizationEnforced"] = "false";
            config.GetSection("TwoFactorAuthentication")["AuthenticatorEnabled"] = "false";
            mockConfiguration.GetSection("TwoFactorAuthentication").Returns(config.GetSection("TwoFactorAuthentication"));

            var urlHelper = Substitute.For <IUrlHelper>();

            urlHelper.IsLocalUrl(Arg.Any <string>()).Returns(false);
            termsOfServiceController.Url = urlHelper;

            // Act
            try
            {
                var actionResult = await termsOfServiceController.Index(returnUrl : "http://www.test.me/redirect", 0);

                // Assert
                Assert.True(false, "Non-local redirect with no context must throw Exception.");
            }
            catch
            {
                // Assert
                Assert.True(true, "Non-local redirect with no context must throw Exception.");
            }
        }
        public async Task Index_ExecutedWithNoOutstandingAgreementsAndIsPkceClient_ViewResultReturned()
        {
            //Arrange
            var id = Guid.NewGuid().ToString();

            using var termsOfServiceController = new TermsOfServiceController(fakeUserManager, termsOfServiceRepository, mockConfiguration, mockIdentityServerInteractionService,
                                                                              mockEventService, mockClientStore, fakeSignInManager)
                  {
                      ControllerContext = new ControllerContext()
                      {
                          HttpContext = new DefaultHttpContext()
                          {
                              User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
                        {
                            new Claim(ClaimTypes.Name, "example name"),
                            new Claim(ClaimTypes.NameIdentifier, id),
                            new Claim("sub", id),
                            new Claim("custom-claim", "example claim value"),
                        }, "mock")),
                          }
                      }
                  };

            fakeUserManager.SetUserModel(userModel);
            termsOfServiceRepository.GetAllOutstandingAgreementsByUserAsync(Arg.Any <Guid>()).Returns(new List <Guid>());

            var builder = new ConfigurationBuilder()
                          .SetBasePath(Directory.GetCurrentDirectory())
                          .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                          .AddEnvironmentVariables();

            var config = builder.Build();

            config.GetSection("TwoFactorAuthentication")["OrganizationEnforced"] = "false";
            config.GetSection("TwoFactorAuthentication")["AuthenticatorEnabled"] = "false";
            mockConfiguration.GetSection("TwoFactorAuthentication").Returns(config.GetSection("TwoFactorAuthentication"));

            mockIdentityServerInteractionService.GetAuthorizationContextAsync(Arg.Any <string>()).Returns(authorizationRequest);

            client.RequirePkce = true;
            mockClientStore.FindEnabledClientByIdAsync(Arg.Any <string>()).Returns(client);

            // Act
            var actionResult = await termsOfServiceController.Index(RETURN_URL, 0);

            // Assert
            var viewResult = actionResult as ViewResult;

            Assert.NotNull(viewResult);
            Assert.True(viewResult.ViewName == "Redirect", $"ViewName must be 'Redirect'.");

            var model = viewResult.Model as RedirectViewModel;

            Assert.True(model.RedirectUrl == RETURN_URL, $"Redirect Url must be '{RETURN_URL}'.");
        }
        public async Task GetTermsOfServiceAsync_WithRandomGuid_ReturnsNotFoundResult()
        {
            // Arrange
            var controller = new TermsOfServiceController(termsOfServiceService, orderByHelper, paginationHelper, mapper);

            // Act
            var result = await controller.GetTermsOfServiceAsync(Guid.NewGuid());

            // Assert
            Assert.IsType <NotFoundResult>(result);
        }
        public async Task Index_PostExecutedWithUnAcceptedTermsOfServiceAndIsPkceClient_ViewResultReturned()
        {
            //Arrange
            var id = Guid.NewGuid().ToString();

            using var termsOfServiceController = new TermsOfServiceController(fakeUserManager, termsOfServiceRepository, mockConfiguration, mockIdentityServerInteractionService,
                                                                              mockEventService, mockClientStore, fakeSignInManager)
                  {
                      ControllerContext = new ControllerContext()
                      {
                          HttpContext = new DefaultHttpContext()
                          {
                              User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
                        {
                            new Claim(ClaimTypes.Name, "example name"),
                            new Claim(ClaimTypes.NameIdentifier, id),
                            new Claim("sub", id),
                            new Claim("custom-claim", "example claim value"),
                        }, "mock")),
                          }
                      }
                  };

            fakeUserManager.SetUserModel(userModel);

            var termOfServiceId          = Guid.NewGuid();
            var termsOfServiceInputModel = new TermsOfServiceInputModel()
            {
                Accepted = false,
                InitialAgreementCount = 3,
                ReturnUrl             = RETURN_URL,
                TermsOfServiceId      = termOfServiceId
            };

            mockIdentityServerInteractionService.GetAuthorizationContextAsync(Arg.Any <string>()).Returns(authorizationRequest);

            client.RequirePkce = true;
            mockClientStore.FindEnabledClientByIdAsync(Arg.Any <string>()).Returns(client);

            // Act
            var actionResult = await termsOfServiceController.Index(termsOfServiceInputModel, "accept", RETURN_URL);

            // Assert
            var viewResult = actionResult as ViewResult;

            Assert.NotNull(viewResult);

            var model = viewResult.Model as RedirectViewModel;

            Assert.NotNull(model);
            Assert.True(model.RedirectUrl == RETURN_URL, $"Redirect URL must be '{RETURN_URL}'.");
        }
        public async Task GetTermsOfServiceAsync_WithEmptyGuid_ReturnsBadRequest()
        {
            // Arrange
            var controller = new TermsOfServiceController(termsOfServiceService, orderByHelper, paginationHelper, mapper);

            // Act
            var result = await controller.GetTermsOfServiceAsync(Guid.Empty);

            // Assert
            var badRequestResult = result as BadRequestResult;

            Assert.NotNull(badRequestResult);
        }
        public async Task DeleteTermsOfServiceAsync_WithGuid_ReturnsNoContent()
        {
            // Arrange
            var controller = new TermsOfServiceController(termsOfServiceService, orderByHelper, paginationHelper, mapper);

            // Act
            IActionResult actionResult = await controller.DeleteTermsOfServiceAsync(Guid.NewGuid());

            // Assert
            var noContentResult = actionResult as NoContentResult;

            Assert.NotNull(noContentResult);
        }
        public async Task Index_PostExecutedWithInvalidUserContext_ThrowsAuthenticationException()
        {
            //Arrange
            var id = Guid.NewGuid().ToString();

            using var termsOfServiceController = new TermsOfServiceController(fakeUserManager, termsOfServiceRepository, mockConfiguration, mockIdentityServerInteractionService,
                                                                              mockEventService, mockClientStore, fakeSignInManager)
                  {
                      ControllerContext = new ControllerContext()
                      {
                          HttpContext = new DefaultHttpContext()
                          {
                              User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
                        {
                            new Claim(ClaimTypes.Name, "example name"),
                            new Claim(ClaimTypes.NameIdentifier, id),
                            new Claim("sub", id),
                            new Claim("custom-claim", "example claim value"),
                        }, "mock")),
                          }
                      }
                  };

            fakeUserManager.SetUserModel(null);

            var termOfServiceId          = Guid.NewGuid();
            var termsOfServiceInputModel = new TermsOfServiceInputModel()
            {
                Accepted = true,
                InitialAgreementCount = 3,
                ReturnUrl             = RETURN_URL,
                TermsOfServiceId      = termOfServiceId
            };

            Exception caughtException = null;

            try
            {
                var actionResult = await termsOfServiceController.Index(termsOfServiceInputModel, "accept", RETURN_URL);
            }
            catch (Exception ex)
            {
                caughtException = ex;
            }

            // Assert
            Assert.True(caughtException is AuthenticationException, "Invalid login data must throw an AuthenticationException.");
        }
        public async Task Index_PostExecutedWithAcceptedTermsOfService_ViewResultReturned()
        {
            //Arrange
            var id = Guid.NewGuid().ToString();

            using var termsOfServiceController = new TermsOfServiceController(fakeUserManager, termsOfServiceRepository, mockConfiguration, mockIdentityServerInteractionService,
                                                                              mockEventService, mockClientStore, fakeSignInManager)
                  {
                      ControllerContext = new ControllerContext()
                      {
                          HttpContext = new DefaultHttpContext()
                          {
                              User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
                        {
                            new Claim(ClaimTypes.Name, "example name"),
                            new Claim(ClaimTypes.NameIdentifier, id),
                            new Claim("sub", id),
                            new Claim("custom-claim", "example claim value"),
                        }, "mock")),
                          }
                      }
                  };

            fakeUserManager.SetUserModel(userModel);

            var termOfServiceId          = Guid.NewGuid();
            var termsOfServiceInputModel = new TermsOfServiceInputModel()
            {
                Accepted = true,
                InitialAgreementCount = 3,
                ReturnUrl             = RETURN_URL,
                TermsOfServiceId      = termOfServiceId
            };

            // Act
            var actionResult = await termsOfServiceController.Index(termsOfServiceInputModel, "accept", RETURN_URL);

            // Assert
            var viewResult = actionResult as RedirectToActionResult;

            Assert.NotNull(viewResult);
            Assert.True(viewResult.ActionName == "Index", "Redirect action must be 'Index'.");
            Assert.True(viewResult.RouteValues.Count == 2, "Route value count must be 2.");
            Assert.True(viewResult.RouteValues["returnUrl"].ToString() == RETURN_URL, $"Route value 'returnUrl' must be '{RETURN_URL}'.");
            Assert.True(viewResult.RouteValues["initialAgreementCount"].ToString() == "3", $"Route value 'returnUrl' must be '3'.");
        }
        public async Task Index_ExecutedWithOutstandingAgreementsButUnfindableAgreementGuid_ThrowsItemNotFoundException()
        {
            //Arrange
            var id = Guid.NewGuid().ToString();

            using var termsOfServiceController = new TermsOfServiceController(fakeUserManager, termsOfServiceRepository, mockConfiguration, mockIdentityServerInteractionService,
                                                                              mockEventService, mockClientStore, fakeSignInManager)
                  {
                      ControllerContext = new ControllerContext()
                      {
                          HttpContext = new DefaultHttpContext()
                          {
                              User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
                        {
                            new Claim(ClaimTypes.Name, "example name"),
                            new Claim(ClaimTypes.NameIdentifier, id),
                            new Claim("sub", id),
                            new Claim("custom-claim", "example claim value"),
                        }, "mock")),
                          }
                      }
                  };

            fakeUserManager.SetUserModel(userModel);
            termsOfServiceRepository.GetAllOutstandingAgreementsByUserAsync(Arg.Any <Guid>())
            .Returns(new List <Guid>()
            {
                Guid.NewGuid(),
                Guid.NewGuid()
            });

            // Act
            Exception caughtException = null;

            try
            {
                var actionResult = await termsOfServiceController.Index(RETURN_URL, 0);
            }
            catch (Exception ex)
            {
                caughtException = ex;
            }

            // Assert
            Assert.True(caughtException is ItemNotFoundException, "Caught exception must be sItemNotFoundException.");
        }
        public async Task Index_ExecutedWithOutstandingAgreements_ViewResultReturned()
        {
            //Arrange
            var id = Guid.NewGuid().ToString();

            using var termsOfServiceController = new TermsOfServiceController(fakeUserManager, termsOfServiceRepository, mockConfiguration, mockIdentityServerInteractionService,
                                                                              mockEventService, mockClientStore, fakeSignInManager)
                  {
                      ControllerContext = new ControllerContext()
                      {
                          HttpContext = new DefaultHttpContext()
                          {
                              User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
                        {
                            new Claim(ClaimTypes.Name, "example name"),
                            new Claim(ClaimTypes.NameIdentifier, id),
                            new Claim("sub", id),
                            new Claim("custom-claim", "example claim value"),
                        }, "mock")),
                          }
                      }
                  };

            fakeUserManager.SetUserModel(userModel);
            termsOfServiceRepository.GetAllOutstandingAgreementsByUserAsync(Arg.Any <Guid>())
            .Returns(new List <Guid>()
            {
                Guid.NewGuid(),
                Guid.NewGuid()
            });

            termsOfServiceRepository.GetByIdAsync(Arg.Any <Guid>(), Arg.Any <bool>(), Arg.Any <bool>()).Returns(termsOfServiceModel);

            // Act
            var actionResult = await termsOfServiceController.Index(RETURN_URL, 0);

            // Assert
            var viewResult = actionResult as ViewResult;

            Assert.NotNull(viewResult);

            var model = viewResult.Model as TermsOfServiceViewModel;

            Assert.True(model.AgreementName == termsOfServiceModel.AgreementName, $"Model field AgreementName '{model.AgreementName}' should be '{termsOfServiceModel.AgreementName}'.");
            Assert.True(model.AgreementCount == 2, $"Model field AgreementCount '{model.AgreementCount}' should be '2'.");
        }
        public async Task ListTermsOfServicesAsync_WithNoInputs_ReturnsList()
        {
            // Arrange
            var inList = new List <TermsOfServiceModel>
            {
                new TermsOfServiceModel {
                    AgreementName = "Test TermsOfServices 1", Id = Guid.NewGuid()
                },
                new TermsOfServiceModel {
                    AgreementName = "Test TermsOfServices 2", Id = Guid.NewGuid()
                },
                new TermsOfServiceModel {
                    AgreementName = "Test TermsOfServices 3", Id = Guid.NewGuid()
                }
            };

            PaginatedResult <TermsOfServiceModel> paginatedResult = new PaginatedResult <TermsOfServiceModel>
            {
                CurrentPage = 1,
                PageCount   = 1,
                PageSize    = 3,
                Results     = inList
            };

            termsOfServiceService.GetPaginatedListAsync(Arg.Any <int>(), Arg.Any <int>(), Arg.Any <bool>(), Arg.Any <string>(), Arg.Any <List <KeyValuePair <string, string> > >()).Returns(paginatedResult);
            var controller = new TermsOfServiceController(termsOfServiceService, orderByHelper, paginationHelper, mapper);

            // Act
            IActionResult actionResult = await controller.ListTermsOfServicesAsync(0, 0, true, string.Empty, string.Empty);

            // Assert
            var okResult = actionResult as OkObjectResult;

            Assert.NotNull(okResult);

            var outList = okResult.Value as List <TermsOfServiceListItem>;

            Assert.NotNull(outList);

            for (var i = 0; i < outList.Count; i++)
            {
                Assert.Equal(outList[i].Uuid, inList[i].Id);
                Assert.Equal(outList[i].AgreementName, inList[i].AgreementName);
            }
        }