private static CosmosClientContext GetMockedClientContext(
            Func <RequestMessage, CancellationToken, Task <ResponseMessage> > handlerFunc)
        {
            CosmosClient client = MockCosmosUtil.CreateMockCosmosClient();

            Mock <PartitionRoutingHelper> partitionRoutingHelperMock = MockCosmosUtil.GetPartitionRoutingHelperMock("0");
            PartitionKeyRangeHandler      partitionKeyRangeHandler   = new PartitionKeyRangeHandler(client, partitionRoutingHelperMock.Object);

            TestHandler testHandler = new TestHandler(handlerFunc);

            partitionKeyRangeHandler.InnerHandler = testHandler;

            RequestHandler handler = client.RequestHandler.InnerHandler;

            while (handler != null)
            {
                if (handler.InnerHandler is RouterHandler)
                {
                    handler.InnerHandler = new RouterHandler(partitionKeyRangeHandler, testHandler);
                    break;
                }

                handler = handler.InnerHandler;
            }

            CosmosResponseFactory responseFactory = new CosmosResponseFactory(MockCosmosUtil.Serializer);

            return(new ClientContextCore(
                       client: client,
                       clientOptions: new CosmosClientOptions(),
                       serializerCore: MockCosmosUtil.Serializer,
                       cosmosResponseFactory: responseFactory,
                       requestHandler: client.RequestHandler,
                       documentClient: new MockDocumentClient()));
        }
        public async Task VerifySendUsesOringianlContinuationOnNonSuccessfulResponse()
        {
            Mock <PartitionRoutingHelper> partitionRoutingHelperMock = this.GetPartitionRoutingHelperMock();
            PartitionKeyRangeHandler      partitionKeyRangeHandler   = new PartitionKeyRangeHandler(MockCosmosUtil.CreateMockCosmosClient(), partitionRoutingHelperMock.Object);

            TestHandler testHandler = new TestHandler(async(request, cancellationToken) => {
                ResponseMessage errorResponse = await TestHandler.ReturnStatusCode(HttpStatusCode.Gone);
                errorResponse.Headers.Remove(HttpConstants.HttpHeaders.Continuation); //Clobber original continuation
                return(errorResponse);
            });

            partitionKeyRangeHandler.InnerHandler = testHandler;

            //Pass valid collections path because it is required by DocumentServiceRequest's constructor. This can't be mocked because ToDocumentServiceRequest() is an extension method
            RequestMessage initialRequest = new RequestMessage(HttpMethod.Get, new Uri($"{Paths.DatabasesPathSegment}/test/{Paths.CollectionsPathSegment}/test", UriKind.Relative));

            initialRequest.OperationType = OperationType.ReadFeed;
            initialRequest.Headers.Add(HttpConstants.HttpHeaders.Continuation, Continuation);
            ResponseMessage response = await partitionKeyRangeHandler.SendAsync(initialRequest, CancellationToken.None);

            Assert.IsFalse(response.IsSuccessStatusCode);
            Assert.AreEqual(System.Net.HttpStatusCode.Gone, response.StatusCode);
            //Check if original continuation was restored
            Assert.AreEqual(Continuation, response.Headers.GetValues(HttpConstants.HttpHeaders.Continuation).First());
            Assert.AreEqual(Continuation, initialRequest.Headers.GetValues(HttpConstants.HttpHeaders.Continuation).First());
        }
        private static CosmosClientContext GetMockedClientContext(
            Func <RequestMessage, CancellationToken, Task <ResponseMessage> > handlerFunc)
        {
            CosmosClient        client        = MockCosmosUtil.CreateMockCosmosClient();
            CosmosClientContext clientContext = ClientContextCore.Create(
                client,
                new MockDocumentClient(),
                new CosmosClientOptions());

            Mock <PartitionRoutingHelper> partitionRoutingHelperMock = MockCosmosUtil.GetPartitionRoutingHelperMock("0");
            PartitionKeyRangeHandler      partitionKeyRangeHandler   = new PartitionKeyRangeHandler(client, partitionRoutingHelperMock.Object);

            TestHandler testHandler = new TestHandler(handlerFunc);

            partitionKeyRangeHandler.InnerHandler = testHandler;

            RequestHandler handler = clientContext.RequestHandler.InnerHandler;

            while (handler != null)
            {
                if (handler.InnerHandler is RouterHandler)
                {
                    handler.InnerHandler = new RouterHandler(partitionKeyRangeHandler, testHandler);
                    break;
                }

                handler = handler.InnerHandler;
            }

            return(clientContext);
        }
        public async Task VerifySendUsesOringianlContinuationOnDocumentClientExceptionAfterRetry()
        {
            Mock <PartitionRoutingHelper> partitionRoutingHelperMock = this.GetPartitionRoutingHelperMock();

            //throw a DocumentClientException
            partitionRoutingHelperMock.Setup(m => m.TryAddPartitionKeyRangeToContinuationTokenAsync(
                                                 It.IsAny <INameValueCollection>(),
                                                 It.IsAny <List <Range <string> > >(),
                                                 It.IsAny <IRoutingMapProvider>(),
                                                 It.Is <string>(x => x == CollectionId),
                                                 It.IsAny <ResolvedRangeInfo>(),
                                                 It.IsAny <ITrace>(),
                                                 It.IsAny <RntbdConstants.RntdbEnumerationDirection>()
                                                 )).ThrowsAsync(new DocumentClientException("error", HttpStatusCode.ServiceUnavailable, SubStatusCodes.Unknown));

            PartitionKeyRangeHandler partitionKeyRangeHandler = new PartitionKeyRangeHandler(MockCosmosUtil.CreateMockCosmosClient(), partitionRoutingHelperMock.Object);

            TestHandler testHandler = new TestHandler(async(request, cancellationToken) =>
            {
                ResponseMessage successResponse = await TestHandler.ReturnSuccess();
                successResponse.Headers.Remove(HttpConstants.HttpHeaders.Continuation); //Clobber original continuation
                return(successResponse);
            });

            partitionKeyRangeHandler.InnerHandler = testHandler;

            //Pass valid collections path because it is required by DocumentServiceRequest's constructor. This can't be mocked because ToDocumentServiceRequest() is an extension method
            RequestMessage initialRequest = new RequestMessage(HttpMethod.Get, new Uri($"{Paths.DatabasesPathSegment}/test/{Paths.CollectionsPathSegment}/test", UriKind.Relative))
            {
                OperationType = OperationType.ReadFeed
            };

            initialRequest.Headers.Add(HttpConstants.HttpHeaders.Continuation, Continuation);
            ResponseMessage response = await partitionKeyRangeHandler.SendAsync(initialRequest, CancellationToken.None);

            Assert.IsFalse(response.IsSuccessStatusCode);
            Assert.AreEqual(System.Net.HttpStatusCode.ServiceUnavailable, response.StatusCode);
            //Check if original continuation was restored
            Assert.AreEqual(Continuation, response.Headers.GetValues(HttpConstants.HttpHeaders.Continuation).First());
            Assert.AreEqual(Continuation, initialRequest.Headers.GetValues(HttpConstants.HttpHeaders.Continuation).First());
        }