コード例 #1
0
        public void SpecificationSearchModelToSpecificationIndexMapping()
        {
            SpecificationSearchModel specificationSearchModel = NewSpecificationSearchModel(_ => _.WithFundingPeriod(NewFundingPeriod())
                                                                                            .WithDataDefinitionRelationshipIds(NewRandomString(), NewRandomString())
                                                                                            .WithFundingStreams(NewFundingStream(), NewFundingStream()));


            SpecificationIndex searchIndex = WhenTheSourceItemsAreMapped(specificationSearchModel).Single();

            searchIndex
            .Should()
            .BeEquivalentTo(new SpecificationIndex
            {
                Id                            = specificationSearchModel.Id,
                Name                          = specificationSearchModel.Name,
                FundingPeriodId               = specificationSearchModel.FundingPeriod.Id,
                FundingPeriodName             = specificationSearchModel.FundingPeriod.Name,
                FundingStreamIds              = specificationSearchModel.FundingStreams.Select(_ => _.Id).ToArray(),
                FundingStreamNames            = specificationSearchModel.FundingStreams.Select(_ => _.Name).ToArray(),
                Description                   = specificationSearchModel.Description,
                LastUpdatedDate               = specificationSearchModel.UpdatedAt,
                DataDefinitionRelationshipIds = specificationSearchModel.DataDefinitionRelationshipIds.ToArray(),
                Status                        = specificationSearchModel.PublishStatus,
                IsSelectedForFunding          = specificationSearchModel.IsSelectedForFunding
            }, opt => opt.ComparingByMembers <Reference>());
        }
コード例 #2
0
        public void SpecificationToSpecificationIndexMapping()
        {
            Specification specification = NewSpecification(_ => _.WithCurrent(NewSpecificationVersion(curr =>
                                                                                                      curr.WithFundingStreamsIds(NewRandomString(), NewRandomString())
                                                                                                      .WithDataDefinitionRelationshipIds(NewRandomString(), NewRandomString(), NewRandomString()))));

            SpecificationIndex searchIndex = WhenTheSourceItemsAreMapped(specification).Single();

            searchIndex
            .Should()
            .BeEquivalentTo(new SpecificationIndex
            {
                Id                            = specification.Id,
                Name                          = specification.Name,
                FundingPeriodId               = specification.Current.FundingPeriod.Id,
                FundingPeriodName             = specification.Current.FundingPeriod.Name,
                FundingStreamIds              = specification.Current.FundingStreams.Select(_ => _.Id).ToArray(),
                FundingStreamNames            = specification.Current.FundingStreams.Select(_ => _.Name).ToArray(),
                Description                   = specification.Current.Description,
                LastUpdatedDate               = specification.Current.Date,
                IsSelectedForFunding          = specification.IsSelectedForFunding,
                DataDefinitionRelationshipIds = specification.Current.DataDefinitionRelationshipIds.ToArray(),
                Status                        = specification.Current.PublishStatus.ToString()
            }, opt => opt.ComparingByMembers <Reference>());
        }
        public async Task SearchById_GivenIdDoesNotReturnSearchResult_ReturnsNull()
        {
            SearchRepositorySettings searchRepositorySettings = new SearchRepositorySettings
            {
                SearchKey         = string.Empty,
                SearchServiceName = string.Empty
            };

            ISearchInitializer searchInitializer = Substitute.For <ISearchInitializer>();

            ISearchIndexClient searchIndexClient = Substitute.For <ISearchIndexClient>();

            AzureOperationResponse <DocumentSearchResult <SpecificationIndex> > documentSearchResult =
                new AzureOperationResponse <DocumentSearchResult <SpecificationIndex> >
            {
                Body = new DocumentSearchResult <SpecificationIndex>(null, null, null, null, null)
            };

            IDocumentsOperations documentsOperations = Substitute.For <IDocumentsOperations>();

            documentsOperations.SearchWithHttpMessagesAsync <SpecificationIndex>(Arg.Any <string>(), Arg.Any <SearchParameters>()).Returns(Task.FromResult(documentSearchResult));

            ISearchServiceClient searchServiceClient = Substitute.For <ISearchServiceClient>();

            searchIndexClient.Documents.Returns(documentsOperations);

            SearchRepository <SpecificationIndex> searchRepository = new SearchRepository <SpecificationIndex>(searchRepositorySettings, searchInitializer, searchServiceClient, searchIndexClient);

            string notFoundId = "notFound";

            SpecificationIndex specificationIndex = await searchRepository.SearchById(notFoundId);

            specificationIndex.Should().BeNull();
        }
