Example #1
0
        public V3SearchResponse V3FromSearch(
            V3SearchRequest request,
            string text,
            SearchParameters parameters,
            DocumentSearchResult <SearchDocument.Full> result,
            TimeSpan duration)
        {
            var results = result.Results;

            result.Results = null;

            var registrationsBaseUrl = GetRegistrationsBaseUrl(request.IncludeSemVer2);

            return(new V3SearchResponse
            {
                Context = GetV3SearchContext(registrationsBaseUrl),
                TotalHits = result.Count.Value,
                Data = results
                       .Select(x =>
                {
                    var package = ToV3SearchPackage(x.Document, registrationsBaseUrl);
                    package.Debug = request.ShowDebug ? x : null;
                    return package;
                })
                       .ToList(),
                Debug = DebugInformation.CreateFromSearchOrNull(
                    request,
                    _options.Value.SearchIndexName,
                    parameters,
                    text,
                    result,
                    duration,
                    AuxiliaryData.Metadata),
            });
        }
        public SearchParameters V3Search(V3SearchRequest request, bool isDefaultSearch)
        {
            var searchParameters = NewSearchParameters();

            ApplyPaging(searchParameters, request);
            ApplySearchIndexFilter(searchParameters, request, isDefaultSearch, request.PackageType);

            return(searchParameters);
        }
Example #3
0
            public void ThrowsWhenTermIsTooBig(string query)
            {
                var request = new V3SearchRequest {
                    Query = query
                };
                var parsed = _target.ParseV3Search(request);

                var e = Assert.Throws <InvalidSearchRequestException>(() => _target.Build(parsed));

                Assert.Equal("Query terms cannot exceed 32768 bytes.", e.Message);
            }
            public void NegativeSkip()
            {
                var request = new V3SearchRequest
                {
                    Skip = -10,
                };

                var output = _target.V3Search(request, It.IsAny <bool>());

                Assert.Equal(0, output.Skip);
            }
            public void InvalidPackageType()
            {
                var request = new V3SearchRequest
                {
                    PackageType = "something's-weird",
                };

                var output = _target.V3Search(request, It.IsAny <bool>());

                Assert.Equal("searchFilters eq 'Default'", output.Filter);
            }
            public void PackageTypeFiltering(string packageType)
            {
                var request = new V3SearchRequest
                {
                    PackageType = packageType,
                };

                var output = _target.V3Search(request, It.IsAny <bool>());

                Assert.Equal($"searchFilters eq 'Default' and filterablePackageTypes/any(p: p eq '{packageType.ToLowerInvariant()}')", output.Filter);
            }
            public void TooLargeTake()
            {
                var request = new V3SearchRequest
                {
                    Take = 1001,
                };

                var output = _target.V3Search(request, It.IsAny <bool>());

                Assert.Equal(20, output.Top);
            }
Example #8
0
        public V3SearchResponse EmptyV3(V3SearchRequest request)
        {
            var registrationsBaseUrl = GetRegistrationsBaseUrl(request.IncludeSemVer2);

            return(new V3SearchResponse
            {
                Context = GetV3SearchContext(registrationsBaseUrl),
                TotalHits = 0,
                Data = new List <V3SearchPackage>(),
                Debug = DebugInformation.CreateFromEmptyOrNull(request),
            });
        }
            public void SearchFilters(bool includePrerelease, bool includeSemVer2, string filter)
            {
                var request = new V3SearchRequest
                {
                    IncludePrerelease = includePrerelease,
                    IncludeSemVer2    = includeSemVer2,
                    Query             = "js"
                };

                var output = _target.V3Search(request, It.IsAny <bool>());

                Assert.Equal(filter, output.Filter);
            }
            public void Paging()
            {
                var request = new V3SearchRequest
                {
                    Skip = 10,
                    Take = 30,
                };

                var output = _target.V3Search(request, It.IsAny <bool>());

                Assert.Equal(10, output.Skip);
                Assert.Equal(30, output.Top);
            }
            public void Defaults()
            {
                var request = new V3SearchRequest();

                var output = _target.V3Search(request, isDefaultSearch: true);

                Assert.Equal(QueryType.Full, output.QueryType);
                Assert.True(output.IncludeTotalResultCount);
                Assert.Equal(DefaultOrderBy, output.OrderBy.ToArray());
                Assert.Equal(0, output.Skip);
                Assert.Equal(0, output.Top);
                Assert.Equal("searchFilters eq 'Default' and (isExcludedByDefault eq false or isExcludedByDefault eq null)", output.Filter);
            }
