From 4f0605d6c2f45d7681ff9de6bdca31f93c32f615 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 7 Apr 2021 08:41:44 -0700 Subject: [PATCH] write test to ensure lastRequestId only increments when we expect it to --- src/core/__tests__/ObservableQuery.ts | 47 +++++++++---------- src/core/__tests__/QueryManager/index.ts | 59 ++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 25 deletions(-) diff --git a/src/core/__tests__/ObservableQuery.ts b/src/core/__tests__/ObservableQuery.ts index 6656b1fffc4..d7bf0c9aeeb 100644 --- a/src/core/__tests__/ObservableQuery.ts +++ b/src/core/__tests__/ObservableQuery.ts @@ -15,6 +15,28 @@ import mockQueryManager from '../../utilities/testing/mocking/mockQueryManager'; import mockWatchQuery from '../../utilities/testing/mocking/mockWatchQuery'; import wrap from '../../utilities/testing/wrap'; +export const mockFetchQuery = (queryManager: QueryManager) => { + const fetchQueryObservable = queryManager.fetchQueryObservable; + const fetchQueryByPolicy: QueryManager["fetchQueryByPolicy"] = + (queryManager as any).fetchQueryByPolicy; + + const mock = (original: T) => jest.fn, Parameters>(function () { + return original.apply(queryManager, arguments); + }); + + const mocks = { + fetchQueryObservable: mock(fetchQueryObservable), + fetchQueryByPolicy: mock(fetchQueryByPolicy), + }; + + Object.assign(queryManager, mocks); + + return mocks; +}; + describe('ObservableQuery', () => { // Standard data for all these tests const query = gql` @@ -929,31 +951,6 @@ describe('ObservableQuery', () => { }); describe('refetch', () => { - function mockFetchQuery(queryManager: QueryManager) { - const fetchQueryObservable = queryManager.fetchQueryObservable; - const fetchQueryByPolicy: QueryManager["fetchQueryByPolicy"] = - (queryManager as any).fetchQueryByPolicy; - - const mock = (original: T) => jest.fn< - ReturnType, - Parameters - >(function () { - return original.apply(queryManager, arguments); - }); - - const mocks = { - fetchQueryObservable: mock(fetchQueryObservable), - fetchQueryByPolicy: mock(fetchQueryByPolicy), - }; - - Object.assign(queryManager, mocks); - - return mocks; - } - itAsync('calls fetchRequest with fetchPolicy `network-only` when using a non-networked fetch policy', (resolve, reject) => { const mockedResponses = [ { diff --git a/src/core/__tests__/QueryManager/index.ts b/src/core/__tests__/QueryManager/index.ts index db5669aa2f1..958e348ad42 100644 --- a/src/core/__tests__/QueryManager/index.ts +++ b/src/core/__tests__/QueryManager/index.ts @@ -37,6 +37,7 @@ import subscribeAndCount from '../../../utilities/testing/subscribeAndCount'; import { stripSymbols } from '../../../utilities/testing/stripSymbols'; import { itAsync } from '../../../utilities/testing/itAsync'; import { ApolloClient } from '../../../core' +import { mockFetchQuery } from '../ObservableQuery'; interface MockedMutation { reject: (reason: any) => any; @@ -2720,6 +2721,64 @@ describe('QueryManager', () => { ]).then(resolve, reject); }); + + itAsync('only increments "queryInfo.lastRequestId" when fetching data from network', (resolve, reject) => { + const query = gql` + query query($id: ID!) { + people_one(id: $id) { + name + } + } + `; + const variables = { id: 1 }; + const dataOne = { + people_one: { + name: 'Luke Skywalker', + }, + }; + const mockedResponses = [ + { + request: { query, variables }, + result: { data: dataOne }, + }, + ]; + + const queryManager = mockQueryManager(reject, ...mockedResponses); + const queryOptions: WatchQueryOptions = { + query, + variables, + fetchPolicy: 'cache-and-network', + }; + const observable = queryManager.watchQuery(queryOptions); + + const mocks = mockFetchQuery(queryManager); + const queryId = '1'; + const getQuery: QueryManager["getQuery"] = + (queryManager as any).getQuery.bind(queryManager); + + subscribeAndCount(reject, observable, async (handleCount) => { + const query = getQuery(queryId); + const fqbpCalls = mocks.fetchQueryByPolicy.mock.calls; + expect(query.lastRequestId).toEqual(1); + expect(fqbpCalls.length).toBe(1); + + // Simulate updating the options of the query, which will trigger + // fetchQueryByPolicy, but it should just read from cache and not + // update "queryInfo.lastRequestId". For more information, see + // https://github.com/apollographql/apollo-client/pull/7956#issue-610298427 + await observable.setOptions({ + ...queryOptions, + fetchPolicy: 'cache-first', + }); + + // "fetchQueryByPolicy" was called, but "lastRequestId" does not update + // since it was able to read from cache. + expect(query.lastRequestId).toEqual(1); + expect(fqbpCalls.length).toBe(2); + resolve(); + }); + }) + describe('polling queries', () => { itAsync('allows you to poll queries', (resolve, reject) => { const query = gql`