コード例 #4
0
 private void AssertSearchResults(SpecificationIndex expectedSpecificationIndex, SpecificationSearchResult specificationSearchResult)
 {
     specificationSearchResult.Id.Should().Be(expectedSpecificationIndex.Id);
     specificationSearchResult.Name.Should().Be(expectedSpecificationIndex.Name);
     specificationSearchResult.FundingPeriodName.Should().Be(expectedSpecificationIndex.FundingPeriodName);
     specificationSearchResult.FundingStreamNames.Should().BeEquivalentTo(expectedSpecificationIndex.FundingStreamNames);
     specificationSearchResult.Status.Should().Be(expectedSpecificationIndex.Status);
     specificationSearchResult.Description.Should().Be(expectedSpecificationIndex.Description);
     specificationSearchResult.LastUpdatedDate.Should().Be(expectedSpecificationIndex.LastUpdatedDate);
     specificationSearchResult.IsSelectedForFunding.Should().Be(expectedSpecificationIndex.IsSelectedForFunding);
 }
        private void AndTheSpecificationIndexHasTheDatasetsSummaryInformation(SpecificationIndex specificationIndex,
                                                                              int expectedTotalMappedCount,
                                                                              DateTimeOffset?expectedLastDatasetUpdatedDate)
        {
            specificationIndex.TotalMappedDataSets
            .Should()
            .Be(expectedTotalMappedCount);

            specificationIndex.MapDatasetLastUpdated
            .Should()
            .Be(expectedLastDatasetUpdatedDate);
        }
        public async Task SearchById_GivenIdReturnsSearchResult_ReturnsResults()
        {
            string existingId = "existingId";

            SearchRepositorySettings searchRepositorySettings = new SearchRepositorySettings
            {
                SearchKey         = string.Empty,
                SearchServiceName = string.Empty
            };

            ISearchInitializer searchInitializer = Substitute.For <ISearchInitializer>();

            ISearchIndexClient searchIndexClient = Substitute.For <ISearchIndexClient>();

            Microsoft.Azure.Search.Models.SearchResult <SpecificationIndex> specificationIndexSearchResult = new Microsoft.Azure.Search.Models.SearchResult <SpecificationIndex>(new SpecificationIndex
            {
                Id = existingId
            });

            AzureOperationResponse <DocumentSearchResult <SpecificationIndex> > documentSearchResult =
                new AzureOperationResponse <DocumentSearchResult <SpecificationIndex> >
            {
                Body = new DocumentSearchResult <SpecificationIndex>(new[]
                {
                    specificationIndexSearchResult
                },
                                                                     null,
                                                                     null,
                                                                     null,
                                                                     null)
            };

            IDocumentsOperations documentsOperations = Substitute.For <IDocumentsOperations>();

            documentsOperations
            .SearchWithHttpMessagesAsync <SpecificationIndex>(Arg.Is <string>(_ => _ == $"\"{existingId}\""),
                                                              Arg.Is <SearchParameters>(_ => _.SearchFields.SequenceEqual(new[]
            {
                "id"
            })))
            .Returns(Task.FromResult(documentSearchResult));

            ISearchServiceClient searchServiceClient = Substitute.For <ISearchServiceClient>();

            searchIndexClient.Documents.Returns(documentsOperations);

            SearchRepository <SpecificationIndex> searchRepository = new SearchRepository <SpecificationIndex>(searchRepositorySettings, searchInitializer, searchServiceClient, searchIndexClient);

            SpecificationIndex specificationIndex = await searchRepository.SearchById(existingId);

            specificationIndex.Should().NotBeNull();
            specificationIndex.Id.Should().Be(existingId);
        }
        public async Task MapsSuppliedSpecificationIntoIndexAddsDatasetSummaryInformationAndThenAndThenIndexesIt()
        {
            DateTimeOffset lastUpdateOne = NewRandomDate();
            DateTimeOffset lastUpdateTwo = lastUpdateOne.AddDays(1);

            Specification      specification      = NewSpecification();
            SpecificationIndex specificationIndex = NewSpecificationIndex();

            DatasetSpecificationRelationshipViewModel[] relationships = AsArray(NewDatasetSpecificationRelationshipViewModel(_ => _.WithDatasetId(NewRandomString())
                                                                                                                             .WithLastUpdatedDate(lastUpdateTwo)),
                                                                                NewDatasetSpecificationRelationshipViewModel(),
                                                                                NewDatasetSpecificationRelationshipViewModel(_ => _.WithDatasetId(NewRandomString())
                                                                                                                             .WithLastUpdatedDate(lastUpdateOne)));

            GivenTheSpecificationIndexMappings(AsArray(specification), specificationIndex);
            AndTheDatasetRelationshipsForSpecificationId(specificationIndex.Id, relationships);

            await WhenTheSpecificationIsIndexed(specification);

            ThenTheIndicesWereIndexed(specificationIndex);
            AndTheSpecificationIndexHasTheDatasetsSummaryInformation(specificationIndex, 2, lastUpdateTwo);
        }
