public async Task HijackIndexAndGetOperation(bool includePrerelease, bool includeSemVer2, bool returned)
            {
                _v2Request.IgnoreFilter      = true;
                _v2Request.IncludePrerelease = includePrerelease;
                _v2Request.IncludeSemVer2    = includeSemVer2;
                _hijackDocument.Prerelease   = true;
                _hijackDocument.SemVerLevel  = SemVerLevelKey.SemVer2;
                _operation = IndexOperation.Get(_key);
                var expectedDocument = returned ? _hijackDocument : null;

                var response = await _target.V2SearchAsync(_v2Request);

                Assert.Same(_v2Response, response);
                _operationBuilder.Verify(
                    x => x.V2SearchWithHijackIndex(_v2Request),
                    Times.Once);
                _hijackOperations.Verify(
                    x => x.GetOrNullAsync <HijackDocument.Full>(_key),
                    Times.Once);
                _responseBuilder.Verify(
                    x => x.V2FromHijackDocument(_v2Request, _key, expectedDocument, It.Is <TimeSpan>(t => t > TimeSpan.Zero)),
                    Times.Once);
                _telemetryService.Verify(
                    x => x.TrackV2GetDocumentWithHijackIndex(It.Is <TimeSpan>(t => t > TimeSpan.Zero)),
                    Times.Once);
            }
        public IndexOperation Autocomplete(AutocompleteRequest request)
        {
            if (HasInvalidParameters(request, request.PackageType))
            {
                return(IndexOperation.Empty());
            }

            var text       = _textBuilder.Autocomplete(request);
            var parameters = _parametersBuilder.Autocomplete(request, text.IsDefaultSearch);

            return(IndexOperation.Search(text.Value, parameters));
        }
        public IndexOperation Autocomplete(AutocompleteRequest request)
        {
            if (HasInvalidParameters(request, request.PackageType))
            {
                return(IndexOperation.Empty());
            }

            var text       = _textBuilder.Autocomplete(request);
            var parameters = _parametersBuilder.Autocomplete(request, IsEmptySearchQuery(text));

            return(IndexOperation.Search(text, parameters));
        }
            public async Task SearchIndexAndGetOperation()
            {
                _operation = IndexOperation.Get(_key);

                var ex = await Assert.ThrowsAsync <NotImplementedException>(() => _target.AutocompleteAsync(_autocompleteRequest));

                Assert.Equal("The operation type Get is not supported.", ex.Message);
                _operationBuilder.Verify(
                    x => x.Autocomplete(_autocompleteRequest),
                    Times.Once);
                _searchOperations.Verify(
                    x => x.GetOrNullAsync <SearchDocument.Full>(It.IsAny <string>()),
                    Times.Never);
                _telemetryService.Verify(
                    x => x.TrackV3GetDocument(It.IsAny <TimeSpan>()),
                    Times.Never);
            }
            public async Task SearchIndexAndEmptyOperation()
            {
                _operation = IndexOperation.Empty();

                var response = await _target.AutocompleteAsync(_autocompleteRequest);

                Assert.Same(_autocompleteResponse, response);
                _operationBuilder.Verify(
                    x => x.Autocomplete(_autocompleteRequest),
                    Times.Once);
                _searchOperations.Verify(
                    x => x.SearchAsync <SearchDocument.Full>(It.IsAny <string>(), It.IsAny <SearchParameters>()),
                    Times.Never);
                _responseBuilder.Verify(
                    x => x.EmptyAutocomplete(_autocompleteRequest),
                    Times.Once);
            }
            public async Task HijackIndexAndEmptyOperation()
            {
                _v2Request.IgnoreFilter = true;
                _operation = IndexOperation.Empty();

                var response = await _target.V2SearchAsync(_v2Request);

                Assert.Same(_v2Response, response);
                _operationBuilder.Verify(
                    x => x.V2SearchWithHijackIndex(_v2Request),
                    Times.Once);
                _searchOperations.Verify(
                    x => x.SearchAsync <HijackDocument.Full>(It.IsAny <string>(), It.IsAny <SearchParameters>()),
                    Times.Never);
                _responseBuilder.Verify(
                    x => x.EmptyV2(_v2Request),
                    Times.Once);
            }
        private bool TryGetHijackDocumentByKey(
            SearchRequest request,
            ParsedQuery parsed,
            out IndexOperation indexOperation)
        {
            if (PagedToFirstItem(request) &&
                parsed.Grouping.Count == 2 &&
                TryGetSinglePackageId(parsed, out var packageId) &&
                TryGetSingleVersion(parsed, out var normalizedVersion))
            {
                var documentKey = DocumentUtilities.GetHijackDocumentKey(packageId, normalizedVersion);

                indexOperation = IndexOperation.Get(documentKey);
                return(true);
            }

            indexOperation = null;
            return(false);
        }
        private bool TryGetSearchDocumentByKey(
            SearchRequest request,
            ParsedQuery parsed,
            out IndexOperation indexOperation)
        {
            if (PagedToFirstItem(request) &&
                parsed.Grouping.Count == 1 &&
                TryGetSinglePackageId(parsed, out var packageId))
            {
                var searchFilters = _parametersBuilder.GetSearchFilters(request);
                var documentKey   = DocumentUtilities.GetSearchDocumentKey(packageId, searchFilters);

                indexOperation = IndexOperation.Get(documentKey);
                return(true);
            }

            indexOperation = null;
            return(false);
        }
            public async Task SearchIndexAndGetOperation()
            {
                _operation = IndexOperation.Get(_key);

                var response = await _target.V3SearchAsync(_v3Request);

                Assert.Same(_v3Response, response);
                _operationBuilder.Verify(
                    x => x.V3Search(_v3Request),
                    Times.Once);
                _searchOperations.Verify(
                    x => x.GetOrNullAsync <SearchDocument.Full>(_key),
                    Times.Once);
                _responseBuilder.Verify(
                    x => x.V3FromSearchDocument(_v3Request, _key, _searchDocument, It.Is <TimeSpan>(t => t > TimeSpan.Zero)),
                    Times.Once);
                _telemetryService.Verify(
                    x => x.TrackV3GetDocument(It.Is <TimeSpan>(t => t > TimeSpan.Zero)),
                    Times.Once);
            }
        public IndexOperation V2SearchWithHijackIndex(V2SearchRequest request)
        {
            if (HasInvalidParameters(request, packageType: null))
            {
                return(IndexOperation.Empty());
            }

            var parsed = _textBuilder.ParseV2Search(request);

            IndexOperation indexOperation;

            if (TryGetHijackDocumentByKey(request, parsed, out indexOperation))
            {
                return(indexOperation);
            }

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

            return(IndexOperation.Search(text.Value, parameters));
        }
        public IndexOperation V2SearchWithSearchIndex(V2SearchRequest request)
        {
            if (HasInvalidParameters(request, packageType: null))
            {
                return(IndexOperation.Empty());
            }

            var parsed = _textBuilder.ParseV2Search(request);

            IndexOperation indexOperation;

            if (TryGetSearchDocumentByKey(request, parsed, out indexOperation))
            {
                return(indexOperation);
            }

            var text       = _textBuilder.Build(parsed);
            var parameters = _parametersBuilder.V2Search(request, IsEmptySearchQuery(text));

            return(IndexOperation.Search(text, parameters));
        }
        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));
        }
            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);
            }
 private static NotImplementedException UnsupportedOperation(IndexOperation operation)
 {
     return(new NotImplementedException($"The operation type {operation.Type} is not supported."));
 }