public async Task <IActionResult> SearchResults([FromQuery] SearchResultsQuery searchQuery, string orderBy = "relevance") { //When never searched in this session if (string.IsNullOrWhiteSpace(SearchViewService.LastSearchParameters)) { //If no compare employers in session then load employers from the cookie if (CompareViewService.BasketItemCount == 0) { CompareViewService.LoadComparedEmployersFromCookie(); } } //Clear the default back url of the employer hub pages EmployerBackUrl = null; ReportBackUrl = null; // ensure parameters are valid if (!searchQuery.TryValidateSearchParams(out HttpStatusViewResult result)) { return(result); } // generate result view model var searchParams = SearchResultsQueryToEmployerSearchParameters(searchQuery); SearchViewModel model = await ViewingService.SearchAsync(searchParams, orderBy); ViewBag.ReturnUrl = SearchViewService.GetLastSearchUrl(); ViewBag.BasketViewModel = new CompareBasketViewModel { CanAddEmployers = false, CanViewCompare = CompareViewService.BasketItemCount > 1, CanClearCompare = true }; return(View("Finder/SearchResults", model)); }
public virtual async Task <IHttpActionResult> AutoComplete(AutoCompleteSearchViewModel request, int limit = MAXIMUM_AUTOCOMPLETE_RESULT) { var originalSearchTerms = request.Query.Trim(); var searchTerms = SearchTermsTransformationProvider.TransformSearchTerm(originalSearchTerms, ComposerContext.CultureInfo.Name); var searchCriteria = await BaseSearchCriteriaProvider.GetSearchCriteriaAsync(searchTerms, RequestUtils.GetBaseUrl(Request).ToString(), false).ConfigureAwait(false); searchCriteria.NumberOfItemsPerPage = limit; var searchResultsViewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false); if (searchResultsViewModel.ProductSearchResults?.TotalCount == 0 && originalSearchTerms != searchTerms) { searchCriteria.Keywords = originalSearchTerms; searchResultsViewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false); } var vm = new AutoCompleteViewModel() { Suggestions = new List <ProductSearchViewModel>() }; if (searchResultsViewModel.ProductSearchResults?.SearchResults?.Count > 0) { vm.Suggestions = searchResultsViewModel.ProductSearchResults.SearchResults.Take(limit) .Select(p => { p.SearchTerm = searchTerms; return(p); }) .ToList(); } return(Ok(vm)); }
public virtual async Task <IHttpActionResult> SuggestCategories(AutoCompleteSearchViewModel request, int limit = MAXIMUM_CATEGORIES_SUGGESTIONS) { string language = ComposerContext.CultureInfo.Name; string searchTerm = request.Query.Trim().ToLower(); List <Category> categories = await SearchViewService.GetAllCategories(); List <Facet> categoryCounts = await SearchViewService.GetCategoryProductCounts(language); List <CategorySuggestionViewModel> categorySuggestionList = new List <CategorySuggestionViewModel>(); foreach (var category in categories) { if (!category.DisplayName.TryGetValue(language, out string displayName)) { continue; } // Find the parents of the category List <Category> parents = new List <Category>(); Category currentNode = category; while (!string.IsNullOrWhiteSpace(currentNode.PrimaryParentCategoryId) && currentNode.PrimaryParentCategoryId != RootCategoryId) { Category parent = categories.Single((cat) => cat.Id == currentNode.PrimaryParentCategoryId); parents.Add(parent); currentNode = parent; } parents.Reverse(); FacetValue categoryCount = categoryCounts .Where((facet) => int.TryParse(CategoryFieldName.Match(facet.FieldName).Groups[1].Value, out int n) && parents.Count == n - 1) .FirstOrDefault()? .Values .Where((facetValue) => facetValue.Value == category.DisplayName[language]).SingleOrDefault(); if (categoryCount != null) { categorySuggestionList.Add(new CategorySuggestionViewModel { DisplayName = displayName, Parents = parents.Select((parent) => parent.DisplayName[language]).ToList(), Quantity = categoryCount.Count }); } } ; List <CategorySuggestionViewModel> finalSuggestions = categorySuggestionList .OrderByDescending((category) => category.Quantity) .Where((suggestion) => suggestion.DisplayName.ToLower().Contains(searchTerm)) .Take(limit) .ToList(); CategorySuggestionsViewModel vm = new CategorySuggestionsViewModel { Suggestions = finalSuggestions }; return(Ok(vm)); }
public async Task WHEN_one_selected_facet_SHOULD_facets_count_should_be_1() { // Arrange SearchViewService service = _container.CreateInstance <SearchViewService>(); var facetName = GetRandom.String(5); SetupFacets(new FacetSetting(facetName)); // Act SearchViewModel model = await service.GetSearchViewModelAsync(new SearchCriteria { Keywords = "any", CultureInfo = new CultureInfo(CultureName), Scope = Scope, SelectedFacets = { new Composer.Parameters.SearchFilter { Name = facetName } } }); // Assert model.SelectedFacets.Facets.Count.Should().Be(1); }
public void WHEN_param_is_null_SHOULD_throw_argument_null_exception() { // Arrange SearchViewService service = _container.CreateInstance <SearchViewService>(); // Act & Assert Assert.ThrowsAsync <ArgumentNullException>(() => service.GetSearchViewModelAsync(null)); }
public virtual async Task <PageHeaderViewModel> GetPageHeaderViewModelAsync(GetPageHeaderParam param) { if (param == null) { throw new ArgumentNullException(nameof(param)); } return(await SearchViewService.GetPageHeaderViewModelAsync(param).ConfigureAwait(false)); }
public void WHEN_scope_is_empty_SHOULD_throw_argument_exception() { // Arrange SearchViewService service = _container.CreateInstance <SearchViewService>(); // Act & Assert Assert.ThrowsAsync <ArgumentException>(() => service.GetSearchViewModelAsync( new SearchCriteria { Keywords = "any", CultureInfo = new CultureInfo(CultureName), Scope = string.Empty } )); }
public void WHEN_culture_info_is_null_SHOULD_throw_argument_exception() { // Arrange SearchViewService service = _container.CreateInstance <SearchViewService>(); // Act & Assert Assert.ThrowsAsync <ArgumentException>(() => service.GetSearchViewModelAsync( new SearchCriteria { Keywords = "any", CultureInfo = null, Scope = "global" } )); }
public async Task WHEN_keywords_is_not_null_or_whitespace_SHOULD_returned_model_contain_keywords() { // Arrange SearchViewService service = _container.CreateInstance <SearchViewService>(); // Act SearchViewModel model = await service.GetSearchViewModelAsync(new SearchCriteria { Keywords = "any", CultureInfo = new CultureInfo(CultureName), Scope = Scope }); // Assert model.Keywords.Should().Be("any"); }
public async Task WHEN_keywords_is_empty_SHOULD_return_no_product() { // Arrange SearchViewService service = _container.CreateInstance <SearchViewService>(); // Act var model = await service.GetSearchViewModelAsync(new SearchCriteria { Keywords = string.Empty, CultureInfo = new CultureInfo(CultureName), Scope = Scope }); //Assert model.ProductSearchResults.TotalCount.Should().Be(0); }
public virtual async Task <IHttpActionResult> GetFacets(GetFacetsRequest request) { var queryString = HttpUtility.ParseQueryString(request.QueryString); var searchCriteria = await BaseSearchCriteriaProvider.GetSearchCriteriaAsync(queryString["keywords"], RequestUtils.GetBaseUrl(Request).ToString(), true).ConfigureAwait(false); searchCriteria.NumberOfItemsPerPage = 0; searchCriteria.SelectedFacets.AddRange(SearchUrlProvider.BuildSelectedFacets(queryString)); var searchResultsViewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false); searchResultsViewModel.ProductSearchResults.Facets = searchResultsViewModel.ProductSearchResults.Facets.Where(f => !f.FieldName.StartsWith(SearchConfiguration.CategoryFacetFiledNamePrefix)).ToList(); return(Ok(searchResultsViewModel)); }
public SearchRequestContext( ISearchViewService searchViewService, ISearchUrlProvider searchUrlProvider, HttpRequestBase request, IBaseSearchCriteriaProvider baseSearchCriteriaProvider) { SearchViewService = searchViewService ?? throw new ArgumentNullException(nameof(searchViewService)); SearchUrlProvider = searchUrlProvider ?? throw new ArgumentNullException(nameof(searchUrlProvider)); Request = request; BaseSearchCriteriaProvider = baseSearchCriteriaProvider ?? throw new ArgumentNullException(nameof(baseSearchCriteriaProvider)); _viewModel = new Lazy <SearchViewModel>(() => { var criteria = BuildProductsSearchCriteria(); return(SearchViewService.GetSearchViewModelAsync(criteria).Result); }); }
public async Task WHEN_no_selected_facet_SHOULD_returned_model_contain_no_facet() { // Arrange SearchViewService service = _container.CreateInstance <SearchViewService>(); // Act SearchViewModel model = await service.GetSearchViewModelAsync(new SearchCriteria { Keywords = "any", CultureInfo = new CultureInfo(CultureName), Scope = Scope, SelectedFacets = { } }); // Assert model.SelectedFacets.Facets.Count.Should().Be(0); }
public SearchRequestContext(IComposerContext composerContext, ISearchViewService searchViewService, IInventoryLocationProvider inventoryLocationProvider, ISearchUrlProvider searchUrlProvider, HttpRequestBase request) { ComposerContext = composerContext ?? throw new ArgumentNullException(nameof(composerContext)); SearchViewService = searchViewService ?? throw new ArgumentNullException(nameof(searchViewService)); InventoryLocationProvider = inventoryLocationProvider ?? throw new ArgumentNullException(nameof(inventoryLocationProvider)); SearchUrlProvider = searchUrlProvider ?? throw new ArgumentNullException(nameof(searchUrlProvider)); Request = request; _viewModel = new Lazy <SearchViewModel>(() => { var criteria = BuildProductsSearchCriteria(); return(SearchViewService.GetSearchViewModelAsync(criteria).Result); }); }
public virtual async Task <IHttpActionResult> GetSearchResults(GetSearchResultsRequest request) { var queryString = HttpUtility.ParseQueryString(request.QueryString ?? ""); var SelectedFacets = SearchUrlProvider.BuildSelectedFacets(queryString).ToList(); var CurrentPage = int.TryParse(queryString[SearchRequestParams.Page], out int page) && page > 0 ? page : 1; var SortDirection = queryString[SearchRequestParams.SortDirection] ?? SearchRequestParams.DefaultSortDirection; var SortBy = queryString[SearchRequestParams.SortBy] ?? SearchRequestParams.DefaultSortBy; var BaseUrl = RequestUtils.GetBaseUrl(Request).ToString(); var Keywords = queryString[SearchRequestParams.Keywords]; BaseSearchViewModel viewModel; if (!string.IsNullOrEmpty(request.CategoryId)) { var param = new GetCategoryBrowsingViewModelParam { CategoryId = request.CategoryId, CategoryName = string.Empty, BaseUrl = BaseUrl, IsAllProducts = false, NumberOfItemsPerPage = SearchConfiguration.MaxItemsPerPage, Page = CurrentPage, SortBy = SortBy, SortDirection = SortDirection, InventoryLocationIds = await InventoryLocationProvider.GetInventoryLocationIdsForSearchAsync().ConfigureAwait(false), SelectedFacets = SelectedFacets, CultureInfo = ComposerContext.CultureInfo, }; viewModel = await CategoryBrowsingViewService.GetCategoryBrowsingViewModelAsync(param).ConfigureAwait(false); } else { var searchCriteria = await BaseSearchCriteriaProvider.GetSearchCriteriaAsync(Keywords, BaseUrl, true, CurrentPage).ConfigureAwait(false); searchCriteria.SortBy = SortBy; searchCriteria.SortDirection = SortDirection; searchCriteria.SelectedFacets.AddRange(SelectedFacets); viewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false); } viewModel.ProductSearchResults.Facets = viewModel.ProductSearchResults.Facets.Where(f => !f.FieldName.StartsWith(SearchConfiguration.CategoryFacetFiledNamePrefix)).ToList(); return(Ok(viewModel)); }
public virtual async Task <IHttpActionResult> AutoComplete(AutoCompleteSearchViewModel request, int limit = MAXIMUM_AUTOCOMPLETE_RESULT) { var originalSearchTerms = request.Query.Trim(); var searchTerms = SearchTermsTransformationProvider.TransformSearchTerm(originalSearchTerms, ComposerContext.CultureInfo.Name);; var searchCriteria = new SearchCriteria { Keywords = searchTerms, NumberOfItemsPerPage = limit, IncludeFacets = false, StartingIndex = 0, SortBy = "score", SortDirection = "desc", Page = 1, BaseUrl = RequestUtils.GetBaseUrl(Request).ToString(), Scope = ComposerContext.Scope, CultureInfo = ComposerContext.CultureInfo, InventoryLocationIds = await InventoryLocationProvider.GetInventoryLocationIdsForSearchAsync().ConfigureAwait(false), }; var searchResultsViewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false); if (searchResultsViewModel.ProductSearchResults?.TotalCount == 0 && originalSearchTerms != searchTerms) { searchCriteria.Keywords = originalSearchTerms; searchResultsViewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false); } var vm = new AutoCompleteViewModel() { Suggestions = new List <ProductSearchViewModel>() }; if (searchResultsViewModel.ProductSearchResults?.SearchResults?.Count > 0) { vm.Suggestions = searchResultsViewModel.ProductSearchResults.SearchResults.Take(limit) .Select(p => { p.SearchTerm = searchTerms; return(p); }) .ToList(); } return(Ok(vm)); }
public async Task WHEN_one_selected_facet_SHOULD_facets_are_not_all_removable() { // Arrange SearchViewService service = _container.CreateInstance <SearchViewService>(); // Act SearchViewModel model = await service.GetSearchViewModelAsync(new SearchCriteria { Keywords = "any", CultureInfo = new CultureInfo(CultureName), Scope = Scope, SelectedFacets = { new Composer.Parameters.SearchFilter() } }); // Assert model.SelectedFacets.IsAllRemovable.Should().BeFalse(); }
public virtual async Task <IHttpActionResult> GetSearchResultsBySkus(GetSearchResultsBySkusRequest request) { if (request.Skus == null) { return(BadRequest($"{nameof(request.Skus)} cannot be empty")); } var queryString = HttpUtility.ParseQueryString(request.QueryString ?? ""); var SelectedFacets = SearchUrlProvider.BuildSelectedFacets(queryString).ToList(); var Keywords = queryString[SearchRequestParams.Keywords]; var BaseUrl = RequestUtils.GetBaseUrl(Request).ToString(); var IncludeFactes = request.IncludeFacets; var searchCriteria = await BaseSearchCriteriaProvider.GetSearchCriteriaAsync(Keywords, BaseUrl, IncludeFactes).ConfigureAwait(false); var searchBySkusCriteria = new SearchBySkusCriteria { Skus = request.Skus, Keywords = searchCriteria.Keywords, NumberOfItemsPerPage = request.Skus.Length, StartingIndex = searchCriteria.StartingIndex, Page = searchCriteria.Page, BaseUrl = searchCriteria.BaseUrl, Scope = searchCriteria.Scope, CultureInfo = searchCriteria.CultureInfo, InventoryLocationIds = searchCriteria.InventoryLocationIds, AvailabilityDate = searchCriteria.AvailabilityDate, IncludeFacets = searchCriteria.IncludeFacets }; searchBySkusCriteria.SelectedFacets.AddRange(SelectedFacets); var viewModel = await SearchViewService.GetSearchViewModelAsync(searchBySkusCriteria).ConfigureAwait(false); if (IncludeFactes) { viewModel.ProductSearchResults.Facets = viewModel.ProductSearchResults.Facets.Where(f => !f.FieldName.StartsWith(SearchConfiguration.CategoryFacetFiledNamePrefix)).ToList(); } return(Ok(viewModel)); }
public virtual async Task <IHttpActionResult> SuggestBrands(AutoCompleteSearchViewModel request, int limit = MAXIMUM_BRAND_SUGGESTIONS) { string searchTerm = request.Query.Trim().ToLower(); List <Facet> facets = await SearchViewService.GetBrandProductCounts(ComposerContext.CultureInfo.Name).ConfigureAwait(false); List <BrandSuggestionViewModel> brandList = facets.Single().Values.Select(facetValue => new BrandSuggestionViewModel { DisplayName = facetValue.DisplayName }).ToList(); BrandSuggestionsViewModel vm = new BrandSuggestionsViewModel() { Suggestions = brandList .Where((suggestion) => suggestion.DisplayName.ToLower().Contains(searchTerm)) .OrderBy(x => x.DisplayName) .Take(limit).ToList() }; return(Ok(vm)); }
// used to generate suggestions for the search on the landing page public async Task <IActionResult> SearchResultsJs([FromQuery] SearchResultsQuery searchQuery) { //Clear the default back url of the employer hub pages EmployerBackUrl = null; ReportBackUrl = null; // ensure parameters are valid if (!searchQuery.TryValidateSearchParams(out HttpStatusViewResult result)) { return(result); } // generate result view model var searchParams = SearchResultsQueryToEmployerSearchParameters(searchQuery); SearchViewModel model = await ViewingService.SearchAsync(searchParams, "relevance"); ViewBag.ReturnUrl = SearchViewService.GetLastSearchUrl(); return(PartialView("Finder/Parts/MainContent", model)); }
public IActionResult Employer(string employerIdentifier) { if (string.IsNullOrWhiteSpace(employerIdentifier)) { return(new HttpBadRequestResult("Missing employer identifier")); } CustomResult <Organisation> organisationLoadingOutcome; try { organisationLoadingOutcome = OrganisationBusinessLogic.LoadInfoFromActiveEmployerIdentifier(employerIdentifier); if (organisationLoadingOutcome.Failed) { return(organisationLoadingOutcome.ErrorMessage.ToHttpStatusViewResult()); } } catch (Exception ex) { CustomLogger.Error($"Cannot decrypt return employerIdentifier from '{employerIdentifier}'", ex); return(View("CustomError", new ErrorViewModel(400))); } //Clear the default back url of the report page ReportBackUrl = null; ViewBag.BasketViewModel = new CompareBasketViewModel { CanAddEmployers = true, CanViewCompare = true }; return(View( "EmployerDetails/Employer", new EmployerDetailsViewModel { Organisation = organisationLoadingOutcome.Result, LastSearchUrl = SearchViewService.GetLastSearchUrl(), EmployerBackUrl = EmployerBackUrl, ComparedEmployers = CompareViewService.ComparedEmployers.Value })); }
public async Task <IActionResult> Step1Task2([FromQuery] SearchResultsQuery searchQuery, string orderBy = "relevance") { if (FeatureFlagHelper.IsFeatureEnabled(FeatureFlag.ReportingStepByStep)) { //When never searched in this session if (string.IsNullOrWhiteSpace(SearchViewService.LastSearchParameters)) { //If no compare employers in session then load employers from the cookie if (CompareViewService.BasketItemCount == 0) { CompareViewService.LoadComparedEmployersFromCookie(); } } // ensure parameters are valid if (!searchQuery.TryValidateSearchParams(out HttpStatusViewResult result)) { return(result); } // generate result view model var searchParams = SearchResultsQueryToEmployerSearchParameters(searchQuery); SearchViewModel model = await ViewingService.SearchAsync(searchParams, orderBy); ViewBag.ReturnUrl = SearchViewService.GetLastSearchUrl(); ViewBag.BasketViewModel = new CompareBasketViewModel { CanAddEmployers = false, CanViewCompare = CompareViewService.BasketItemCount > 1, CanClearCompare = true }; return(View("../ReportingStepByStep/Step1Task2", model)); } else { return(new HttpNotFoundResult()); } }
public IActionResult CompareEmployers(int year, string employers = null) { if (year == 0) { CompareViewService.SortColumn = null; CompareViewService.SortAscending = true; year = ReportingYearsHelper.GetTheMostRecentCompletedReportingYear(); } //Load employers from querystring (via shared email) if (!string.IsNullOrWhiteSpace(employers)) { string[] comparedEmployers = employers.SplitI("-"); if (comparedEmployers.Any()) { CompareViewService.ClearBasket(); CompareViewService.AddRangeToBasket(comparedEmployers); CompareViewService.SortAscending = true; CompareViewService.SortColumn = null; return(RedirectToAction("CompareEmployers", new { year })); } } //If the session is lost then load employers from the cookie else if (CompareViewService.BasketItemCount == 0) { CompareViewService.LoadComparedEmployersFromCookie(); } ViewBag.ReturnUrl = Url.Action("CompareEmployers", new { year }); //Clear the default back url of the employer hub pages EmployerBackUrl = null; ReportBackUrl = null; //Get the compare basket organisations IEnumerable <CompareReportModel> compareReports = OrganisationBusinessLogic.GetCompareData( CompareViewService.ComparedEmployers.Value.AsEnumerable(), year, CompareViewService.SortColumn, CompareViewService.SortAscending); //Track the compared employers string lastComparedEmployerList = CompareViewService.ComparedEmployers.Value.ToList().ToSortedSet().ToDelimitedString(); if (CompareViewService.LastComparedEmployerList != lastComparedEmployerList && IsAction("CompareEmployers")) { SortedSet <string> employerIds = compareReports.Select(r => r.EncOrganisationId).ToSortedSet(); WebTracker.TrackPageView( this, $"compare-employers: {employerIds.ToDelimitedString()}", $"{ViewBag.ReturnUrl}?{employerIds.ToEncapsulatedString("e=", null, "&", "&", false)}"); foreach (CompareReportModel employer in compareReports) { WebTracker.TrackPageView( this, $"{employer.EncOrganisationId}: {employer.OrganisationName}", $"{ViewBag.ReturnUrl}?{employer.EncOrganisationId}={employer.OrganisationName}"); } CompareViewService.LastComparedEmployerList = lastComparedEmployerList; } //Generate the shared links string shareEmailUrl = Url.Action( nameof(CompareEmployers), "Compare", new { year, employers = CompareViewService.ComparedEmployers.Value.ToList().ToDelimitedString("-") }, Request.Scheme); ViewBag.BasketViewModel = new CompareBasketViewModel { CanAddEmployers = true, CanViewCompare = false, CanClearCompare = true }; return(View( "CompareEmployers", new CompareViewModel { LastSearchUrl = SearchViewService.GetLastSearchUrl(), CompareReports = compareReports, CompareBasketCount = CompareViewService.BasketItemCount, ShareEmailUrl = CompareViewService.BasketItemCount <= CompareViewService.MaxCompareBasketShareCount ? shareEmailUrl : null, Year = year, SortAscending = CompareViewService.SortAscending, SortColumn = CompareViewService.SortColumn })); }