コード例 #8
0
        public async Task SearchSpecifications_GivenValidModelWithOneFilter_ThenSearchIsPerformed()
        {
            //Arrange
            SearchModel model = new SearchModel
            {
                PageNumber    = 1,
                Top           = 50,
                IncludeFacets = true,
                Filters       = new Dictionary <string, string[]>()
                {
                    { "status", new string [] { "test" } }
                },
                SearchTerm = "testTerm",
            };

            SpecificationIndex expectedSpecificationIndex = new SpecificationIndex()
            {
                Id   = "test-sp1",
                Name = "test-sp1-name",
                FundingPeriodName    = "fp",
                FundingStreamNames   = new[] { "fs" },
                Status               = "test-status",
                Description          = "des",
                IsSelectedForFunding = true,
                LastUpdatedDate      = new DateTimeOffset(new DateTime(2020, 09, 08, 10, 40, 15))
            };

            SearchResults <SpecificationIndex> searchResults = new SearchResults <SpecificationIndex>()
            {
                Results = new List <Repositories.Common.Search.SearchResult <SpecificationIndex> >()
                {
                    new Repositories.Common.Search.SearchResult <SpecificationIndex>()
                    {
                        Result = expectedSpecificationIndex
                    }
                }
            };

            ILogger logger = CreateLogger();

            ISearchRepository <SpecificationIndex> searchRepository = CreateSearchRepository();

            searchRepository
            .Search(Arg.Any <string>(), Arg.Any <SearchParameters>())
            .Returns(searchResults);

            SpecificationsSearchService service = CreateSearchService(logger: logger, searchRepository: searchRepository);

            //Act
            IActionResult result = await service.SearchSpecifications(model);

            //Assert
            SpecificationSearchResults searchResult = result
                                                      .Should()
                                                      .BeOfType <OkObjectResult>()
                                                      .Which
                                                      .Value
                                                      .As <SpecificationSearchResults>();

            searchResult.Results.Count().Should().Be(1);
            AssertSearchResults(expectedSpecificationIndex, searchResult.Results.First());

            await
            searchRepository
            .Received(3)
            .Search(model.SearchTerm, Arg.Is <SearchParameters>(c =>
                                                                model.Filters.Keys.All(f => c.Filter.Contains(f)) &&
                                                                !string.IsNullOrWhiteSpace(c.Filter)
                                                                ));
        }
        public async Task MapsSuppliedSearchModelsIntoIndicesAddsDatasetSummaryInformationAndThenIndexesThem()
        {
            DateTimeOffset lastUpdateFour = NewRandomDate();
            DateTimeOffset lastUpdateTwo  = lastUpdateFour.AddDays(1);
            DateTimeOffset lastUpdateOne  = lastUpdateFour.AddDays(10);

            SpecificationSearchModel[] specifications = AsArray(
                NewSpecificationSearchModel(),
                NewSpecificationSearchModel(),
                NewSpecificationSearchModel(),
                NewSpecificationSearchModel(),
                NewSpecificationSearchModel(),
                NewSpecificationSearchModel(),
                NewSpecificationSearchModel(),
                NewSpecificationSearchModel(),
                NewSpecificationSearchModel()
                );
            SpecificationIndex specificationIndexOne   = NewSpecificationIndex();
            SpecificationIndex specificationIndexTwo   = NewSpecificationIndex();
            SpecificationIndex specificationIndexThree = NewSpecificationIndex();
            SpecificationIndex specificationIndexFour  = NewSpecificationIndex();
            SpecificationIndex specificationIndexFive  = NewSpecificationIndex();
            SpecificationIndex specificationIndexSix   = NewSpecificationIndex();
            SpecificationIndex specificationIndexSeven = NewSpecificationIndex();

            GivenTheSpecificationIndexMappings(specifications,
                                               specificationIndexOne,
                                               specificationIndexTwo,
                                               specificationIndexThree,
                                               specificationIndexFour,
                                               specificationIndexFive,
                                               specificationIndexSix,
                                               specificationIndexSeven);
            AndTheDatasetRelationshipsForSpecificationId(specificationIndexFour.Id,
                                                         NewDatasetSpecificationRelationshipViewModel(_ => _.WithDatasetId(NewRandomString())
                                                                                                      .WithLastUpdatedDate(lastUpdateFour)),
                                                         NewDatasetSpecificationRelationshipViewModel());
            AndTheDatasetRelationshipsForSpecificationId(specificationIndexSix.Id, NewDatasetSpecificationRelationshipViewModel());
            AndTheDatasetRelationshipsForSpecificationId(specificationIndexSeven.Id, NewDatasetSpecificationRelationshipViewModel());
            AndTheDatasetRelationshipsForSpecificationId(specificationIndexFive.Id, NewDatasetSpecificationRelationshipViewModel());
            AndTheDatasetRelationshipsForSpecificationId(specificationIndexTwo.Id,
                                                         NewDatasetSpecificationRelationshipViewModel(_ => _.WithDatasetId(NewRandomString())),
                                                         NewDatasetSpecificationRelationshipViewModel(_ => _.WithDatasetId(NewRandomString())
                                                                                                      .WithLastUpdatedDate(lastUpdateTwo)),
                                                         NewDatasetSpecificationRelationshipViewModel(_ => _.WithDatasetId(NewRandomString())
                                                                                                      .WithLastUpdatedDate(lastUpdateTwo.AddDays(-1))),
                                                         NewDatasetSpecificationRelationshipViewModel());
            AndTheDatasetRelationshipsForSpecificationId(specificationIndexOne.Id,
                                                         NewDatasetSpecificationRelationshipViewModel(_ => _.WithDatasetId(NewRandomString())
                                                                                                      .WithLastUpdatedDate(lastUpdateOne)),
                                                         NewDatasetSpecificationRelationshipViewModel(_ => _.WithDatasetId(NewRandomString())
                                                                                                      .WithLastUpdatedDate(lastUpdateOne.AddDays(-1))),
                                                         NewDatasetSpecificationRelationshipViewModel());

            await WhenTheSpecificationsAreIndexed(specifications);

            ThenTheIndicesWereIndexed(specificationIndexOne,
                                      specificationIndexTwo,
                                      specificationIndexThree,
                                      specificationIndexFour,
                                      specificationIndexFive);
            AndTheIndicesWereIndexed(specificationIndexSix,
                                     specificationIndexSeven);
            AndTheSpecificationIndexHasTheDatasetsSummaryInformation(specificationIndexOne, 2, lastUpdateOne);
            AndTheSpecificationIndexHasTheDatasetsSummaryInformation(specificationIndexTwo, 3, lastUpdateTwo);
            AndTheSpecificationIndexHasTheDatasetsSummaryInformation(specificationIndexThree, 0, null);
            AndTheSpecificationIndexHasTheDatasetsSummaryInformation(specificationIndexFour, 1, lastUpdateFour);
            AndTheSpecificationIndexHasTheDatasetsSummaryInformation(specificationIndexFive, 0, null);
            AndTheSpecificationIndexHasTheDatasetsSummaryInformation(specificationIndexSix, 0, null);
            AndTheSpecificationIndexHasTheDatasetsSummaryInformation(specificationIndexSeven, 0, null);
        }
