public void ShouldReturnBadRequestIfTheUrlIsinvalidFormatlInRequest(SearchWidgetPageMode mode, string jobProfileUrl, HttpStatusCode expectation) { //Arrange var webAppContext = new WebAppContext(); // OUR SERVICE TYPE var searchQuery = A.Fake <ISearchQueryService <JobProfileIndex> >(); var mapper = A.Fake <IMapper>(); var applicationLogger = A.Fake <IApplicationLogger>(); var spellcheckerServiceFake = A.Fake <ISpellcheckService>(ops => ops.Strict()); var fakeAsyncHelper = new AsyncHelper(); var controller = new JobProfileSearchBoxController(searchQuery, webAppContext, mapper, applicationLogger, fakeAsyncHelper, spellcheckerServiceFake) { CurrentPageMode = mode }; switch (expectation) { case HttpStatusCode.NotFound: controller.WithCallTo(c => c.Search(string.Empty, jobProfileUrl)).ShouldGiveHttpStatus(expectation); break; case HttpStatusCode.Redirect: default: controller.WithCallTo(c => c.Search(string.Empty, jobProfileUrl)).ShouldRedirectTo($"{controller.JobProfileDetailsPage}{jobProfileUrl}"); break; } }
public void SearchTest(string searchTerm, SearchWidgetPageMode mode, string jobProfileUrl) { //Setup Fakes & dummies var serviceFake = A.Fake <ISearchQueryService <JobProfileIndex> >(ops => ops.Strict()); var loggerFake = A.Fake <IApplicationLogger>(); var spellcheckerServiceFake = A.Fake <ISpellcheckService>(ops => ops.Strict()); var fakeAsyncHelper = new AsyncHelper(); var webAppContext = A.Fake <IWebAppContext>(ops => ops.Strict()); var mapperCfg = new MapperConfiguration(cfg => { cfg.AddProfile <JobProfilesAutoMapperProfile>(); }); A.CallTo(() => webAppContext.IsValidAndFormattedUrl(A <string> ._)).Returns(true); //Instantiate var searchController = new JobProfileSearchBoxController(serviceFake, webAppContext, mapperCfg.CreateMapper(), loggerFake, fakeAsyncHelper, spellcheckerServiceFake) { CurrentPageMode = mode }; //Act var searchMethodCall = searchController.WithCallTo(c => c.Search(searchTerm, jobProfileUrl)); if (string.IsNullOrWhiteSpace(searchTerm)) { if (mode == SearchWidgetPageMode.Landing) { //Assert searchMethodCall .ShouldRenderView("Index") //this is not default for this action .WithModel <JobProfileSearchBoxViewModel>(vm => string.IsNullOrWhiteSpace(vm.PlaceholderText) == false); } else if (mode == SearchWidgetPageMode.SearchResults) { //Assert searchMethodCall .ShouldRenderView("SearchResult") .WithModel <JobProfileSearchResultViewModel>(vm => string.IsNullOrWhiteSpace(vm.PlaceholderText) == false); } else { //Assert searchMethodCall .ShouldRedirectTo($"{searchController.JobProfileDetailsPage}{jobProfileUrl}"); } } else { //Assert searchMethodCall .ShouldRedirectTo($"{searchController.SearchResultsPage}?searchTerm={searchTerm}"); } A.CallTo(() => serviceFake.Search(A <string> ._, A <SearchProperties> ._)).MustNotHaveHappened(); }
public void IndexTest(string searchTerm, SearchWidgetPageMode mode, int page = 1) { //Setup Fakes & dummies var serviceFake = A.Fake <ISearchQueryService <JobProfileIndex> >(ops => ops.Strict()); var loggerFake = A.Fake <IApplicationLogger>(); var webAppContext = A.Fake <IWebAppContext>(ops => ops.Strict()); var defaultJobProfilePage = "/jobprofile-details/"; var expectedTotalMessage = string.IsNullOrWhiteSpace(searchTerm) ? null : "0 results found - try again using a different job title"; var spellcheckerServiceFake = A.Fake <ISpellcheckService>(); var fakeAsyncHelper = new AsyncHelper(); var mapperCfg = new MapperConfiguration(cfg => { cfg.AddProfile <JobProfilesAutoMapperProfile>(); }); var expectedSearchResultsViewModel = Enumerable.Empty <JobProfileSearchResultItemViewModel>(); var dummySearchResult = A.Dummy <SearchResult <JobProfileIndex> >(); if (string.IsNullOrWhiteSpace(searchTerm)) { dummySearchResult.Results = Enumerable.Empty <SearchResultItem <JobProfileIndex> >(); dummySearchResult.Count = 0; } else { var dummyIndex = new JobProfileIndex { Title = searchTerm, AlternativeTitle = new[] { "alt" }, SalaryStarter = 10, SalaryExperienced = 10, Overview = "overview", UrlName = "dummy-url", JobProfileCategoriesWithUrl = new[] { "CatOneURL|Cat One", "CatTwoURL|Cat Two" } }; dummySearchResult.Count = 1; expectedTotalMessage = "1 result found"; dummySearchResult.Results = A.CollectionOfDummy <SearchResultItem <JobProfileIndex> >(1); dummySearchResult.Results.First().ResultItem = dummyIndex; expectedSearchResultsViewModel = new List <JobProfileSearchResultItemViewModel> { new JobProfileSearchResultItemViewModel { ResultItemTitle = dummyIndex.Title, ResultItemAlternativeTitle = string.Join(", ", dummyIndex.AlternativeTitle).Trim().TrimEnd(','), ResultItemSalaryRange = string.Format(new CultureInfo("en-GB", false), "{0:C0} to {1:C0}", dummyIndex.SalaryStarter, dummyIndex.SalaryExperienced), ResultItemOverview = dummyIndex.Overview, ResultItemUrlName = $"{defaultJobProfilePage}{dummyIndex.UrlName}", Rank = (int)dummySearchResult.Results.First().Rank, Score = dummySearchResult.Results.First().Score, JobProfileCategoriesWithUrl = dummyIndex.JobProfileCategoriesWithUrl } }.AsEnumerable(); } //Set-up calls A.CallTo(() => serviceFake.SearchAsync(A <string> ._, A <SearchProperties> ._)).Returns(dummySearchResult); //Instantiate var searchController = new JobProfileSearchBoxController(serviceFake, webAppContext, mapperCfg.CreateMapper(), loggerFake, fakeAsyncHelper, spellcheckerServiceFake) { CurrentPageMode = mode, JobProfileDetailsPage = defaultJobProfilePage }; //Act var searchMethodCall = searchController.WithCallTo(c => c.Index(searchTerm, page)); if (mode == SearchWidgetPageMode.SearchResults) { //Assert searchMethodCall .ShouldRenderView("SearchResult") .WithModel <JobProfileSearchResultViewModel>(vm => { vm.SearchTerm.Should().BeEquivalentTo(searchTerm); vm.PlaceholderText.Should().NotBeNullOrWhiteSpace(); vm.TotalResultsMessage.Should().Be(expectedTotalMessage); vm.SearchResults.Should().NotBeNull(); vm.SearchResults.Should().BeEquivalentTo(expectedSearchResultsViewModel); }) .AndNoModelErrors() ; if (string.IsNullOrWhiteSpace(searchTerm)) { A.CallTo(() => serviceFake.SearchAsync(A <string> ._, A <SearchProperties> ._)).MustNotHaveHappened(); } else { A.CallTo(() => serviceFake.SearchAsync(A <string> .That.Matches(m => m == searchTerm), A <SearchProperties> ._)) .MustHaveHappened(Repeated.Exactly.Once); } } else { searchMethodCall .ShouldRenderDefaultView() .WithModel <JobProfileSearchBoxViewModel>(vm => { vm.PlaceholderText.Should().NotBeNullOrWhiteSpace(); }); A.CallTo(() => serviceFake.SearchAsync(A <string> ._, A <SearchProperties> ._)).MustNotHaveHappened(); } }
public void IndexTestAutomapperAndTotalMessage(string searchTerm, SearchWidgetPageMode mode, int resultsCount, int page = 1) { //Setup Fakes & dummies var queryServiceFake = A.Fake <ISearchQueryService <JobProfileIndex> >(ops => ops.Strict()); var loggerFake = A.Fake <IApplicationLogger>(); var webAppContext = A.Fake <IWebAppContext>(ops => ops.Strict()); var defaultJobProfilePage = "/jobprofile-details/"; var expectedTotalMessage = "0 results found - try again using a different job title"; var fakeAsyncHelper = new AsyncHelper(); var fakeSpellChecker = A.Fake <ISpellcheckService>(); var mapperCfg = new MapperConfiguration(cfg => { cfg.AddProfile <JobProfilesAutoMapperProfile>(); }); var expectedSearchResultsViewModel = Enumerable.Empty <JobProfileSearchResultItemViewModel>(); var dummySearchResult = A.Dummy <SearchResult <JobProfileIndex> >(); if (string.IsNullOrWhiteSpace(searchTerm)) { dummySearchResult.Results = Enumerable.Empty <SearchResultItem <JobProfileIndex> >(); dummySearchResult.Count = 0; } else { var dummyIndex = new JobProfileIndex { Title = searchTerm, AlternativeTitle = new[] { "alt" }, SalaryStarter = 10, SalaryExperienced = 10, Overview = "overview", UrlName = "dummy-url" }; dummySearchResult.Count = resultsCount; expectedTotalMessage = $"{resultsCount} result{(resultsCount == 1 ? string.Empty : "s")} found"; dummySearchResult.Results = A.CollectionOfDummy <SearchResultItem <JobProfileIndex> >(resultsCount); var rawResultItems = new List <SearchResultItem <JobProfileIndex> >(); for (int i = 0; i < resultsCount; i++) { rawResultItems.Add(new SearchResultItem <JobProfileIndex> { ResultItem = dummyIndex }); } dummySearchResult.Results = rawResultItems; var expectedSearchResultsRawViewModel = new List <JobProfileSearchResultItemViewModel>(); foreach (var dummyIndexItem in dummySearchResult.Results) { expectedSearchResultsRawViewModel.Add(new JobProfileSearchResultItemViewModel { ResultItemTitle = dummyIndexItem.ResultItem.Title, ResultItemAlternativeTitle = string.Join(", ", dummyIndexItem.ResultItem.AlternativeTitle).Trim().TrimEnd(','), ResultItemSalaryRange = string.Format(new CultureInfo("en-GB", false), "{0:C0} to {1:C0}", dummyIndexItem.ResultItem.SalaryStarter, dummyIndexItem.ResultItem.SalaryExperienced), ResultItemOverview = dummyIndexItem.ResultItem.Overview, ResultItemUrlName = $"{defaultJobProfilePage}{dummyIndexItem.ResultItem.UrlName}", Rank = (int)dummyIndexItem.Rank, Score = dummyIndexItem.Score, JobProfileCategoriesWithUrl = Enumerable.Empty <string>() }); } expectedSearchResultsViewModel = expectedSearchResultsRawViewModel.AsEnumerable(); } //Set-up calls A.CallTo(() => queryServiceFake.SearchAsync(A <string> ._, A <SearchProperties> ._)).Returns(dummySearchResult); //Instantiate // var searchController = new JobProfileSearchBoxController(queryServiceFake, webAppContext, mapperCfg.CreateMapper(), loggerFake) var searchController = new JobProfileSearchBoxController(queryServiceFake, webAppContext, mapperCfg.CreateMapper(), loggerFake, fakeAsyncHelper, fakeSpellChecker) { CurrentPageMode = mode, JobProfileDetailsPage = defaultJobProfilePage }; //Act var searchMethodCall = searchController.WithCallTo(c => c.Index(searchTerm, page)); //Assert searchMethodCall .ShouldRenderView("SearchResult") .WithModel <JobProfileSearchResultViewModel>(vm => { vm.TotalResultsMessage.Should().Be(expectedTotalMessage); vm.SearchResults.Should().BeEquivalentTo(expectedSearchResultsViewModel); }) .AndNoModelErrors() ; }
public void SearchResultsPaginationViewModelTest(string searchTerm, SearchWidgetPageMode mode, int resultsCount, int page, int pageSize) { //Setup Fakes & dummies var queryServiceFake = A.Fake <ISearchQueryService <JobProfileIndex> >(ops => ops.Strict()); var loggerFake = A.Fake <IApplicationLogger>(); var webAppContext = A.Fake <IWebAppContext>(ops => ops.Strict()); var defaultJobProfilePage = "/jobprofile-details/"; var defaultSearchResultsPage = "/search-result"; var defaultJobProfileCateegoryPage = "/job-categories/"; var expectedTotalMessage = "0 results found - try again using a different job title"; var placeholderText = "Enter a job title or keywords"; var salaryBlankText = "Variable"; var fakeSpellChecker = A.Fake <ISpellcheckService>(); var fakeAsyncHelper = new AsyncHelper(); var mapperCfg = new MapperConfiguration(cfg => { cfg.AddProfile <JobProfilesAutoMapperProfile>(); }); var expectedSearchResultsViewModel = Enumerable.Empty <JobProfileSearchResultItemViewModel>(); var dummySearchResult = A.Dummy <SearchResult <JobProfileIndex> >(); var expectedViewModel = new JobProfileSearchResultViewModel { TotalPages = (resultsCount + pageSize - 1) / pageSize, Count = resultsCount, SearchTerm = searchTerm, PlaceholderText = placeholderText, AutoCompleteMinimumCharacters = 2, MaximumNumberOfDisplayedSuggestions = 5, UseFuzzyAutoCompleteMatching = true, JobProfileCategoryPage = defaultJobProfileCateegoryPage, SalaryBlankText = salaryBlankText, AutoCompleteMaximumCharacters = 7 }; if (string.IsNullOrWhiteSpace(searchTerm)) { dummySearchResult.Results = Enumerable.Empty <SearchResultItem <JobProfileIndex> >(); dummySearchResult.Count = 0; } else { var currentPage = page > 0 ? page : 1; var dummyIndex = new JobProfileIndex { Title = searchTerm, AlternativeTitle = new[] { "alt" }, SalaryStarter = 10, SalaryExperienced = 10, Overview = "overview", UrlName = "dummy-url", JobProfileCategoriesWithUrl = new[] { "CatOneURL|Cat One", "CatTwoURL|Cat Two" } }; dummySearchResult.Count = resultsCount; expectedTotalMessage = $"{resultsCount} result{(resultsCount == 1 ? string.Empty : "s")} found"; expectedViewModel.TotalResultsMessage = expectedTotalMessage; if (expectedViewModel.TotalPages > 1) { expectedViewModel.PageNumber = currentPage; expectedViewModel.NextPageUrl = new Uri($"{defaultSearchResultsPage}?searchTerm={HttpUtility.UrlEncode(searchTerm)}&page={currentPage + 1}", UriKind.RelativeOrAbsolute); expectedViewModel.NextPageUrlText = $"{currentPage + 1} of {expectedViewModel.TotalPages}"; if (currentPage > 1) { expectedViewModel.PreviousPageUrl = new Uri($"{defaultSearchResultsPage}?searchTerm={HttpUtility.UrlEncode(searchTerm)}&page={currentPage - 1}", UriKind.RelativeOrAbsolute); expectedViewModel.PreviousPageUrlText = $"{currentPage - 1} of {expectedViewModel.TotalPages}"; } } expectedViewModel.PageNumber = currentPage; dummySearchResult.Results = A.CollectionOfDummy <SearchResultItem <JobProfileIndex> >(resultsCount); var rawResultItems = new List <SearchResultItem <JobProfileIndex> >(); for (int i = 0; i < resultsCount; i++) { rawResultItems.Add(new SearchResultItem <JobProfileIndex> { ResultItem = dummyIndex }); } dummySearchResult.Results = rawResultItems; var expectedSearchResultsRawViewModel = new List <JobProfileSearchResultItemViewModel>(); foreach (var dummyIndexItem in dummySearchResult.Results) { expectedSearchResultsRawViewModel.Add(new JobProfileSearchResultItemViewModel { ResultItemTitle = dummyIndexItem.ResultItem.Title, ResultItemAlternativeTitle = string.Join(", ", dummyIndexItem.ResultItem.AlternativeTitle).Trim().TrimEnd(','), ResultItemSalaryRange = string.Format(new CultureInfo("en-GB", false), "{0:C0} to {1:C0}", dummyIndexItem.ResultItem.SalaryStarter, dummyIndexItem.ResultItem.SalaryExperienced), ResultItemOverview = dummyIndexItem.ResultItem.Overview, ResultItemUrlName = $"{defaultJobProfilePage}{dummyIndexItem.ResultItem.UrlName}", Rank = (int)dummyIndexItem.Rank, Score = dummyIndexItem.Score, JobProfileCategoriesWithUrl = dummyIndexItem.ResultItem.JobProfileCategoriesWithUrl }); } expectedSearchResultsViewModel = expectedSearchResultsRawViewModel.AsEnumerable(); expectedViewModel.SearchResults = expectedSearchResultsViewModel; } //Set-up calls A.CallTo(() => queryServiceFake.SearchAsync(A <string> ._, A <SearchProperties> ._)).Returns(dummySearchResult); //Instantiate var searchController = new JobProfileSearchBoxController(queryServiceFake, webAppContext, mapperCfg.CreateMapper(), loggerFake, fakeAsyncHelper, fakeSpellChecker) { CurrentPageMode = mode, JobProfileDetailsPage = defaultJobProfilePage, PageSize = pageSize, SearchResultsPage = defaultSearchResultsPage, PlaceholderText = placeholderText }; //Act var searchMethodCall = searchController.WithCallTo(c => c.Index(searchTerm, page)); if (mode == SearchWidgetPageMode.SearchResults) { //Assert searchMethodCall .ShouldRenderView("SearchResult") .WithModel <JobProfileSearchResultViewModel>(vm => { vm.Should().BeEquivalentTo(expectedViewModel); }) .AndNoModelErrors() ; A.CallTo(() => queryServiceFake.SearchAsync(A <string> ._, A <SearchProperties> .That.Matches(m => m.Page == page && m.Count == pageSize))).MustHaveHappened(); A.CallTo(() => fakeSpellChecker.CheckSpellingAsync(A <string> ._)).MustHaveHappened(); } }