From 0a1a2bf4213e2f9f91d1a05e6c5e63eb6104b1e6 Mon Sep 17 00:00:00 2001 From: Steve Faulkner Date: Thu, 10 Jun 2021 17:29:19 -0700 Subject: [PATCH] Remove QueryUtils.queryAll and fix test (#885) --- src/Common/QueriesClient.ts | 63 ++++++++++-------------- src/Utils/QueryUtils.test.ts | 94 ++---------------------------------- src/Utils/QueryUtils.ts | 31 ------------ 3 files changed, 29 insertions(+), 159 deletions(-) diff --git a/src/Common/QueriesClient.ts b/src/Common/QueriesClient.ts index 23e1ee9e1..dfb31a2f6 100644 --- a/src/Common/QueriesClient.ts +++ b/src/Common/QueriesClient.ts @@ -1,4 +1,3 @@ -import { ItemDefinition, QueryIterator, Resource } from "@azure/cosmos"; import * as _ from "underscore"; import * as DataModels from "../Contracts/DataModels"; import * as ViewModels from "../Contracts/ViewModels"; @@ -7,13 +6,11 @@ import DocumentsTab from "../Explorer/Tabs/DocumentsTab"; import DocumentId from "../Explorer/Tree/DocumentId"; import { userContext } from "../UserContext"; import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils"; -import * as QueryUtils from "../Utils/QueryUtils"; import { BackendDefaults, HttpStatusCodes, SavedQueries } from "./Constants"; import { createCollection } from "./dataAccess/createCollection"; import { createDocument } from "./dataAccess/createDocument"; import { deleteDocument } from "./dataAccess/deleteDocument"; import { queryDocuments } from "./dataAccess/queryDocuments"; -import { queryDocumentsPage } from "./dataAccess/queryDocumentsPage"; import { handleError } from "./ErrorHandlingUtils"; export class QueriesClient { @@ -100,45 +97,35 @@ export class QueriesClient { const options: any = { enableCrossPartitionQuery: true }; const clearMessage = NotificationConsoleUtils.logConsoleProgress("Fetching saved queries"); - const queryIterator: QueryIterator = queryDocuments( + const results = await queryDocuments( SavedQueries.DatabaseName, SavedQueries.CollectionName, this.fetchQueriesQuery(), options - ); - const fetchQueries = async (firstItemIndex: number): Promise => - await queryDocumentsPage(queriesCollection.id(), queryIterator, firstItemIndex); - return QueryUtils.queryAllPages(fetchQueries) - .then( - (results: ViewModels.QueryResults) => { - let queries: DataModels.Query[] = _.map(results.documents, (document: DataModels.Query) => { - if (!document) { - return undefined; - } - const { id, resourceId, query, queryName } = document; - const parsedQuery: DataModels.Query = { - resourceId: resourceId, - queryName: queryName, - query: query, - id: id, - }; - try { - this.validateQuery(parsedQuery); - return parsedQuery; - } catch (error) { - return undefined; - } - }); - queries = _.reject(queries, (parsedQuery: DataModels.Query) => !parsedQuery); - NotificationConsoleUtils.logConsoleInfo("Successfully fetched saved queries"); - return Promise.resolve(queries); - }, - (error: any) => { - handleError(error, "getSavedQueries", "Failed to fetch saved queries"); - return Promise.reject(error); - } - ) - .finally(() => clearMessage()); + ).fetchAll(); + + let queries: DataModels.Query[] = _.map(results.resources, (document: DataModels.Query) => { + if (!document) { + return undefined; + } + const { id, resourceId, query, queryName } = document; + const parsedQuery: DataModels.Query = { + resourceId: resourceId, + queryName: queryName, + query: query, + id: id, + }; + try { + this.validateQuery(parsedQuery); + return parsedQuery; + } catch (error) { + return undefined; + } + }); + queries = _.reject(queries, (parsedQuery: DataModels.Query) => !parsedQuery); + NotificationConsoleUtils.logConsoleInfo("Successfully fetched saved queries"); + clearMessage(); + return queries; } public async deleteQuery(query: DataModels.Query): Promise { diff --git a/src/Utils/QueryUtils.test.ts b/src/Utils/QueryUtils.test.ts index 820a64e49..80ed18620 100644 --- a/src/Utils/QueryUtils.test.ts +++ b/src/Utils/QueryUtils.test.ts @@ -91,97 +91,11 @@ describe("Query Utils", () => { expect(queryStub.getCall(1).args[0]).toBe(0); }); - it("should not perform multiple queries if the first page of results has items", (done) => { + it("should not perform multiple queries if the first page of results has items", async () => { const queryStub = sinon.stub().returns(Q.resolve(queryResultWithItemsInPage)); - QueryUtils.queryPagesUntilContentPresent(0, queryStub).finally(() => { - expect(queryStub.callCount).toBe(1); - expect(queryStub.getCall(0).args[0]).toBe(0); - done(); - }); - }); - - it("should not proceed with subsequent queries if the first one errors out", (done) => { - const queryStub = sinon.stub().returns(Q.reject("Error injected for testing purposes")); - QueryUtils.queryPagesUntilContentPresent(0, queryStub).finally(() => { - expect(queryStub.callCount).toBe(1); - expect(queryStub.getCall(0).args[0]).toBe(0); - done(); - }); - }); - }); - - describe("queryAllPages()", () => { - const queryResultWithNoContinuation: ViewModels.QueryResults = { - documents: [{ a: "123" }], - activityId: "123", - requestCharge: 1, - hasMoreResults: false, - firstItemIndex: 1, - lastItemIndex: 1, - itemCount: 1, - }; - const queryResultWithContinuation: ViewModels.QueryResults = { - documents: [{ b: "123" }], - activityId: "123", - requestCharge: 1, - hasMoreResults: true, - firstItemIndex: 0, - lastItemIndex: 0, - itemCount: 1, - }; - - it("should follow continuation token to fetch all pages", (done) => { - const queryStub = sinon - .stub() - .onFirstCall() - .returns(Q.resolve(queryResultWithContinuation)) - .returns(Q.resolve(queryResultWithNoContinuation)); - QueryUtils.queryAllPages(queryStub).then( - (results: ViewModels.QueryResults) => { - expect(queryStub.callCount).toBe(2); - expect(queryStub.getCall(0).args[0]).toBe(0); - expect(queryStub.getCall(1).args[0]).toBe(1); - expect(results.itemCount).toBe( - queryResultWithContinuation.documents.length + queryResultWithNoContinuation.documents.length - ); - expect(results.requestCharge).toBe( - queryResultWithContinuation.requestCharge + queryResultWithNoContinuation.requestCharge - ); - expect(results.documents).toEqual( - queryResultWithContinuation.documents.concat(queryResultWithNoContinuation.documents) - ); - done(); - }, - (error: any) => { - fail(error); - } - ); - }); - - it("should not perform subsequent fetches when result has no continuation", (done) => { - const queryStub = sinon.stub().returns(Q.resolve(queryResultWithNoContinuation)); - QueryUtils.queryAllPages(queryStub).then( - (results: ViewModels.QueryResults) => { - expect(queryStub.callCount).toBe(1); - expect(queryStub.getCall(0).args[0]).toBe(0); - expect(results.itemCount).toBe(queryResultWithNoContinuation.documents.length); - expect(results.requestCharge).toBe(queryResultWithNoContinuation.requestCharge); - expect(results.documents).toEqual(queryResultWithNoContinuation.documents); - done(); - }, - (error: any) => { - fail(error); - } - ); - }); - - it("should not proceed with subsequent fetches if the first one errors out", (done) => { - const queryStub = sinon.stub().returns(Q.reject("Error injected for testing purposes")); - QueryUtils.queryAllPages(queryStub).finally(() => { - expect(queryStub.callCount).toBe(1); - expect(queryStub.getCall(0).args[0]).toBe(0); - done(); - }); + await QueryUtils.queryPagesUntilContentPresent(0, queryStub); + expect(queryStub.callCount).toBe(1); + expect(queryStub.getCall(0).args[0]).toBe(0); }); }); }); diff --git a/src/Utils/QueryUtils.ts b/src/Utils/QueryUtils.ts index b652df70f..71d8a57a0 100644 --- a/src/Utils/QueryUtils.ts +++ b/src/Utils/QueryUtils.ts @@ -81,34 +81,3 @@ export const queryPagesUntilContentPresent = async ( return await doRequest(firstItemIndex); }; - -export const queryAllPages = async ( - queryItems: (itemIndex: number) => Promise -): Promise => { - const queryResults: ViewModels.QueryResults = { - documents: [], - activityId: undefined, - hasMoreResults: false, - itemCount: 0, - firstItemIndex: 0, - lastItemIndex: 0, - requestCharge: 0, - roundTrips: 0, - }; - const doRequest = async (itemIndex: number): Promise => { - const results = await queryItems(itemIndex); - const { requestCharge, hasMoreResults, itemCount, lastItemIndex, documents } = results; - queryResults.roundTrips = queryResults.roundTrips + 1; - queryResults.requestCharge = Number(queryResults.requestCharge) + Number(requestCharge); - queryResults.hasMoreResults = hasMoreResults; - queryResults.itemCount = queryResults.itemCount + itemCount; - queryResults.lastItemIndex = lastItemIndex; - queryResults.documents = queryResults.documents.concat(documents); - if (queryResults.hasMoreResults) { - return doRequest(queryResults.lastItemIndex + 1); - } - return queryResults; - }; - - return doRequest(0); -};