Example #12
0
            public void CanExcludeTestData(string query, bool includeTestData, string expected)
            {
                _config.TestOwners = new List <string> {
                    "TestUserA", "TestUserB"
                };
                var request = new V3SearchRequest
                {
                    Query           = query,
                    IncludeTestData = includeTestData,
                };
                var parsed = _target.ParseV3Search(request);

                var actual = _target.Build(parsed);

                Assert.Equal(expected, actual.Value);
            }
Example #13
0
        public async Task <V3SearchResponse> V3SearchAsync(V3SearchRequest request)
        {
            var operation = _operationBuilder.V3Search(request);

            V3SearchResponse output;

            switch (operation.Type)
            {
            case IndexOperationType.Get:
                var documentResult = await Measure.DurationWithValueAsync(
                    () => _searchIndex.Documents.GetOrNullAsync <SearchDocument.Full>(operation.DocumentKey));

                output = _responseBuilder.V3FromSearchDocument(
                    request,
                    operation.DocumentKey,
                    documentResult.Value,
                    documentResult.Duration);

                _telemetryService.TrackV3GetDocument(documentResult.Duration);
                break;

            case IndexOperationType.Search:
                var result = await Measure.DurationWithValueAsync(() => _searchIndex.Documents.SearchAsync <SearchDocument.Full>(
                                                                      operation.SearchText,
                                                                      operation.SearchParameters));

                output = _responseBuilder.V3FromSearch(
                    request,
                    operation.SearchText,
                    operation.SearchParameters,
                    result.Value,
                    result.Duration);

                _telemetryService.TrackV3SearchQuery(result.Duration);
                break;

            case IndexOperationType.Empty:
                output = _responseBuilder.EmptyV3(request);
                break;

            default:
                throw UnsupportedOperation(operation);
            }

            return(output);
        }
Example #14
0
            public void ThrowsWhenQueryHasTooManyClauses(int nonFieldScopedTerms, int fieldScopedTerms, bool shouldThrow)
            {
                var request = new V3SearchRequest {
                    Query = GenerateQuery(nonFieldScopedTerms, fieldScopedTerms)
                };
                var parsed = _target.ParseV3Search(request);

                if (shouldThrow)
                {
                    var e = Assert.Throws <InvalidSearchRequestException>(() => _target.Build(parsed));
                    Assert.Equal("A query can only have up to 1024 clauses.", e.Message);
                }
                else
                {
                    _target.ParseV3Search(request);
                }
            }
            public Facts()
            {
                TextBuilder       = new Mock <ISearchTextBuilder>();
                ParametersBuilder = new Mock <ISearchParametersBuilder>();

                AutocompleteRequest = new AutocompleteRequest {
                    Skip = 0, Take = 20
                };
                V2SearchRequest = new V2SearchRequest {
                    Skip = 0, Take = 20
                };
                V3SearchRequest = new V3SearchRequest {
                    Skip = 0, Take = 20
                };
                Text        = "";
                Parameters  = new SearchParameters();
                ParsedQuery = new ParsedQuery(new Dictionary <QueryField, HashSet <string> >());

                TextBuilder
                .Setup(x => x.Autocomplete(It.IsAny <AutocompleteRequest>()))
                .Returns(() => Text);
                TextBuilder
                .Setup(x => x.ParseV2Search(It.IsAny <V2SearchRequest>()))
                .Returns(() => ParsedQuery);
                TextBuilder
                .Setup(x => x.ParseV3Search(It.IsAny <V3SearchRequest>()))
                .Returns(() => ParsedQuery);
                TextBuilder
                .Setup(x => x.Build(It.IsAny <ParsedQuery>()))
                .Returns(() => Text);
                ParametersBuilder
                .Setup(x => x.Autocomplete(It.IsAny <AutocompleteRequest>(), It.IsAny <bool>()))
                .Returns(() => Parameters);
                ParametersBuilder
                .Setup(x => x.V2Search(It.IsAny <V2SearchRequest>(), It.IsAny <bool>()))
                .Returns(() => Parameters);
                ParametersBuilder
                .Setup(x => x.V3Search(It.IsAny <V3SearchRequest>(), It.IsAny <bool>()))
                .Returns(() => Parameters);

                Target = new IndexOperationBuilder(
                    TextBuilder.Object,
                    ParametersBuilder.Object);
            }
        public IndexOperation V3Search(V3SearchRequest request)
        {
            if (HasInvalidParameters(request, request.PackageType))
            {
                return(IndexOperation.Empty());
            }

            var parsed = _textBuilder.ParseV3Search(request);

            IndexOperation indexOperation;

            if (request.PackageType == null &&
                TryGetSearchDocumentByKey(request, parsed, out indexOperation))
            {
                return(indexOperation);
            }

            var text       = _textBuilder.Build(parsed);
            var parameters = _parametersBuilder.V3Search(request, text.IsDefaultSearch);

            return(IndexOperation.Search(text.Value, parameters));
        }
