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);
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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}"));
        }
Example #10
0
        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);
        }
Example #11
0
        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
            });
        }