コード例 #10
0
        public void SearchIndexTest_GivenSearchSchemasAndModels_EnsureFieldsMatch()
        {
            // Arrange
            IList <string>         ErrorLog = new List <string>();
            DatasetDefinitionIndex datasetDefinitionIndex = new DatasetDefinitionIndex();
            ProvidersIndex         providersIndex         = new ProvidersIndex();
            PublishedFundingIndex  publishedfundingindex  = new PublishedFundingIndex();
            PublishedProviderIndex publishedProviderIndex = new PublishedProviderIndex();
            SpecificationIndex     specificationindex     = new SpecificationIndex();
            TemplateIndex          templateIndex          = new TemplateIndex();

            IEnumerable <Type> searchIndexTypes = GetTypesWithSearchIndexAttribute();

            IEnumerable <string> indexNames = Directory
                                              .GetDirectories(searchIndexDirectoryPath, "*index", SearchOption.TopDirectoryOnly)
                                              .Select(m => new DirectoryInfo(m).Name);

            //Act
            foreach (string indexName in indexNames)
            {
                try
                {
                    string jsonFilePath = $@"{searchIndexDirectoryPath}\{indexName}\{indexName}.json";

                    string            jsonText          = File.ReadAllText(jsonFilePath, Encoding.UTF8);
                    SearchIndexSchema searchIndexSchema = JsonConvert.DeserializeObject <SearchIndexSchema>(jsonText);
                    if (searchIndexSchema?.Name == null)
                    {
                        ErrorLog.Add(string.IsNullOrWhiteSpace(jsonText)
                            ? $"{indexName} json is blank"
                            : $"{indexName} json name is not available");
                    }
                    else if (searchIndexSchema.Name != indexName)
                    {
                        ErrorLog.Add($"Expected to find index { indexName }, but found { searchIndexSchema.Name }");
                    }
                    else
                    {
                        Type searchIndexType = searchIndexTypes
                                               .FirstOrDefault(m => m.CustomAttributes
                                                               .FirstOrDefault(p => p.NamedArguments
                                                                               .Any(n => n.TypedValue.Value.ToString() == searchIndexSchema.Name)) != null);

                        IEnumerable <string> searchIndexProperties = searchIndexType.GetProperties()
                                                                     .Select(m => m.CustomAttributes
                                                                             .FirstOrDefault(a => a.AttributeType.Name == "JsonPropertyAttribute")
                                                                             ?.ConstructorArguments[0].Value.ToString().ToLower())
                                                                     .Where(p => p != null);

                        IEnumerable <string> searchIndexJsonProperties = searchIndexSchema.Fields
                                                                         .Select(m => m.Name.ToLower())
                                                                         .Where(p => p != null);

                        if (!searchIndexProperties.Any())
                        {
                            ErrorLog.Add($"Index {indexName}: The model contains no properties");
                        }
                        else if (!searchIndexJsonProperties.Any())
                        {
                            ErrorLog.Add($"Index {indexName}: The json contains no properties");
                        }
                        else
                        {
                            IEnumerable <string> notInJson = searchIndexProperties.Except(searchIndexJsonProperties);
                            if (notInJson.Any())
                            {
                                string properties = string.Join(",", notInJson);
                                ErrorLog.Add($"Index {indexName}: The model contains the following properties not found in the json schema ({properties})");
                            }

                            IEnumerable <string> notInModel = searchIndexJsonProperties.Except(searchIndexProperties);
                            if (notInModel.Any())
                            {
                                string properties = string.Join(",", notInModel);
                                ErrorLog.Add($"Index {indexName}: The json schema contains the following properties not found in the model ({properties})");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    ErrorLog.Add($"Unexpected error checking '{indexName}': {e.Message}{Environment.NewLine}{ e.StackTrace }");
                }
            }

            //Assert
            if (ErrorLog.Any())
            {
                Assert.Fail(string.Join(Environment.NewLine, ErrorLog));
            }
        }
コード例 #11
0
        public void SearchIndexTest_GivenSearchSchemasAndModels_EnsuresAttributesMatch()
        {
            //Arrange
            IList <string>         ErrorLog = new List <string>();
            DatasetDefinitionIndex datasetDefinitionIndex = new DatasetDefinitionIndex();
            ProvidersIndex         providersIndex         = new ProvidersIndex();
            PublishedFundingIndex  publishedfundingindex  = new PublishedFundingIndex();
            PublishedProviderIndex publishedProviderIndex = new PublishedProviderIndex();
            SpecificationIndex     specificationindex     = new SpecificationIndex();
            TemplateIndex          templateIndex          = new TemplateIndex();

            IEnumerable <Type> searchIndexTypes = GetTypesWithSearchIndexAttribute();

            IEnumerable <string> indexNames = Directory
                                              .GetDirectories(searchIndexDirectoryPath, "*index", SearchOption.TopDirectoryOnly)
                                              .Select(m => new DirectoryInfo(m).Name);

            //Act
            foreach (string indexName in indexNames)
            {
                try
                {
                    string jsonFilePath = $@"{searchIndexDirectoryPath}\{indexName}\{indexName}.json";

                    string jsonText = File.ReadAllText(jsonFilePath, Encoding.UTF8);

                    SearchIndexSchema searchIndexSchema = JsonConvert.DeserializeObject <SearchIndexSchema>(jsonText);
                    if (searchIndexSchema?.Name == null)
                    {
                        ErrorLog.Add(string.IsNullOrWhiteSpace(jsonText)
                            ? $"{indexName} json is blank"
                            : $"{indexName} json name is not available");
                    }
                    else if (searchIndexSchema.Name != indexName)
                    {
                        ErrorLog.Add($"Expected to find index {indexName}, but found {searchIndexSchema.Name}");
                    }
                    else
                    {
                        Type searchIndexType = searchIndexTypes.FirstOrDefault(m =>
                                                                               m.CustomAttributes.FirstOrDefault(p =>
                                                                                                                 p.NamedArguments.Any(n =>
                                                                                                                                      n.TypedValue.Value.ToString() == searchIndexSchema.Name)) != null);

                        IEnumerable <PropertyInfo> searchIndexProperties = searchIndexType.GetProperties();

                        foreach (SearchIndexField searchIndexField in searchIndexSchema.Fields)
                        {
                            PropertyInfo matchedProperty = searchIndexProperties.FirstOrDefault(m =>
                                                                                                string.Equals(m.CustomAttributes
                                                                                                              .SingleOrDefault(x => x.AttributeType.Name == "JsonPropertyAttribute")
                                                                                                              ?.ConstructorArguments[0].ToString().Replace("\"", "")
                                                                                                              ?? m.Name,
                                                                                                              searchIndexField.Name,
                                                                                                              StringComparison.InvariantCultureIgnoreCase));

                            if (matchedProperty == null)
                            {
                                ErrorLog.Add($"{indexName}: {searchIndexField.Name} did not match any properties");
                            }
                            else
                            {
                                CheckIndexFieldTypes(matchedProperty, searchIndexField, ErrorLog, indexName);
                                CheckIndexAttributes(matchedProperty, searchIndexField, ErrorLog, indexName);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    ErrorLog.Add($"Unexpected error checking '{indexName}': {e.Message}{Environment.NewLine}{e.StackTrace}");
                }
            }

            //Assert
            if (ErrorLog.Any())
            {
                Assert.Fail(string.Join(Environment.NewLine, ErrorLog));
            }
        }