Example #17
0
        public V3SearchResponse V3FromSearchDocument(
            V3SearchRequest request,
            string documentKey,
            SearchDocument.Full document,
            TimeSpan duration)
        {
            var registrationsBaseUrl = GetRegistrationsBaseUrl(request.IncludeSemVer2);

            var data = new List <V3SearchPackage>();

            if (document != null)
            {
                var package = ToV3SearchPackage(document, registrationsBaseUrl);
                package.Debug = request.ShowDebug ? new DebugDocumentResult {
                    Document = document
                } : null;
                data.Add(package);
            }

            return(new V3SearchResponse
            {
                Context = new V3SearchContext
                {
                    Vocab = "http://schema.nuget.org/schema#",
                    Base = registrationsBaseUrl,
                },
                TotalHits = data.Count,
                Data = data,
                Debug = DebugInformation.CreateFromGetOrNull(
                    request,
                    _options.Value.SearchIndexName,
                    documentKey,
                    duration,
                    AuxiliaryData.Metadata),
            });
        }
Example #18
0
 public ParsedQuery ParseV3Search(V3SearchRequest request)
 {
     return(GetParsedQuery(request.Query, request.IncludeTestData));
 }
            public BaseFacts()
            {
                _operationBuilder = new Mock <IIndexOperationBuilder>();
                _searchIndex      = new Mock <ISearchIndexClientWrapper>();
                _searchOperations = new Mock <IDocumentsOperationsWrapper>();
                _hijackIndex      = new Mock <ISearchIndexClientWrapper>();
                _hijackOperations = new Mock <IDocumentsOperationsWrapper>();
                _responseBuilder  = new Mock <ISearchResponseBuilder>();
                _telemetryService = new Mock <IAzureSearchTelemetryService>();

                _v2Request           = new V2SearchRequest();
                _v3Request           = new V3SearchRequest();
                _autocompleteRequest = new AutocompleteRequest();
                _key                  = "key";
                _text                 = "search";
                _parameters           = new SearchParameters();
                _operation            = IndexOperation.Search(_text, _parameters);
                _searchResult         = new DocumentSearchResult <SearchDocument.Full>();
                _searchDocument       = new SearchDocument.Full();
                _hijackResult         = new DocumentSearchResult <HijackDocument.Full>();
                _hijackDocument       = new HijackDocument.Full();
                _v2Response           = new V2SearchResponse();
                _v3Response           = new V3SearchResponse();
                _autocompleteResponse = new AutocompleteResponse();

                _operationBuilder
                .Setup(x => x.V2SearchWithHijackIndex(It.IsAny <V2SearchRequest>()))
                .Returns(() => _operation);
                _operationBuilder
                .Setup(x => x.V2SearchWithSearchIndex(It.IsAny <V2SearchRequest>()))
                .Returns(() => _operation);
                _operationBuilder
                .Setup(x => x.V3Search(It.IsAny <V3SearchRequest>()))
                .Returns(() => _operation);
                _operationBuilder
                .Setup(x => x.Autocomplete(It.IsAny <AutocompleteRequest>()))
                .Returns(() => _operation);

                // Set up the search to take at least one millisecond. This allows us to test the measured duration.
                _searchOperations
                .Setup(x => x.SearchAsync <SearchDocument.Full>(It.IsAny <string>(), It.IsAny <SearchParameters>()))
                .ReturnsAsync(() => _searchResult)
                .Callback(() => Thread.Sleep(TimeSpan.FromMilliseconds(1)));
                _searchOperations
                .Setup(x => x.GetOrNullAsync <SearchDocument.Full>(It.IsAny <string>()))
                .ReturnsAsync(() => _searchDocument)
                .Callback(() => Thread.Sleep(TimeSpan.FromMilliseconds(1)));
                _hijackOperations
                .Setup(x => x.SearchAsync <HijackDocument.Full>(It.IsAny <string>(), It.IsAny <SearchParameters>()))
                .ReturnsAsync(() => _hijackResult)
                .Callback(() => Thread.Sleep(TimeSpan.FromMilliseconds(1)));
                _hijackOperations
                .Setup(x => x.GetOrNullAsync <HijackDocument.Full>(It.IsAny <string>()))
                .ReturnsAsync(() => _hijackDocument)
                .Callback(() => Thread.Sleep(TimeSpan.FromMilliseconds(1)));

                _responseBuilder
                .Setup(x => x.V2FromHijack(
                           It.IsAny <V2SearchRequest>(),
                           It.IsAny <string>(),
                           It.IsAny <SearchParameters>(),
                           It.IsAny <DocumentSearchResult <HijackDocument.Full> >(),
                           It.IsAny <TimeSpan>()))
                .Returns(() => _v2Response);
                _responseBuilder
                .Setup(x => x.V2FromHijackDocument(
                           It.IsAny <V2SearchRequest>(),
                           It.IsAny <string>(),
                           It.IsAny <HijackDocument.Full>(),
                           It.IsAny <TimeSpan>()))
                .Returns(() => _v2Response);
                _responseBuilder
                .Setup(x => x.V2FromSearch(
                           It.IsAny <V2SearchRequest>(),
                           It.IsAny <string>(),
                           It.IsAny <SearchParameters>(),
                           It.IsAny <DocumentSearchResult <SearchDocument.Full> >(),
                           It.IsAny <TimeSpan>()))
                .Returns(() => _v2Response);
                _responseBuilder
                .Setup(x => x.V2FromSearchDocument(
                           It.IsAny <V2SearchRequest>(),
                           It.IsAny <string>(),
                           It.IsAny <SearchDocument.Full>(),
                           It.IsAny <TimeSpan>()))
                .Returns(() => _v2Response);
                _responseBuilder
                .Setup(x => x.V3FromSearch(
                           It.IsAny <V3SearchRequest>(),
                           It.IsAny <string>(),
                           It.IsAny <SearchParameters>(),
                           It.IsAny <DocumentSearchResult <SearchDocument.Full> >(),
                           It.IsAny <TimeSpan>()))
                .Returns(() => _v3Response);
                _responseBuilder
                .Setup(x => x.V3FromSearchDocument(
                           It.IsAny <V3SearchRequest>(),
                           It.IsAny <string>(),
                           It.IsAny <SearchDocument.Full>(),
                           It.IsAny <TimeSpan>()))
                .Returns(() => _v3Response);
                _responseBuilder
                .Setup(x => x.AutocompleteFromSearch(
                           It.IsAny <AutocompleteRequest>(),
                           It.IsAny <string>(),
                           It.IsAny <SearchParameters>(),
                           It.IsAny <DocumentSearchResult <SearchDocument.Full> >(),
                           It.IsAny <TimeSpan>()))
                .Returns(() => _autocompleteResponse);
                _responseBuilder
                .Setup(x => x.EmptyV2(It.IsAny <V2SearchRequest>()))
                .Returns(() => _v2Response);
                _responseBuilder
                .Setup(x => x.EmptyV3(It.IsAny <V3SearchRequest>()))
                .Returns(() => _v3Response);
                _responseBuilder
                .Setup(x => x.EmptyAutocomplete(It.IsAny <AutocompleteRequest>()))
                .Returns(() => _autocompleteResponse);

                _searchIndex.Setup(x => x.Documents).Returns(() => _searchOperations.Object);
                _hijackIndex.Setup(x => x.Documents).Returns(() => _hijackOperations.Object);

                _target = new AzureSearchService(
                    _operationBuilder.Object,
                    _searchIndex.Object,
                    _hijackIndex.Object,
                    _responseBuilder.Object,
                    _telemetryService.Object);
            }
