< Summary

Class:Azure.Search.Documents.Models.SearchContinuationToken
Assembly:Azure.Search.Documents
File(s):C:\Git\azure-sdk-for-net\sdk\search\Azure.Search.Documents\src\Models\SearchContinuationToken.cs
Covered lines:34
Uncovered lines:4
Coverable lines:38
Total lines:101
Line coverage:89.4% (34 of 38)
Covered branches:10
Total branches:16
Branch coverage:62.5% (10 of 16)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.cctor()-100%100%
Serialize(...)-100%100%
Deserialize(...)-81.82%50%

File(s)

C:\Git\azure-sdk-for-net\sdk\search\Azure.Search.Documents\src\Models\SearchContinuationToken.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.IO;
 6using System.Text.Json;
 7using Azure.Core;
 8
 9namespace Azure.Search.Documents.Models
 10{
 11    /// <summary>
 12    /// Creates continuation tokens used for resuming a search that requires
 13    /// multiple requests to return the user's desired data.  This is only to
 14    /// support server-side paging.  Client-side paging should be handled with
 15    /// Skip and Size.
 16    /// </summary>
 17    internal static class SearchContinuationToken
 18    {
 19        private const string ApiVersionName = "apiVersion";
 120        private static readonly JsonEncodedText s_apiVersionEncodedName = JsonEncodedText.Encode(ApiVersionName);
 21
 22        private const string NextLinkName = "nextLink";
 123        private static readonly JsonEncodedText s_nextLinkEncodedName = JsonEncodedText.Encode(NextLinkName);
 24
 25        private const string NextPageParametersName = "nextPageParameters";
 126        private static readonly JsonEncodedText s_nextPageParametersEncodedName = JsonEncodedText.Encode(NextPageParamet
 27
 28        /// <summary>
 29        /// Creates a durable, opaque continuation token that can be provided
 30        /// to users.
 31        /// </summary>
 32        /// <param name="nextPageUri">
 33        /// URI of additional results when making GET requests.
 34        /// </param>
 35        /// <param name="nextPageOptions">
 36        /// <see cref="SearchOptions"/> for additional results when making POST
 37        /// requests.
 38        /// </param>
 39        /// <returns>A continuation token.</returns>
 40        public static string Serialize(Uri nextPageUri, SearchOptions nextPageOptions)
 41        {
 42            // There's no continuation token if there's no next page
 3443            if (nextPageUri == null || nextPageOptions == null)
 44            {
 645                return null;
 46            }
 2847            using MemoryStream buffer = new MemoryStream();
 2848            using (Utf8JsonWriter writer = new Utf8JsonWriter(buffer))
 49            {
 2850                writer.WriteStartObject();
 2851                writer.WriteString(s_apiVersionEncodedName, SearchClientOptions.ContinuationTokenVersion.ToVersionString
 2852                writer.WriteString(s_nextLinkEncodedName, nextPageUri.ToString());
 2853                writer.WritePropertyName(s_nextPageParametersEncodedName);
 2854                writer.WriteObjectValue(nextPageOptions);
 2855                writer.WriteEndObject();
 2856            }
 2857            return Convert.ToBase64String(buffer.ToArray());
 2858        }
 59
 60        /// <summary>
 61        /// Parses a continuation token and returns the corresponding to the
 62        /// next page's <see cref="SearchOptions"/>.
 63        /// </summary>
 64        /// <param name="continuationToken">
 65        /// The serialized continuation token.
 66        /// </param>
 67        /// <returns>The continuation token's next page options.</returns>
 68        public static SearchOptions Deserialize(string continuationToken)
 69        {
 1470            Argument.AssertNotNullOrEmpty(continuationToken, nameof(continuationToken));
 1471            byte[] decoded = Convert.FromBase64String(continuationToken);
 72            try
 73            {
 1474                using JsonDocument json = JsonDocument.Parse(decoded);
 1475                if (json.RootElement.ValueKind == JsonValueKind.Object &&
 1476                    json.RootElement.TryGetProperty(ApiVersionName, out JsonElement apiVersion) &&
 1477                    apiVersion.ValueKind == JsonValueKind.String &&
 1478                    // Today we only validate against a single known version,
 1479                    // but in the future we may want to support a range of
 1480                    // valid continuation token serialization formats.  This
 1481                    // will need to be updated accordingly.
 1482                    string.Equals(
 1483                        apiVersion.GetString(),
 1484                        SearchClientOptions.ContinuationTokenVersion.ToVersionString(),
 1485                        StringComparison.OrdinalIgnoreCase) &&
 1486                    json.RootElement.TryGetProperty(NextPageParametersName, out JsonElement nextPageParams) &&
 1487                    nextPageParams.ValueKind == JsonValueKind.Object)
 88                {
 89                    // We only use the nextPageParameters because we do all of
 90                    // our searching via HTTP POST requests
 1491                    return SearchOptions.DeserializeSearchOptions(nextPageParams);
 92                }
 093            }
 094            catch (JsonException)
 95            {
 096            }
 97
 098            throw new ArgumentException("Invalid continuation token", nameof(continuationToken));
 1499        }
 100    }
 101}