public void Init() { _reservationRepository = new Mock <IReservationRepository>(); _reservationIndexRepository = new Mock <IReservationIndexRepository>(); _ruleRepository = new Mock <IRuleRepository>(); _options = new Mock <IOptions <ReservationsConfiguration> >(); _service = new AccountReservationService( _reservationRepository.Object, _ruleRepository.Object, _options.Object, _reservationIndexRepository.Object, Mock.Of <IAccountLegalEntitiesRepository>()); _expectedSelectedFilter = new SelectedSearchFilters { CourseFilter = "Baker - Level 1", EmployerNameFilter = "Test Ltd", StartDateFilter = DateTime.Now.ToString("g") }; _reservationIndexRepository.Setup(x => x.Find( ProviderId, SearchTerm, PageNumber, PageItemNumber, It.IsAny <SelectedSearchFilters>())) .ReturnsAsync(new IndexedReservationSearchResult()); }
public async Task ThenWillFilterSearchResultsByStartDate() { //Arrange var expectedSearchTerm = "test"; var expectedProviderId = 1001; ushort pageNumber = 1; ushort pageItemSize = 2; _expectedSelectedFilters = new SelectedSearchFilters { StartDateFilter = DateTime.Now.ToString("dd/MM/yyyy") }; var queryTemplate = @"""should"": []"; var expectedQuery = @"""should"": [{""match"":{""reservationPeriod"": {""query"":""" + _expectedSelectedFilters.StartDateFilter + @""",""operator"":""and""}}}],""minimum_should_match"":1"; _mockElasticSearchQueries.Setup(x => x.FindReservationsQuery).Returns(queryTemplate); //Act await _repository.Find(expectedProviderId, expectedSearchTerm, pageNumber, pageItemSize, _expectedSelectedFilters); //Assert _mockClient.Verify(c => c.SearchAsync <StringResponse>( "test", It.Is <PostData>(pd => pd.GetRequestString().RemoveLineEndingsAndWhiteSpace().Equals(expectedQuery.RemoveLineEndingsAndWhiteSpace())), It.IsAny <SearchRequestParameters>(), It.IsAny <CancellationToken>()), Times.Once); }
public void ThenWillSayIfFiltersAreNotSelected() { //Arrange var filters = new SelectedSearchFilters(); //Act var result = filters.HasFilters; //Assert Assert.IsFalse(result); }
public void ThenWillSayIfCourseFiltersAreSelected() { //Arrange var filters = new SelectedSearchFilters { CourseFilter = "Test" }; //Act var result = filters.HasFilters; //Assert Assert.IsTrue(result); }
public void ThenWillSayIfStartDateFiltersAreSelected() { //Arrange var filters = new SelectedSearchFilters { StartDateFilter = DateTime.Now.ToString("g") }; //Act var result = filters.HasFilters; //Assert Assert.IsTrue(result); }
private async Task <ElasticResponse <ReservationIndex> > GetSearchResult( long providerId, string searchTerm, ushort pageItemCount, ushort startingDocumentIndex, string reservationIndexName, SelectedSearchFilters selectedFilters) { var request = string.IsNullOrEmpty(searchTerm) ? GetReservationsSearchString(startingDocumentIndex, pageItemCount, providerId, selectedFilters) : GetReservationsSearchString(startingDocumentIndex, pageItemCount, providerId, searchTerm, selectedFilters); _logger.LogDebug($"Searching with search term: {searchTerm}"); var jsonResponse = await _client.SearchAsync <StringResponse>(reservationIndexName, PostData.String(request)); var searchResult = JsonConvert.DeserializeObject <ElasticResponse <ReservationIndex> >(jsonResponse.Body); return(searchResult); }
private string GetReservationsSearchString( ushort startingDocumentIndex, ushort pageItemCount, long providerId, SelectedSearchFilters selectedFilters) { var query = _elasticQueries.GetAllReservationsQuery.Replace("{startingDocumentIndex}", startingDocumentIndex.ToString()); query = query.Replace("{providerId}", providerId.ToString()); query = query.Replace("{pageItemCount}", pageItemCount.ToString()); if (selectedFilters.HasFilters) { var filterClause = GetFilterSearchSubString(selectedFilters); query = query.Replace(@"""should"": []", filterClause); } query = query.Replace("{pageItemCount}", pageItemCount.ToString()); return(query); }
private string GetFilterSearchSubString(SelectedSearchFilters selectedFilters) { var filterClauseBuilder = new StringBuilder(); var minMatchValue = 0; if (!string.IsNullOrWhiteSpace(selectedFilters.CourseFilter)) { filterClauseBuilder.Append(@"{""match"" : { ""courseDescription"" : { ""query"":""" + selectedFilters.CourseFilter + @""", ""operator"":""and""}}},"); minMatchValue++; } if (!string.IsNullOrWhiteSpace(selectedFilters.EmployerNameFilter)) { filterClauseBuilder.Append(@"{""match"" : { ""accountLegalEntityName"" : { ""query"":""" + selectedFilters.EmployerNameFilter + @""", ""operator"":""and""}}},"); minMatchValue++; } if (!string.IsNullOrWhiteSpace(selectedFilters.StartDateFilter)) { filterClauseBuilder.Append(@"{""match"" : { ""reservationPeriod"" : { ""query"":""" + selectedFilters.StartDateFilter + @""", ""operator"":""and""}}},"); minMatchValue++; } var filterClause = filterClauseBuilder.ToString().TrimEnd(','); return(@"""should"": [" + filterClause + @"], ""minimum_should_match"": " + minMatchValue); }
public void Init() { _mockClient = new Mock <IElasticLowLevelClient>(); _mockElasticSearchQueries = new Mock <IElasticSearchQueries>(); _mockElasticSearchQueries.Setup(x => x.FindReservationsQuery).Returns("search"); _mockElasticSearchQueries.Setup(x => x.GetAllReservationsQuery).Returns("search"); _mockElasticSearchQueries.Setup(x => x.GetFilterValuesQuery).Returns("aggs"); _mockElasticSearchQueries.Setup(x => x.LastIndexSearchQuery).Returns("Get index"); _mockElasticSearchQueries.Setup(x => x.GetReservationCountQuery).Returns("ReservationCount"); _mockElasticSearchQueries.Setup(x => x.ReservationIndexLookupName).Returns("-reservations-index-registry"); _apiEnvironment = new ReservationsApiEnvironment("test"); _repository = new ReservationIndexRepository(_mockClient.Object, _apiEnvironment, _mockElasticSearchQueries.Object, Mock.Of <ILogger <ReservationIndexRepository> >()); _expectedSelectedFilters = new SelectedSearchFilters { CourseFilter = "Baker - Level 1", EmployerNameFilter = "Test Ltd", StartDateFilter = DateTime.Now.ToString("dd/MM/yyyy") }; var indexLookUpResponse = @"{""took"":0,""timed_out"":false,""_shards"":{""total"":1,""successful"":1,""skipped"":0,""failed"":0},""hits"":{""total"": {""value"":3,""relation"":""eq""},""max_score"":null,""hits"":[{""_index"":""local-reservations-index-registry"",""_type"":""_doc"", ""_id"":""41444ccb-9687-4d3a-b0d5-295f3c35b153"",""_score"":null,""_source"":{""id"":""41444ccb-9687-4d3a-b0d5-295f3c35b153"",""name"": ""test"",""dateCreated"":""2019-11-06T15:11:00.5385739+00:00""},""sort"":[1573053060538]}]}}"; _mockClient.Setup(c => c.SearchAsync <StringResponse>( "test-reservations-index-registry", It.IsAny <PostData>(), It.IsAny <SearchRequestParameters>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new StringResponse(indexLookUpResponse)); var aggregationResponse = @"{""took"":0,""timed_out"":false,""_shards"":{""total"":1,""successful"":1,""skipped"":0,""failed"":0}, ""hits"":{""total"":{""value"":5,""relation"":""eq""},""max_score"":null,""hits"":[]},""aggregations"": {""uniqueReservationPeriod"":{""doc_count_error_upper_bound"":0,""sum_other_doc_count"":0,""buckets"":[{""key"": ""2019-09-01 00:00:00"",""doc_count"":2},{""key"":""2019-10-01 00:00:00"",""doc_count"":2}]},""uniqueAccountLegalEntityName"": {""doc_count_error_upper_bound"":0,""sum_other_doc_count"":0,""buckets"":[{""key"":""Acme Bank"",""doc_count"":2}, {""key"":""Test Ltd"",""doc_count"":2}]},""uniqueCourseDescription"":{""doc_count_error_upper_bound"":0, ""sum_other_doc_count"":0,""buckets"":[{""key"":""Baker - Level 1"",""doc_count"":4},{""key"":""Banking - Level 2"",""doc_count"":2}]}}}"; _mockClient.Setup(c => c.SearchAsync <StringResponse>( "test", It.Is <PostData>(pd => pd.GetRequestString().Contains("aggs")), It.IsAny <SearchRequestParameters>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new StringResponse(aggregationResponse)); var searchReponse = @"{""took"":33,""timed_out"":false,""_shards"":{""total"":1,""successful"":1,""skipped"":0,""failed"":0}, ""hits"":{""total"":{""value"":3,""relation"":""eq""},""max_score"":null,""hits"":[{""_index"": ""local-reservations-84ede7a8-20da-4d17-b273-ae76c377550f"",""_type"":""_doc"",""_id"": ""2_11_dd7a05b5-7252-44c7-b411-24b92e226977"",""_score"":null,""_source"":{""id"": ""2_11_dd7a05b5-7252-44c7-b411-24b92e226977"",""reservationId"":""dd7a05b5-7252-44c7-b411-24b92e226977"", ""accountId"":1,""isLevyAccount"":false,""createdDate"":""2019-08-20T14:37:01.7530000"",""startDate"": ""2019-09-01T00:00:00"",""expiryDate"":""2020-09-30T00:00:00"",""status"":1,""courseId"":""4"",""courseTitle"": ""Computer Management"",""courseLevel"":2,""courseName"":""Computer Management 2"",""accountLegalEntityId"":11, ""providerId"":2,""accountLegalEntityName"":""Test Ltd"",""indexedProviderId"":2},""sort"":[""Test Co"", ""Computer Management"",1567296000000]}]}}"; _mockClient.Setup(c => c.SearchAsync <StringResponse>( "test", It.Is <PostData>(pd => !pd.GetRequestString().Contains("aggs")), It.IsAny <SearchRequestParameters>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new StringResponse(searchReponse)); _mockClient.Setup(c => c.CountAsync <StringResponse>( "test", It.IsAny <PostData>(), It.IsAny <CountRequestParameters>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new StringResponse(@"{""count"":10}")); }
public async Task <IndexedReservationSearchResult> Find( long providerId, string searchTerm, ushort pageNumber, ushort pageItemCount, SelectedSearchFilters selectedFilters) { _logger.LogInformation("Starting reservation search"); var reservationIndex = await GetCurrentReservationIndex(); if (string.IsNullOrWhiteSpace(reservationIndex?.Name)) { _logger.LogWarning("Searching failed. Latest Reservation index does not have a name value"); return(new IndexedReservationSearchResult()); } var startingDocumentIndex = (ushort)(pageNumber < 2 ? 0 : (pageNumber - 1) * pageItemCount); var elasticSearchResult = await GetSearchResult( providerId, searchTerm, pageItemCount, startingDocumentIndex, reservationIndex.Name, selectedFilters); if (elasticSearchResult == null) { _logger.LogWarning("Searching failed. Elastic search response could not be de-serialised"); return(new IndexedReservationSearchResult()); } _logger.LogDebug("Searching complete, returning search results"); var totalRecordCount = await GetSearchResultCount(reservationIndex.Name, providerId); var filterValues = await GetFilterValues(reservationIndex.Name, providerId); var searchResult = new IndexedReservationSearchResult { Reservations = elasticSearchResult.Items, TotalReservations = (uint)elasticSearchResult.hits.total.value, TotalReservationsForProvider = totalRecordCount, Filters = new SearchFilters { CourseFilters = filterValues.Courses, EmployerFilters = filterValues.AccountLegalEntityNames, StartDateFilters = filterValues.StartDates } }; return(searchResult); }
public async Task <ReservationSearchResult> FindReservations( long providerId, string searchTerm, ushort pageNumber, ushort pageItemCount, SelectedSearchFilters selectedFilters) { var result = await _reservationIndexRepository.Find( providerId, searchTerm, pageNumber, pageItemCount, selectedFilters); return(new ReservationSearchResult { Reservations = result.Reservations.Select(r => r.ToReservation()), TotalReservations = result.TotalReservations, Filters = result.Filters, TotalReservationsForProvider = result.TotalReservationsForProvider }); }