Example #20
0
            public BaseFacts()
            {
                _auxiliaryData = new Mock <IAuxiliaryData>();
                _config        = new SearchServiceConfiguration();
                _options       = new Mock <IOptionsSnapshot <SearchServiceConfiguration> >();
                _options.Setup(x => x.Value).Returns(() => _config);
                _auxiliaryMetadata = new AuxiliaryFilesMetadata(
                    new DateTimeOffset(2019, 1, 3, 11, 0, 0, TimeSpan.Zero),
                    new AuxiliaryFileMetadata(
                        new DateTimeOffset(2019, 1, 1, 11, 0, 0, TimeSpan.Zero),
                        TimeSpan.FromSeconds(15),
                        1234,
                        "\"etag-a\""),
                    new AuxiliaryFileMetadata(
                        new DateTimeOffset(2019, 1, 2, 11, 0, 0, TimeSpan.Zero),
                        TimeSpan.FromSeconds(30),
                        5678,
                        "\"etag-b\""));

                _config.SearchIndexName             = "search-index";
                _config.HijackIndexName             = "hijack-index";
                _config.SemVer1RegistrationsBaseUrl = "https://example/reg/";
                _config.SemVer2RegistrationsBaseUrl = "https://example/reg-gz-semver2/";
                _config.FlatContainerBaseUrl        = Data.FlatContainerBaseUrl;
                _config.FlatContainerContainerName  = Data.FlatContainerContainerName;

                _auxiliaryData
                .Setup(x => x.GetTotalDownloadCount(It.IsAny <string>()))
                .Returns(Data.TotalDownloadCount);
                _auxiliaryData
                .Setup(x => x.GetDownloadCount(It.IsAny <string>(), It.IsAny <string>()))
                .Returns(23);
                _auxiliaryData
                .Setup(x => x.IsVerified(It.IsAny <string>()))
                .Returns(true);
                _auxiliaryData
                .Setup(x => x.Metadata)
                .Returns(() => _auxiliaryMetadata);

                _v2Request = new V2SearchRequest
                {
                    IncludePrerelease = true,
                    IncludeSemVer2    = true,
                };
                _v3Request = new V3SearchRequest
                {
                    IncludePrerelease = true,
                    IncludeSemVer2    = true
                };
                _autocompleteRequest = new AutocompleteRequest
                {
                    IncludePrerelease = true,
                    IncludeSemVer2    = true,
                };
                _searchParameters  = new SearchParameters();
                _text              = "azure storage sdk";
                _duration          = TimeSpan.FromMilliseconds(250);
                _emptySearchResult = new DocumentSearchResult <SearchDocument.Full>
                {
                    Count   = 0,
                    Results = new List <SearchResult <SearchDocument.Full> >(),
                };
                _searchResult = new DocumentSearchResult <SearchDocument.Full>
                {
                    Count   = 1,
                    Results = new List <SearchResult <SearchDocument.Full> >
                    {
                        new SearchResult <SearchDocument.Full>
                        {
                            Document = Data.SearchDocument,
                        },
                    },
                };
                _manySearchResults = new DocumentSearchResult <SearchDocument.Full>
                {
                    Count   = 2,
                    Results = new List <SearchResult <SearchDocument.Full> >
                    {
                        new SearchResult <SearchDocument.Full>
                        {
                            Document = Data.SearchDocument,
                        },
                        new SearchResult <SearchDocument.Full>
                        {
                            Document = Data.SearchDocument,
                        },
                    },
                };
                _hijackResult = new DocumentSearchResult <HijackDocument.Full>
                {
                    Count   = 1,
                    Results = new List <SearchResult <HijackDocument.Full> >
                    {
                        new SearchResult <HijackDocument.Full>
                        {
                            Document = Data.HijackDocument,
                        },
                    },
                };

                _jsonSerializerSettings = new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    Converters        =
                    {
                        new StringEnumConverter(),
                    },
                    Formatting = Formatting.Indented,
                };
            }
Example #21
0
 public ParsedQuery ParseV3Search(V3SearchRequest request)
 {
     return(GetParsedQuery(request.Query));
 }