From 5c092635034b49cd073557fcb5c284bad1645d1f Mon Sep 17 00:00:00 2001 From: jdecroock Date: Fri, 7 Jul 2023 15:12:59 +0200 Subject: [PATCH] add tests --- .../src/extras/relayPagination.test.ts | 2484 +++++++++-------- .../src/extras/simplePagination.test.ts | 844 +++--- 2 files changed, 1771 insertions(+), 1557 deletions(-) diff --git a/exchanges/graphcache/src/extras/relayPagination.test.ts b/exchanges/graphcache/src/extras/relayPagination.test.ts index f6f4fdaa64..29a1486f42 100644 --- a/exchanges/graphcache/src/extras/relayPagination.test.ts +++ b/exchanges/graphcache/src/extras/relayPagination.test.ts @@ -1,5 +1,5 @@ import { gql } from '@urql/core'; -import { it, expect } from 'vitest'; +import { it, expect, describe } from 'vitest'; import { __initAnd_query as query } from '../operations/query'; import { __initAnd_write as write } from '../operations/write'; import { Store } from '../store/store'; @@ -19,1458 +19,1598 @@ function itemEdge(numItem: number) { }; } -it('works with forward pagination', () => { - const Pagination = gql` - query ($cursor: String) { - __typename - items(first: 1, after: $cursor) { +describe('as resolver', () => { + it('works with forward pagination', () => { + const Pagination = gql` + query ($cursor: String) { __typename - edges { + items(first: 1, after: $cursor) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasNextPage - endCursor + pageInfo { + __typename + hasNextPage + endCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const pageOne = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1)], - nodes: [itemNode(1)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - endCursor: '1', + const pageOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1)], + nodes: [itemNode(1)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + endCursor: '1', + }, }, - }, - }; + }; - const pageTwo = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(2)], - nodes: [itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - endCursor: null, + const pageTwo = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(2)], + nodes: [itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: false, + endCursor: null, + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { cursor: null } }, pageOne); - write(store, { query: Pagination, variables: { cursor: '1' } }, pageTwo); + write(store, { query: Pagination, variables: { cursor: null } }, pageOne); + write(store, { query: Pagination, variables: { cursor: '1' } }, pageTwo); - const res = query(store, { query: Pagination }); + const res = query(store, { query: Pagination }); - expect(res.partial).toBe(false); - expect(res.data).toEqual({ - ...pageTwo, - items: { - ...pageTwo.items, - edges: [pageOne.items.edges[0], pageTwo.items.edges[0]], - nodes: [pageOne.items.nodes[0], pageTwo.items.nodes[0]], - }, + expect(res.partial).toBe(false); + expect(res.data).toEqual({ + ...pageTwo, + items: { + ...pageTwo.items, + edges: [pageOne.items.edges[0], pageTwo.items.edges[0]], + nodes: [pageOne.items.nodes[0], pageTwo.items.nodes[0]], + }, + }); }); -}); -it('works with backwards pagination', () => { - const Pagination = gql` - query ($cursor: String) { - __typename - items(last: 1, before: $cursor) { + it('works with backwards pagination', () => { + const Pagination = gql` + query ($cursor: String) { __typename - edges { + items(last: 1, before: $cursor) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasPreviousPage - startCursor + pageInfo { + __typename + hasPreviousPage + startCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const pageOne = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(2)], - nodes: [itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasPreviousPage: true, - startCursor: '2', + const pageOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(2)], + nodes: [itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasPreviousPage: true, + startCursor: '2', + }, }, - }, - }; + }; - const pageTwo = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1)], - nodes: [itemNode(1)], - pageInfo: { - __typename: 'PageInfo', - hasPreviousPage: false, - startCursor: null, + const pageTwo = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1)], + nodes: [itemNode(1)], + pageInfo: { + __typename: 'PageInfo', + hasPreviousPage: false, + startCursor: null, + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { cursor: null } }, pageOne); - write(store, { query: Pagination, variables: { cursor: '2' } }, pageTwo); + write(store, { query: Pagination, variables: { cursor: null } }, pageOne); + write(store, { query: Pagination, variables: { cursor: '2' } }, pageTwo); - const res = query(store, { query: Pagination }); + const res = query(store, { query: Pagination }); - expect(res.partial).toBe(false); - expect(res.data).toEqual({ - ...pageTwo, - items: { - ...pageTwo.items, - edges: [pageTwo.items.edges[0], pageOne.items.edges[0]], - nodes: [pageTwo.items.nodes[0], pageOne.items.nodes[0]], - }, + expect(res.partial).toBe(false); + expect(res.data).toEqual({ + ...pageTwo, + items: { + ...pageTwo.items, + edges: [pageTwo.items.edges[0], pageOne.items.edges[0]], + nodes: [pageTwo.items.nodes[0], pageOne.items.nodes[0]], + }, + }); }); -}); -it('handles duplicate edges', () => { - const Pagination = gql` - query ($cursor: String) { - __typename - items(first: 2, after: $cursor) { + it('handles duplicate edges', () => { + const Pagination = gql` + query ($cursor: String) { __typename - edges { + items(first: 2, after: $cursor) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasNextPage - endCursor + pageInfo { + __typename + hasNextPage + endCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const pageOne = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1), itemEdge(2)], - nodes: [itemNode(1), itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - endCursor: '2', + const pageOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1), itemEdge(2)], + nodes: [itemNode(1), itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + endCursor: '2', + }, }, - }, - }; + }; - const pageTwo = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(2), itemEdge(3)], - nodes: [itemNode(2), itemNode(3)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - endCursor: null, + const pageTwo = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(2), itemEdge(3)], + nodes: [itemNode(2), itemNode(3)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: false, + endCursor: null, + }, }, - }, - }; + }; + + write(store, { query: Pagination, variables: { cursor: null } }, pageOne); + write(store, { query: Pagination, variables: { cursor: '1' } }, pageTwo); + + const res = query(store, { query: Pagination }); - write(store, { query: Pagination, variables: { cursor: null } }, pageOne); - write(store, { query: Pagination, variables: { cursor: '1' } }, pageTwo); - - const res = query(store, { query: Pagination }); - - expect(res.partial).toBe(false); - expect(res.data).toEqual({ - ...pageTwo, - items: { - ...pageTwo.items, - edges: [ - pageOne.items.edges[0], - pageTwo.items.edges[0], - pageTwo.items.edges[1], - ], - nodes: [ - pageOne.items.nodes[0], - pageTwo.items.nodes[0], - pageTwo.items.nodes[1], - ], - }, + expect(res.partial).toBe(false); + expect(res.data).toEqual({ + ...pageTwo, + items: { + ...pageTwo.items, + edges: [ + pageOne.items.edges[0], + pageTwo.items.edges[0], + pageTwo.items.edges[1], + ], + nodes: [ + pageOne.items.nodes[0], + pageTwo.items.nodes[0], + pageTwo.items.nodes[1], + ], + }, + }); }); -}); -it('works with simultaneous forward and backward pagination (outwards merging)', () => { - const Pagination = gql` - query ($first: Int, $last: Int, $before: String, $after: String) { - __typename - items(first: $first, last: $last, before: $before, after: $after) { + it('works with simultaneous forward and backward pagination (outwards merging)', () => { + const Pagination = gql` + query ($first: Int, $last: Int, $before: String, $after: String) { __typename - edges { + items(first: $first, last: $last, before: $before, after: $after) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasPreviousPage - hasNextPage - startCursor - endCursor + pageInfo { + __typename + hasPreviousPage + hasNextPage + startCursor + endCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination({ mergeMode: 'outwards' }), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination({ mergeMode: 'outwards' }), + }, }, - }, - }); + }); - const pageOne = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1)], - nodes: [itemNode(1)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: false, - startCursor: null, - endCursor: '1', + const pageOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1)], + nodes: [itemNode(1)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: false, + startCursor: null, + endCursor: '1', + }, }, - }, - }; + }; - const pageTwo = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(2)], - nodes: [itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: true, - startCursor: '2', - endCursor: '2', + const pageTwo = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(2)], + nodes: [itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: true, + startCursor: '2', + endCursor: '2', + }, }, - }, - }; + }; - const pageThree = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(-1)], - nodes: [itemNode(-1)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - hasPreviousPage: true, - startCursor: '-1', - endCursor: null, + const pageThree = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(-1)], + nodes: [itemNode(-1)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: false, + hasPreviousPage: true, + startCursor: '-1', + endCursor: null, + }, }, - }, - }; - - write( - store, - { query: Pagination, variables: { after: '1', first: 1 } }, - pageOne - ); - write( - store, - { query: Pagination, variables: { after: '2', first: 1 } }, - pageTwo - ); - write( - store, - { query: Pagination, variables: { before: '1', last: 1 } }, - pageThree - ); - - const res = query(store, { - query: Pagination, - variables: { before: '1', last: 1 }, - }); - - expect(res.partial).toBe(false); - expect(res.data).toEqual({ - ...pageThree, - items: { - ...pageThree.items, - edges: [ - pageThree.items.edges[0], - pageOne.items.edges[0], - pageTwo.items.edges[0], - ], - nodes: [ - pageThree.items.nodes[0], - pageOne.items.nodes[0], - pageTwo.items.nodes[0], - ], - pageInfo: { - ...pageThree.items.pageInfo, - hasPreviousPage: true, - hasNextPage: true, - startCursor: '-1', - endCursor: '2', + }; + + write( + store, + { query: Pagination, variables: { after: '1', first: 1 } }, + pageOne + ); + write( + store, + { query: Pagination, variables: { after: '2', first: 1 } }, + pageTwo + ); + write( + store, + { query: Pagination, variables: { before: '1', last: 1 } }, + pageThree + ); + + const res = query(store, { + query: Pagination, + variables: { before: '1', last: 1 }, + }); + + expect(res.partial).toBe(false); + expect(res.data).toEqual({ + ...pageThree, + items: { + ...pageThree.items, + edges: [ + pageThree.items.edges[0], + pageOne.items.edges[0], + pageTwo.items.edges[0], + ], + nodes: [ + pageThree.items.nodes[0], + pageOne.items.nodes[0], + pageTwo.items.nodes[0], + ], + pageInfo: { + ...pageThree.items.pageInfo, + hasPreviousPage: true, + hasNextPage: true, + startCursor: '-1', + endCursor: '2', + }, }, - }, + }); }); -}); -it('works with simultaneous forward and backward pagination (inwards merging)', () => { - const Pagination = gql` - query ($first: Int, $last: Int, $before: String, $after: String) { - __typename - items(first: $first, last: $last, before: $before, after: $after) { + it('works with simultaneous forward and backward pagination (inwards merging)', () => { + const Pagination = gql` + query ($first: Int, $last: Int, $before: String, $after: String) { __typename - edges { + items(first: $first, last: $last, before: $before, after: $after) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasPreviousPage - hasNextPage - startCursor - endCursor + pageInfo { + __typename + hasPreviousPage + hasNextPage + startCursor + endCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination({ mergeMode: 'inwards' }), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination({ mergeMode: 'inwards' }), + }, }, - }, - }); + }); - const pageOne = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1)], - nodes: [itemNode(1)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: false, - startCursor: null, - endCursor: '1', + const pageOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1)], + nodes: [itemNode(1)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: false, + startCursor: null, + endCursor: '1', + }, }, - }, - }; + }; - const pageTwo = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(2)], - nodes: [itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: true, - startCursor: '2', - endCursor: '2', + const pageTwo = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(2)], + nodes: [itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: true, + startCursor: '2', + endCursor: '2', + }, }, - }, - }; + }; - const pageThree = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(-1)], - nodes: [itemNode(-1)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - hasPreviousPage: true, - startCursor: '-1', - endCursor: null, + const pageThree = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(-1)], + nodes: [itemNode(-1)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: false, + hasPreviousPage: true, + startCursor: '-1', + endCursor: null, + }, }, - }, - }; - - write( - store, - { query: Pagination, variables: { after: '1', first: 1 } }, - pageOne - ); - write( - store, - { query: Pagination, variables: { after: '2', first: 1 } }, - pageTwo - ); - write( - store, - { query: Pagination, variables: { before: '1', last: 1 } }, - pageThree - ); - - const res = query(store, { - query: Pagination, - variables: { before: '1', last: 1 }, - }); - - expect(res.partial).toBe(false); - expect(res.data).toEqual({ - ...pageThree, - items: { - ...pageThree.items, - edges: [ - pageOne.items.edges[0], - pageTwo.items.edges[0], - pageThree.items.edges[0], - ], - nodes: [ - pageOne.items.nodes[0], - pageTwo.items.nodes[0], - pageThree.items.nodes[0], - ], - pageInfo: { - ...pageThree.items.pageInfo, - hasPreviousPage: true, - hasNextPage: true, - startCursor: '-1', - endCursor: '2', + }; + + write( + store, + { query: Pagination, variables: { after: '1', first: 1 } }, + pageOne + ); + write( + store, + { query: Pagination, variables: { after: '2', first: 1 } }, + pageTwo + ); + write( + store, + { query: Pagination, variables: { before: '1', last: 1 } }, + pageThree + ); + + const res = query(store, { + query: Pagination, + variables: { before: '1', last: 1 }, + }); + + expect(res.partial).toBe(false); + expect(res.data).toEqual({ + ...pageThree, + items: { + ...pageThree.items, + edges: [ + pageOne.items.edges[0], + pageTwo.items.edges[0], + pageThree.items.edges[0], + ], + nodes: [ + pageOne.items.nodes[0], + pageTwo.items.nodes[0], + pageThree.items.nodes[0], + ], + pageInfo: { + ...pageThree.items.pageInfo, + hasPreviousPage: true, + hasNextPage: true, + startCursor: '-1', + endCursor: '2', + }, }, - }, + }); }); -}); -it('prevents overlapping of pagination on different arguments', () => { - const Pagination = gql` - query ($filter: String) { - items(first: 1, filter: $filter) { - __typename - edges { + it('prevents overlapping of pagination on different arguments', () => { + const Pagination = gql` + query ($filter: String) { + items(first: 1, filter: $filter) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasNextPage - endCursor + pageInfo { + __typename + hasNextPage + endCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const page = withId => ({ - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(withId)], - nodes: [itemNode(withId)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - endCursor: null, + const page = withId => ({ + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(withId)], + nodes: [itemNode(withId)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: false, + endCursor: null, + }, }, - }, - }); - - write( - store, - { query: Pagination, variables: { filter: 'one' } }, - page('one') - ); - write( - store, - { query: Pagination, variables: { filter: 'two' } }, - page('two') - ); - - const resOne = query(store, { - query: Pagination, - variables: { filter: 'one' }, + }); + + write( + store, + { query: Pagination, variables: { filter: 'one' } }, + page('one') + ); + write( + store, + { query: Pagination, variables: { filter: 'two' } }, + page('two') + ); + + const resOne = query(store, { + query: Pagination, + variables: { filter: 'one' }, + }); + const resTwo = query(store, { + query: Pagination, + variables: { filter: 'two' }, + }); + const resThree = query(store, { + query: Pagination, + variables: { filter: 'three' }, + }); + + expect(resOne.data).toHaveProperty('items.edges[0].node.id', 'one'); + expect(resOne.data).toHaveProperty('items.edges.length', 1); + + expect(resTwo.data).toHaveProperty('items.edges[0].node.id', 'two'); + expect(resTwo.data).toHaveProperty('items.edges.length', 1); + + expect(resThree.data).toEqual(null); }); - const resTwo = query(store, { - query: Pagination, - variables: { filter: 'two' }, - }); - const resThree = query(store, { - query: Pagination, - variables: { filter: 'three' }, - }); - - expect(resOne.data).toHaveProperty('items.edges[0].node.id', 'one'); - expect(resOne.data).toHaveProperty('items.edges.length', 1); - - expect(resTwo.data).toHaveProperty('items.edges[0].node.id', 'two'); - expect(resTwo.data).toHaveProperty('items.edges.length', 1); - expect(resThree.data).toEqual(null); -}); - -it('returns an empty array of edges when the cache has zero edges stored', () => { - const Pagination = gql` - query { - items(first: 1) { - __typename - edges { - __typename - } - nodes { + it('returns an empty array of edges when the cache has zero edges stored', () => { + const Pagination = gql` + query { + items(first: 1) { __typename + edges { + __typename + } + nodes { + __typename + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); - - write( - store, - { query: Pagination }, - { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [], - nodes: [], - }, - } - ); + }); + + write( + store, + { query: Pagination }, + { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [], + nodes: [], + }, + } + ); - const res = query(store, { - query: Pagination, - }); + const res = query(store, { + query: Pagination, + }); - expect(res.data).toHaveProperty('items', { - __typename: 'ItemsConnection', - edges: [], - nodes: [], + expect(res.data).toHaveProperty('items', { + __typename: 'ItemsConnection', + edges: [], + nodes: [], + }); }); -}); -it('returns other fields on the same level as the edges', () => { - const Pagination = gql` - query { - __typename - items(first: 1) { + it('returns other fields on the same level as the edges', () => { + const Pagination = gql` + query { __typename - totalCount + items(first: 1) { + __typename + totalCount + } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); - - write( - store, - { query: Pagination }, - { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - totalCount: 2, - }, - } - ); + }); + + write( + store, + { query: Pagination }, + { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + totalCount: 2, + }, + } + ); - const resOne = query(store, { - query: Pagination, - }); + const resOne = query(store, { + query: Pagination, + }); - expect(resOne.data).toHaveProperty('items', { - __typename: 'ItemsConnection', - totalCount: 2, + expect(resOne.data).toHaveProperty('items', { + __typename: 'ItemsConnection', + totalCount: 2, + }); }); -}); -it('returns a subset of the cached items if the query requests less items than the cached ones', () => { - const Pagination = gql` - query ($first: Int, $last: Int, $before: String, $after: String) { - __typename - items(first: $first, last: $last, before: $before, after: $after) { + it('returns a subset of the cached items if the query requests less items than the cached ones', () => { + const Pagination = gql` + query ($first: Int, $last: Int, $before: String, $after: String) { __typename - edges { + items(first: $first, last: $last, before: $before, after: $after) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasPreviousPage - hasNextPage - startCursor - endCursor + pageInfo { + __typename + hasPreviousPage + hasNextPage + startCursor + endCursor + } } } - } - `; - - const store = new Store({ - schema: require('../test-utils/relayPagination_schema.json'), - resolvers: { - Query: { - items: relayPagination({ mergeMode: 'outwards' }), + `; + + const store = new Store({ + schema: require('../test-utils/relayPagination_schema.json'), + resolvers: { + Query: { + items: relayPagination({ mergeMode: 'outwards' }), + }, }, - }, - }); + }); - const results = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1), itemEdge(2), itemEdge(3), itemEdge(4), itemEdge(5)], - nodes: [itemNode(1), itemNode(2), itemNode(3), itemNode(4), itemNode(5)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: false, - startCursor: '1', - endCursor: '5', + const results = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [ + itemEdge(1), + itemEdge(2), + itemEdge(3), + itemEdge(4), + itemEdge(5), + ], + nodes: [ + itemNode(1), + itemNode(2), + itemNode(3), + itemNode(4), + itemNode(5), + ], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: false, + startCursor: '1', + endCursor: '5', + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { first: 2 } }, results); + write(store, { query: Pagination, variables: { first: 2 } }, results); - const res = query(store, { - query: Pagination, - variables: { first: 2 }, - }); + const res = query(store, { + query: Pagination, + variables: { first: 2 }, + }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(results); -}); + expect(res.partial).toBe(false); + expect(res.data).toEqual(results); + }); -it("returns the cached items even if they don't fullfil the query", () => { - const Pagination = gql` - query ($first: Int, $last: Int, $before: String, $after: String) { - __typename - items(first: $first, last: $last, before: $before, after: $after) { + it("returns the cached items even if they don't fullfil the query", () => { + const Pagination = gql` + query ($first: Int, $last: Int, $before: String, $after: String) { __typename - edges { + items(first: $first, last: $last, before: $before, after: $after) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasPreviousPage - hasNextPage - startCursor - endCursor + pageInfo { + __typename + hasPreviousPage + hasNextPage + startCursor + endCursor + } } } - } - `; - - const store = new Store({ - schema: require('../test-utils/relayPagination_schema.json'), - resolvers: { - Query: { - items: relayPagination(), + `; + + const store = new Store({ + schema: require('../test-utils/relayPagination_schema.json'), + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const results = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1), itemEdge(2), itemEdge(3), itemEdge(4), itemEdge(5)], - nodes: [itemNode(1), itemNode(2), itemNode(3), itemNode(4), itemNode(5)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: false, - startCursor: '1', - endCursor: '5', + const results = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [ + itemEdge(1), + itemEdge(2), + itemEdge(3), + itemEdge(4), + itemEdge(5), + ], + nodes: [ + itemNode(1), + itemNode(2), + itemNode(3), + itemNode(4), + itemNode(5), + ], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: false, + startCursor: '1', + endCursor: '5', + }, }, - }, - }; + }; - write( - store, - { query: Pagination, variables: { after: '3', first: 3, last: 3 } }, - results - ); + write( + store, + { query: Pagination, variables: { after: '3', first: 3, last: 3 } }, + results + ); - const res = query(store, { - query: Pagination, - variables: { after: '3', first: 3, last: 3 }, - }); + const res = query(store, { + query: Pagination, + variables: { after: '3', first: 3, last: 3 }, + }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(results); -}); + expect(res.partial).toBe(false); + expect(res.data).toEqual(results); + }); -it('returns the cached items even when they come from a different query', () => { - const Pagination = gql` - query ($first: Int, $last: Int, $before: String, $after: String) { - __typename - items(first: $first, last: $last, before: $before, after: $after) { + it('returns the cached items even when they come from a different query', () => { + const Pagination = gql` + query ($first: Int, $last: Int, $before: String, $after: String) { __typename - edges { + items(first: $first, last: $last, before: $before, after: $after) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasPreviousPage - hasNextPage - startCursor - endCursor + pageInfo { + __typename + hasPreviousPage + hasNextPage + startCursor + endCursor + } } } - } - `; - - const store = new Store({ - schema: require('../test-utils/relayPagination_schema.json'), - resolvers: { - Query: { - items: relayPagination(), + `; + + const store = new Store({ + schema: require('../test-utils/relayPagination_schema.json'), + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const results = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1), itemEdge(2), itemEdge(3), itemEdge(4), itemEdge(5)], - nodes: [itemNode(1), itemNode(2), itemNode(3), itemNode(4), itemNode(5)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: false, - startCursor: '1', - endCursor: '5', + const results = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [ + itemEdge(1), + itemEdge(2), + itemEdge(3), + itemEdge(4), + itemEdge(5), + ], + nodes: [ + itemNode(1), + itemNode(2), + itemNode(3), + itemNode(4), + itemNode(5), + ], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: false, + startCursor: '1', + endCursor: '5', + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { first: 5 } }, results); + write(store, { query: Pagination, variables: { first: 5 } }, results); - const res = query(store, { - query: Pagination, - variables: { after: '3', first: 2, last: 2 }, - }); + const res = query(store, { + query: Pagination, + variables: { after: '3', first: 2, last: 2 }, + }); - expect(res.partial).toBe(true); - expect(res.data).toEqual(results); -}); + expect(res.partial).toBe(true); + expect(res.data).toEqual(results); + }); -it('caches and retrieves correctly queries with inwards pagination', () => { - const Pagination = gql` - query ($first: Int, $last: Int, $before: String, $after: String) { - __typename - items(first: $first, last: $last, before: $before, after: $after) { + it('caches and retrieves correctly queries with inwards pagination', () => { + const Pagination = gql` + query ($first: Int, $last: Int, $before: String, $after: String) { __typename - edges { + items(first: $first, last: $last, before: $before, after: $after) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasPreviousPage - hasNextPage - startCursor - endCursor + pageInfo { + __typename + hasPreviousPage + hasNextPage + startCursor + endCursor + } } } - } - `; - - const store = new Store({ - schema: require('../test-utils/relayPagination_schema.json'), - resolvers: { - Query: { - items: relayPagination(), + `; + + const store = new Store({ + schema: require('../test-utils/relayPagination_schema.json'), + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const results = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1), itemEdge(2), itemEdge(3), itemEdge(4), itemEdge(5)], - nodes: [itemNode(1), itemNode(2), itemNode(3), itemNode(4), itemNode(5)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: false, - startCursor: '1', - endCursor: '5', + const results = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [ + itemEdge(1), + itemEdge(2), + itemEdge(3), + itemEdge(4), + itemEdge(5), + ], + nodes: [ + itemNode(1), + itemNode(2), + itemNode(3), + itemNode(4), + itemNode(5), + ], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: false, + startCursor: '1', + endCursor: '5', + }, }, - }, - }; + }; - write( - store, - { query: Pagination, variables: { after: '2', first: 2, last: 2 } }, - results - ); + write( + store, + { query: Pagination, variables: { after: '2', first: 2, last: 2 } }, + results + ); - const res = query(store, { - query: Pagination, - variables: { after: '2', first: 2, last: 2 }, - }); + const res = query(store, { + query: Pagination, + variables: { after: '2', first: 2, last: 2 }, + }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(results); -}); + expect(res.partial).toBe(false); + expect(res.data).toEqual(results); + }); -it('does not include a previous result when adding parameters', () => { - const Pagination = gql` - query ($first: Int, $filter: String) { - __typename - items(first: $first, filter: $filter) { + it('does not include a previous result when adding parameters', () => { + const Pagination = gql` + query ($first: Int, $filter: String) { __typename - edges { + items(first: $first, filter: $filter) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasPreviousPage - hasNextPage - startCursor - endCursor + pageInfo { + __typename + hasPreviousPage + hasNextPage + startCursor + endCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const results = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1), itemEdge(2)], - nodes: [itemNode(1), itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: false, - startCursor: '1', - endCursor: '2', + const results = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1), itemEdge(2)], + nodes: [itemNode(1), itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: false, + startCursor: '1', + endCursor: '2', + }, }, - }, - }; + }; - const results2 = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [], - nodes: [], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - hasPreviousPage: false, - startCursor: '1', - endCursor: '2', + const results2 = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [], + nodes: [], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: false, + hasPreviousPage: false, + startCursor: '1', + endCursor: '2', + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { first: 2 } }, results); + write(store, { query: Pagination, variables: { first: 2 } }, results); - write( - store, - { query: Pagination, variables: { first: 2, filter: 'b' } }, - results2 - ); + write( + store, + { query: Pagination, variables: { first: 2, filter: 'b' } }, + results2 + ); - const res = query(store, { - query: Pagination, - variables: { first: 2, filter: 'b' }, + const res = query(store, { + query: Pagination, + variables: { first: 2, filter: 'b' }, + }); + expect(res.data).toEqual(results2); }); - expect(res.data).toEqual(results2); -}); -it('Works with edges absent from query', () => { - const Pagination = gql` - query ($first: Int, $last: Int, $before: String, $after: String) { - __typename - items(first: $first, last: $last, before: $before, after: $after) { + it('Works with edges absent from query', () => { + const Pagination = gql` + query ($first: Int, $last: Int, $before: String, $after: String) { __typename - nodes { + items(first: $first, last: $last, before: $before, after: $after) { __typename - id - } - pageInfo { - __typename - hasPreviousPage - hasNextPage - startCursor - endCursor + nodes { + __typename + id + } + pageInfo { + __typename + hasPreviousPage + hasNextPage + startCursor + endCursor + } } } - } - `; - - const store = new Store({ - schema: require('../test-utils/relayPagination_schema.json'), - resolvers: { - Query: { - items: relayPagination({ mergeMode: 'outwards' }), + `; + + const store = new Store({ + schema: require('../test-utils/relayPagination_schema.json'), + resolvers: { + Query: { + items: relayPagination({ mergeMode: 'outwards' }), + }, }, - }, - }); + }); - const results = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - nodes: [itemNode(1), itemNode(2), itemNode(3), itemNode(4), itemNode(5)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: false, - startCursor: '1', - endCursor: '5', + const results = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + nodes: [ + itemNode(1), + itemNode(2), + itemNode(3), + itemNode(4), + itemNode(5), + ], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: false, + startCursor: '1', + endCursor: '5', + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { first: 2 } }, results); + write(store, { query: Pagination, variables: { first: 2 } }, results); - const res = query(store, { - query: Pagination, - variables: { first: 2 }, - }); + const res = query(store, { + query: Pagination, + variables: { first: 2 }, + }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(results); -}); + expect(res.partial).toBe(false); + expect(res.data).toEqual(results); + }); -it('Works with nodes absent from query', () => { - const Pagination = gql` - query ($first: Int, $last: Int, $before: String, $after: String) { - __typename - items(first: $first, last: $last, before: $before, after: $after) { + it('Works with nodes absent from query', () => { + const Pagination = gql` + query ($first: Int, $last: Int, $before: String, $after: String) { __typename - edges { + items(first: $first, last: $last, before: $before, after: $after) { __typename - node { + edges { __typename - id + node { + __typename + id + } + } + pageInfo { + __typename + hasPreviousPage + hasNextPage + startCursor + endCursor } - } - pageInfo { - __typename - hasPreviousPage - hasNextPage - startCursor - endCursor } } - } - `; - - const store = new Store({ - schema: require('../test-utils/relayPagination_schema.json'), - resolvers: { - Query: { - items: relayPagination({ mergeMode: 'outwards' }), + `; + + const store = new Store({ + schema: require('../test-utils/relayPagination_schema.json'), + resolvers: { + Query: { + items: relayPagination({ mergeMode: 'outwards' }), + }, }, - }, - }); + }); - const results = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1), itemEdge(2), itemEdge(3), itemEdge(4), itemEdge(5)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - hasPreviousPage: false, - startCursor: '1', - endCursor: '5', + const results = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [ + itemEdge(1), + itemEdge(2), + itemEdge(3), + itemEdge(4), + itemEdge(5), + ], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + hasPreviousPage: false, + startCursor: '1', + endCursor: '5', + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { first: 2 } }, results); + write(store, { query: Pagination, variables: { first: 2 } }, results); - const res = query(store, { - query: Pagination, - variables: { first: 2 }, - }); + const res = query(store, { + query: Pagination, + variables: { first: 2 }, + }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(results); -}); + expect(res.partial).toBe(false); + expect(res.data).toEqual(results); + }); -it('handles subsequent queries with larger last values', () => { - const Pagination = gql` - query ($last: Int!) { - __typename - items(last: $last) { + it('handles subsequent queries with larger last values', () => { + const Pagination = gql` + query ($last: Int!) { __typename - edges { + items(last: $last) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasPreviousPage - startCursor + pageInfo { + __typename + hasPreviousPage + startCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const pageOne = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(2)], - nodes: [itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasPreviousPage: true, - startCursor: '2', + const pageOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(2)], + nodes: [itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasPreviousPage: true, + startCursor: '2', + }, }, - }, - }; + }; - const pageTwo = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1), itemEdge(2)], - nodes: [itemNode(1), itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasPreviousPage: false, - startCursor: '1', + const pageTwo = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1), itemEdge(2)], + nodes: [itemNode(1), itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasPreviousPage: false, + startCursor: '1', + }, }, - }, - }; + }; - const pageThree = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(0), itemEdge(1), itemEdge(2)], - nodes: [itemNode(0), itemNode(1), itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasPreviousPage: false, - startCursor: '0', + const pageThree = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(0), itemEdge(1), itemEdge(2)], + nodes: [itemNode(0), itemNode(1), itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasPreviousPage: false, + startCursor: '0', + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { last: 1 } }, pageOne); - write(store, { query: Pagination, variables: { last: 2 } }, pageTwo); + write(store, { query: Pagination, variables: { last: 1 } }, pageOne); + write(store, { query: Pagination, variables: { last: 2 } }, pageTwo); - let res = query(store, { query: Pagination, variables: { last: 2 } }); + let res = query(store, { query: Pagination, variables: { last: 2 } }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(pageTwo); + expect(res.partial).toBe(false); + expect(res.data).toEqual(pageTwo); - write(store, { query: Pagination, variables: { last: 3 } }, pageThree); + write(store, { query: Pagination, variables: { last: 3 } }, pageThree); - res = query(store, { query: Pagination, variables: { last: 3 } }); + res = query(store, { query: Pagination, variables: { last: 3 } }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(pageThree); -}); + expect(res.partial).toBe(false); + expect(res.data).toEqual(pageThree); + }); -it('handles subsequent queries with larger first values', () => { - const Pagination = gql` - query ($first: Int!) { - __typename - items(first: $first) { + it('handles subsequent queries with larger first values', () => { + const Pagination = gql` + query ($first: Int!) { __typename - edges { + items(first: $first) { __typename - node { + edges { + __typename + node { + __typename + id + } + } + nodes { __typename id } - } - nodes { - __typename - id - } - pageInfo { - __typename - hasNextPage - endCursor + pageInfo { + __typename + hasNextPage + endCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const pageOne = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1)], - nodes: [itemNode(1)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: true, - endCursor: '1', + const pageOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1)], + nodes: [itemNode(1)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + endCursor: '1', + }, }, - }, - }; + }; - const pageTwo = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - edges: [itemEdge(1), itemEdge(2)], - nodes: [itemNode(1), itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - endCursor: '2', + const pageTwo = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1), itemEdge(2)], + nodes: [itemNode(1), itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: false, + endCursor: '2', + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { first: 1 } }, pageOne); - write(store, { query: Pagination, variables: { first: 2 } }, pageTwo); + write(store, { query: Pagination, variables: { first: 1 } }, pageOne); + write(store, { query: Pagination, variables: { first: 2 } }, pageTwo); - const res = query(store, { query: Pagination, variables: { first: 2 } }); + const res = query(store, { query: Pagination, variables: { first: 2 } }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(pageTwo); -}); + expect(res.partial).toBe(false); + expect(res.data).toEqual(pageTwo); + }); -it('ignores empty pages when paginating', () => { - const PaginationForward = gql` - query ($first: Int!, $after: String) { - __typename - items(first: $first, after: $after) { + it('ignores empty pages when paginating', () => { + const PaginationForward = gql` + query ($first: Int!, $after: String) { __typename - nodes { + items(first: $first, after: $after) { __typename - id - } - pageInfo { - __typename - startCursor - endCursor + nodes { + __typename + id + } + pageInfo { + __typename + startCursor + endCursor + } } } - } - `; - const PaginationBackward = gql` - query ($last: Int!, $before: String) { - __typename - items(last: $last, before: $before) { + `; + const PaginationBackward = gql` + query ($last: Int!, $before: String) { __typename - nodes { + items(last: $last, before: $before) { __typename - id - } - pageInfo { - __typename - startCursor - endCursor + nodes { + __typename + id + } + pageInfo { + __typename + startCursor + endCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, }, - }, - }); + }); - const forwardOne = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - nodes: [itemNode(1), itemNode(2)], - pageInfo: { - __typename: 'PageInfo', - startCursor: '1', - endCursor: '2', + const forwardOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + nodes: [itemNode(1), itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + startCursor: '1', + endCursor: '2', + }, }, - }, - }; - const forwardAfter = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - nodes: [], - pageInfo: { - __typename: 'PageInfo', - startCursor: null, - endCursor: null, + }; + const forwardAfter = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + nodes: [], + pageInfo: { + __typename: 'PageInfo', + startCursor: null, + endCursor: null, + }, }, - }, - }; - const backwardBefore = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - nodes: [], - pageInfo: { - __typename: 'PageInfo', - startCursor: null, - endCursor: null, + }; + const backwardBefore = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + nodes: [], + pageInfo: { + __typename: 'PageInfo', + startCursor: null, + endCursor: null, + }, }, - }, - }; - - write( - store, - { query: PaginationForward, variables: { first: 2 } }, - forwardOne - ); - write( - store, - { query: PaginationBackward, variables: { last: 1, before: '1' } }, - backwardBefore - ); - - const res = query(store, { - query: PaginationForward, - variables: { first: 2 }, + }; + + write( + store, + { query: PaginationForward, variables: { first: 2 } }, + forwardOne + ); + write( + store, + { query: PaginationBackward, variables: { last: 1, before: '1' } }, + backwardBefore + ); + + const res = query(store, { + query: PaginationForward, + variables: { first: 2 }, + }); + + expect(res.partial).toBe(false); + expect(res.data).toEqual(forwardOne); + write( + store, + { query: PaginationForward, variables: { first: 1, after: '2' } }, + forwardAfter + ); + + expect(res.partial).toBe(false); + expect(res.data).toEqual(forwardOne); }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(forwardOne); - write( - store, - { query: PaginationForward, variables: { first: 1, after: '2' } }, - forwardAfter - ); + it('allows for an empty page when this is the only result', () => { + const Pagination = gql` + query ($first: Int!, $after: String) { + __typename + items(first: $first, after: $after) { + __typename + nodes { + __typename + id + } + pageInfo { + __typename + startCursor + endCursor + } + } + } + `; - expect(res.partial).toBe(false); - expect(res.data).toEqual(forwardOne); + const store = new Store({ + resolvers: { + Query: { + items: relayPagination(), + }, + }, + }); + + const pageOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + nodes: [], + pageInfo: { + __typename: 'PageInfo', + startCursor: null, + endCursor: null, + }, + }, + }; + + write(store, { query: Pagination, variables: { first: 2 } }, pageOne); + const res = query(store, { + query: Pagination, + variables: { first: 2 }, + }); + + expect(res.partial).toBe(false); + expect(res.data).toEqual(pageOne); + }); }); -it('allows for an empty page when this is the only result', () => { - const Pagination = gql` - query ($first: Int!, $after: String) { - __typename - items(first: $first, after: $after) { +describe('as directive', () => { + it('works with forward pagination', () => { + const Pagination = gql` + query ($cursor: String) { __typename - nodes { + items(first: 1, after: $cursor) @relayPagination { __typename - id - } - pageInfo { - __typename - startCursor - endCursor + edges { + __typename + node { + __typename + id + } + } + nodes { + __typename + id + } + pageInfo { + __typename + hasNextPage + endCursor + } } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - items: relayPagination(), + const store = new Store({ + directives: { + relayPagination: relayPagination(), }, - }, - }); + }); - const pageOne = { - __typename: 'Query', - items: { - __typename: 'ItemsConnection', - nodes: [], - pageInfo: { - __typename: 'PageInfo', - startCursor: null, - endCursor: null, + const pageOne = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(1)], + nodes: [itemNode(1)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: true, + endCursor: '1', + }, }, - }, - }; + }; - write(store, { query: Pagination, variables: { first: 2 } }, pageOne); - const res = query(store, { - query: Pagination, - variables: { first: 2 }, - }); + const pageTwo = { + __typename: 'Query', + items: { + __typename: 'ItemsConnection', + edges: [itemEdge(2)], + nodes: [itemNode(2)], + pageInfo: { + __typename: 'PageInfo', + hasNextPage: false, + endCursor: null, + }, + }, + }; + + write(store, { query: Pagination, variables: { cursor: null } }, pageOne); + write(store, { query: Pagination, variables: { cursor: '1' } }, pageTwo); + + const res = query(store, { query: Pagination }); - expect(res.partial).toBe(false); - expect(res.data).toEqual(pageOne); + expect(res.partial).toBe(false); + expect(res.data).toEqual({ + ...pageTwo, + items: { + ...pageTwo.items, + edges: [pageOne.items.edges[0], pageTwo.items.edges[0]], + nodes: [pageOne.items.nodes[0], pageTwo.items.nodes[0]], + }, + }); + }); }); diff --git a/exchanges/graphcache/src/extras/simplePagination.test.ts b/exchanges/graphcache/src/extras/simplePagination.test.ts index a79103c901..d1f1e6242b 100644 --- a/exchanges/graphcache/src/extras/simplePagination.test.ts +++ b/exchanges/graphcache/src/extras/simplePagination.test.ts @@ -1,437 +1,511 @@ import { gql } from '@urql/core'; -import { it, expect } from 'vitest'; +import { it, expect, describe } from 'vitest'; import { __initAnd_query as query } from '../operations/query'; import { __initAnd_write as write } from '../operations/write'; import { Store } from '../store/store'; import { simplePagination } from './simplePagination'; -it('works with forward pagination', () => { - const Pagination = gql` - query ($skip: Number, $limit: Number) { - __typename - persons(skip: $skip, limit: $limit) { +describe('as resolver', () => { + it('works with forward pagination', () => { + const Pagination = gql` + query ($skip: Number, $limit: Number) { __typename - id - name + persons(skip: $skip, limit: $limit) { + __typename + id + name + } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - persons: simplePagination(), + const store = new Store({ + resolvers: { + Query: { + persons: simplePagination(), + }, }, - }, + }); + + const pageOne = { + __typename: 'Query', + persons: [ + { id: 1, name: 'Jovi', __typename: 'Person' }, + { id: 2, name: 'Phil', __typename: 'Person' }, + { id: 3, name: 'Andy', __typename: 'Person' }, + ], + }; + + const pageTwo = { + __typename: 'Query', + persons: [ + { id: 4, name: 'Kadi', __typename: 'Person' }, + { id: 5, name: 'Dom', __typename: 'Person' }, + { id: 6, name: 'Sofia', __typename: 'Person' }, + ], + }; + + write( + store, + { query: Pagination, variables: { skip: 0, limit: 3 } }, + pageOne + ); + const pageOneResult = query(store, { + query: Pagination, + variables: { skip: 0, limit: 3 }, + }); + expect(pageOneResult.data).toEqual(pageOne); + + write( + store, + { query: Pagination, variables: { skip: 3, limit: 3 } }, + pageTwo + ); + + const pageTwoResult = query(store, { + query: Pagination, + variables: { skip: 3, limit: 3 }, + }); + expect((pageTwoResult.data as any).persons).toEqual([ + ...pageOne.persons, + ...pageTwo.persons, + ]); + + const pageThreeResult = query(store, { + query: Pagination, + variables: { skip: 6, limit: 3 }, + }); + expect(pageThreeResult.data).toEqual(null); }); - const pageOne = { - __typename: 'Query', - persons: [ - { id: 1, name: 'Jovi', __typename: 'Person' }, - { id: 2, name: 'Phil', __typename: 'Person' }, - { id: 3, name: 'Andy', __typename: 'Person' }, - ], - }; - - const pageTwo = { - __typename: 'Query', - persons: [ - { id: 4, name: 'Kadi', __typename: 'Person' }, - { id: 5, name: 'Dom', __typename: 'Person' }, - { id: 6, name: 'Sofia', __typename: 'Person' }, - ], - }; - - write( - store, - { query: Pagination, variables: { skip: 0, limit: 3 } }, - pageOne - ); - const pageOneResult = query(store, { - query: Pagination, - variables: { skip: 0, limit: 3 }, - }); - expect(pageOneResult.data).toEqual(pageOne); - - write( - store, - { query: Pagination, variables: { skip: 3, limit: 3 } }, - pageTwo - ); - - const pageTwoResult = query(store, { - query: Pagination, - variables: { skip: 3, limit: 3 }, - }); - expect((pageTwoResult.data as any).persons).toEqual([ - ...pageOne.persons, - ...pageTwo.persons, - ]); - - const pageThreeResult = query(store, { - query: Pagination, - variables: { skip: 6, limit: 3 }, - }); - expect(pageThreeResult.data).toEqual(null); -}); - -it('works with backwards pagination', () => { - const Pagination = gql` - query ($skip: Number, $limit: Number) { - __typename - persons(skip: $skip, limit: $limit) { + it('works with backwards pagination', () => { + const Pagination = gql` + query ($skip: Number, $limit: Number) { __typename - id - name + persons(skip: $skip, limit: $limit) { + __typename + id + name + } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - persons: simplePagination({ mergeMode: 'before' }), + const store = new Store({ + resolvers: { + Query: { + persons: simplePagination({ mergeMode: 'before' }), + }, }, - }, + }); + + const pageOne = { + __typename: 'Query', + persons: [ + { id: 7, name: 'Jovi', __typename: 'Person' }, + { id: 8, name: 'Phil', __typename: 'Person' }, + { id: 9, name: 'Andy', __typename: 'Person' }, + ], + }; + + const pageTwo = { + __typename: 'Query', + persons: [ + { id: 4, name: 'Kadi', __typename: 'Person' }, + { id: 5, name: 'Dom', __typename: 'Person' }, + { id: 6, name: 'Sofia', __typename: 'Person' }, + ], + }; + + write( + store, + { query: Pagination, variables: { skip: 0, limit: 3 } }, + pageOne + ); + const pageOneResult = query(store, { + query: Pagination, + variables: { skip: 0, limit: 3 }, + }); + expect(pageOneResult.data).toEqual(pageOne); + + write( + store, + { query: Pagination, variables: { skip: 3, limit: 3 } }, + pageTwo + ); + + const pageTwoResult = query(store, { + query: Pagination, + variables: { skip: 3, limit: 3 }, + }); + expect((pageTwoResult.data as any).persons).toEqual([ + ...pageTwo.persons, + ...pageOne.persons, + ]); + + const pageThreeResult = query(store, { + query: Pagination, + variables: { skip: 6, limit: 3 }, + }); + expect(pageThreeResult.data).toEqual(null); }); - const pageOne = { - __typename: 'Query', - persons: [ - { id: 7, name: 'Jovi', __typename: 'Person' }, - { id: 8, name: 'Phil', __typename: 'Person' }, - { id: 9, name: 'Andy', __typename: 'Person' }, - ], - }; - - const pageTwo = { - __typename: 'Query', - persons: [ - { id: 4, name: 'Kadi', __typename: 'Person' }, - { id: 5, name: 'Dom', __typename: 'Person' }, - { id: 6, name: 'Sofia', __typename: 'Person' }, - ], - }; - - write( - store, - { query: Pagination, variables: { skip: 0, limit: 3 } }, - pageOne - ); - const pageOneResult = query(store, { - query: Pagination, - variables: { skip: 0, limit: 3 }, - }); - expect(pageOneResult.data).toEqual(pageOne); - - write( - store, - { query: Pagination, variables: { skip: 3, limit: 3 } }, - pageTwo - ); - - const pageTwoResult = query(store, { - query: Pagination, - variables: { skip: 3, limit: 3 }, - }); - expect((pageTwoResult.data as any).persons).toEqual([ - ...pageTwo.persons, - ...pageOne.persons, - ]); - - const pageThreeResult = query(store, { - query: Pagination, - variables: { skip: 6, limit: 3 }, - }); - expect(pageThreeResult.data).toEqual(null); -}); - -it('handles duplicates', () => { - const Pagination = gql` - query ($skip: Number, $limit: Number) { - __typename - persons(skip: $skip, limit: $limit) { + it('handles duplicates', () => { + const Pagination = gql` + query ($skip: Number, $limit: Number) { __typename - id - name + persons(skip: $skip, limit: $limit) { + __typename + id + name + } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - persons: simplePagination(), + const store = new Store({ + resolvers: { + Query: { + persons: simplePagination(), + }, }, - }, + }); + + const pageOne = { + __typename: 'Query', + persons: [ + { id: 1, name: 'Jovi', __typename: 'Person' }, + { id: 2, name: 'Phil', __typename: 'Person' }, + { id: 3, name: 'Andy', __typename: 'Person' }, + ], + }; + + const pageTwo = { + __typename: 'Query', + persons: [ + { id: 3, name: 'Andy', __typename: 'Person' }, + { id: 4, name: 'Kadi', __typename: 'Person' }, + { id: 5, name: 'Dom', __typename: 'Person' }, + ], + }; + + write( + store, + { query: Pagination, variables: { skip: 0, limit: 3 } }, + pageOne + ); + write( + store, + { query: Pagination, variables: { skip: 2, limit: 3 } }, + pageTwo + ); + + const result = query(store, { + query: Pagination, + variables: { skip: 2, limit: 3 }, + }); + expect(result.data).toEqual({ + __typename: 'Query', + persons: [...pageOne.persons, pageTwo.persons[1], pageTwo.persons[2]], + }); }); - const pageOne = { - __typename: 'Query', - persons: [ - { id: 1, name: 'Jovi', __typename: 'Person' }, - { id: 2, name: 'Phil', __typename: 'Person' }, - { id: 3, name: 'Andy', __typename: 'Person' }, - ], - }; - - const pageTwo = { - __typename: 'Query', - persons: [ - { id: 3, name: 'Andy', __typename: 'Person' }, - { id: 4, name: 'Kadi', __typename: 'Person' }, - { id: 5, name: 'Dom', __typename: 'Person' }, - ], - }; - - write( - store, - { query: Pagination, variables: { skip: 0, limit: 3 } }, - pageOne - ); - write( - store, - { query: Pagination, variables: { skip: 2, limit: 3 } }, - pageTwo - ); - - const result = query(store, { - query: Pagination, - variables: { skip: 2, limit: 3 }, - }); - expect(result.data).toEqual({ - __typename: 'Query', - persons: [...pageOne.persons, pageTwo.persons[1], pageTwo.persons[2]], - }); -}); - -it('should not return previous result when adding a parameter', () => { - const Pagination = gql` - query ($skip: Number, $limit: Number, $filter: String) { - __typename - persons(skip: $skip, limit: $limit, filter: $filter) { + it('should not return previous result when adding a parameter', () => { + const Pagination = gql` + query ($skip: Number, $limit: Number, $filter: String) { __typename - id - name + persons(skip: $skip, limit: $limit, filter: $filter) { + __typename + id + name + } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - persons: simplePagination(), + const store = new Store({ + resolvers: { + Query: { + persons: simplePagination(), + }, }, - }, - }); - - const pageOne = { - __typename: 'Query', - persons: [ - { id: 1, name: 'Jovi', __typename: 'Person' }, - { id: 2, name: 'Phil', __typename: 'Person' }, - { id: 3, name: 'Andy', __typename: 'Person' }, - ], - }; - - const emptyPage = { - __typename: 'Query', - persons: [], - }; - - write( - store, - { query: Pagination, variables: { skip: 0, limit: 3 } }, - pageOne - ); - write( - store, - { query: Pagination, variables: { skip: 0, limit: 3, filter: 'b' } }, - emptyPage - ); - - const res = query(store, { - query: Pagination, - variables: { skip: 0, limit: 3, filter: 'b' }, + }); + + const pageOne = { + __typename: 'Query', + persons: [ + { id: 1, name: 'Jovi', __typename: 'Person' }, + { id: 2, name: 'Phil', __typename: 'Person' }, + { id: 3, name: 'Andy', __typename: 'Person' }, + ], + }; + + const emptyPage = { + __typename: 'Query', + persons: [], + }; + + write( + store, + { query: Pagination, variables: { skip: 0, limit: 3 } }, + pageOne + ); + write( + store, + { query: Pagination, variables: { skip: 0, limit: 3, filter: 'b' } }, + emptyPage + ); + + const res = query(store, { + query: Pagination, + variables: { skip: 0, limit: 3, filter: 'b' }, + }); + expect(res.data).toEqual({ __typename: 'Query', persons: [] }); }); - expect(res.data).toEqual({ __typename: 'Query', persons: [] }); -}); -it('should preserve the correct order in forward pagination', () => { - const Pagination = gql` - query ($skip: Number, $limit: Number) { - __typename - persons(skip: $skip, limit: $limit) { + it('should preserve the correct order in forward pagination', () => { + const Pagination = gql` + query ($skip: Number, $limit: Number) { __typename - id - name + persons(skip: $skip, limit: $limit) { + __typename + id + name + } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - persons: simplePagination({ mergeMode: 'after' }), + const store = new Store({ + resolvers: { + Query: { + persons: simplePagination({ mergeMode: 'after' }), + }, }, - }, - }); - - const pageOne = { - __typename: 'Query', - persons: [ - { id: 1, name: 'Jovi', __typename: 'Person' }, - { id: 2, name: 'Phil', __typename: 'Person' }, - { id: 3, name: 'Andy', __typename: 'Person' }, - ], - }; - - const pageTwo = { - __typename: 'Query', - persons: [ - { id: 4, name: 'Kadi', __typename: 'Person' }, - { id: 5, name: 'Dom', __typename: 'Person' }, - { id: 6, name: 'Sofia', __typename: 'Person' }, - ], - }; - - write( - store, - { query: Pagination, variables: { skip: 3, limit: 3 } }, - pageTwo - ); - write( - store, - { query: Pagination, variables: { skip: 0, limit: 3 } }, - pageOne - ); - - const result = query(store, { - query: Pagination, - variables: { skip: 3, limit: 3 }, - }); - expect(result.data).toEqual({ - __typename: 'Query', - persons: [...pageOne.persons, ...pageTwo.persons], + }); + + const pageOne = { + __typename: 'Query', + persons: [ + { id: 1, name: 'Jovi', __typename: 'Person' }, + { id: 2, name: 'Phil', __typename: 'Person' }, + { id: 3, name: 'Andy', __typename: 'Person' }, + ], + }; + + const pageTwo = { + __typename: 'Query', + persons: [ + { id: 4, name: 'Kadi', __typename: 'Person' }, + { id: 5, name: 'Dom', __typename: 'Person' }, + { id: 6, name: 'Sofia', __typename: 'Person' }, + ], + }; + + write( + store, + { query: Pagination, variables: { skip: 3, limit: 3 } }, + pageTwo + ); + write( + store, + { query: Pagination, variables: { skip: 0, limit: 3 } }, + pageOne + ); + + const result = query(store, { + query: Pagination, + variables: { skip: 3, limit: 3 }, + }); + expect(result.data).toEqual({ + __typename: 'Query', + persons: [...pageOne.persons, ...pageTwo.persons], + }); }); -}); -it('should preserve the correct order in backward pagination', () => { - const Pagination = gql` - query ($skip: Number, $limit: Number) { - __typename - persons(skip: $skip, limit: $limit) { + it('should preserve the correct order in backward pagination', () => { + const Pagination = gql` + query ($skip: Number, $limit: Number) { __typename - id - name + persons(skip: $skip, limit: $limit) { + __typename + id + name + } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - persons: simplePagination({ mergeMode: 'before' }), + const store = new Store({ + resolvers: { + Query: { + persons: simplePagination({ mergeMode: 'before' }), + }, }, - }, + }); + + const pageOne = { + __typename: 'Query', + persons: [ + { id: 7, name: 'Jovi', __typename: 'Person' }, + { id: 8, name: 'Phil', __typename: 'Person' }, + { id: 9, name: 'Andy', __typename: 'Person' }, + ], + }; + + const pageTwo = { + __typename: 'Query', + persons: [ + { id: 4, name: 'Kadi', __typename: 'Person' }, + { id: 5, name: 'Dom', __typename: 'Person' }, + { id: 6, name: 'Sofia', __typename: 'Person' }, + ], + }; + + write( + store, + { query: Pagination, variables: { skip: 3, limit: 3 } }, + pageTwo + ); + write( + store, + { query: Pagination, variables: { skip: 0, limit: 3 } }, + pageOne + ); + + const result = query(store, { + query: Pagination, + variables: { skip: 3, limit: 3 }, + }); + + expect(result.data).toEqual({ + __typename: 'Query', + persons: [...pageTwo.persons, ...pageOne.persons], + }); }); - const pageOne = { - __typename: 'Query', - persons: [ - { id: 7, name: 'Jovi', __typename: 'Person' }, - { id: 8, name: 'Phil', __typename: 'Person' }, - { id: 9, name: 'Andy', __typename: 'Person' }, - ], - }; - - const pageTwo = { - __typename: 'Query', - persons: [ - { id: 4, name: 'Kadi', __typename: 'Person' }, - { id: 5, name: 'Dom', __typename: 'Person' }, - { id: 6, name: 'Sofia', __typename: 'Person' }, - ], - }; - - write( - store, - { query: Pagination, variables: { skip: 3, limit: 3 } }, - pageTwo - ); - write( - store, - { query: Pagination, variables: { skip: 0, limit: 3 } }, - pageOne - ); - - const result = query(store, { - query: Pagination, - variables: { skip: 3, limit: 3 }, - }); + it('prevents overlapping of pagination on different arguments', () => { + const Pagination = gql` + query ($skip: Number, $limit: Number, $filter: string) { + __typename + persons(skip: $skip, limit: $limit, filter: $filter) { + __typename + id + name + } + } + `; - expect(result.data).toEqual({ - __typename: 'Query', - persons: [...pageTwo.persons, ...pageOne.persons], + const store = new Store({ + resolvers: { + Query: { + persons: simplePagination(), + }, + }, + }); + + const page = withId => ({ + __typename: 'Query', + persons: [{ id: withId, name: withId, __typename: 'Person' }], + }); + + write( + store, + { query: Pagination, variables: { filter: 'one', skip: 0, limit: 1 } }, + page('one') + ); + + write( + store, + { query: Pagination, variables: { filter: 'two', skip: 1, limit: 1 } }, + page('two') + ); + + const resOne = query(store, { + query: Pagination, + variables: { filter: 'one', skip: 0, limit: 1 }, + }); + const resTwo = query(store, { + query: Pagination, + variables: { filter: 'two', skip: 1, limit: 1 }, + }); + const resThree = query(store, { + query: Pagination, + variables: { filter: 'three', skip: 2, limit: 1 }, + }); + + expect(resOne.data).toHaveProperty('persons[0].id', 'one'); + expect(resOne.data).toHaveProperty('persons.length', 1); + + expect(resTwo.data).toHaveProperty('persons[0].id', 'two'); + expect(resTwo.data).toHaveProperty('persons.length', 1); + + expect(resThree.data).toEqual(null); }); }); -it('prevents overlapping of pagination on different arguments', () => { - const Pagination = gql` - query ($skip: Number, $limit: Number, $filter: string) { - __typename - persons(skip: $skip, limit: $limit, filter: $filter) { +describe('as directive', () => { + it('works with forward pagination', () => { + const Pagination = gql` + query ($skip: Number, $limit: Number) { __typename - id - name + persons(skip: $skip, limit: $limit) @simplePagination { + __typename + id + name + } } - } - `; + `; - const store = new Store({ - resolvers: { - Query: { - persons: simplePagination(), + const store = new Store({ + directives: { + simplePagination: simplePagination(), }, - }, + }); + + const pageOne = { + __typename: 'Query', + persons: [ + { id: 1, name: 'Jovi', __typename: 'Person' }, + { id: 2, name: 'Phil', __typename: 'Person' }, + { id: 3, name: 'Andy', __typename: 'Person' }, + ], + }; + + const pageTwo = { + __typename: 'Query', + persons: [ + { id: 4, name: 'Kadi', __typename: 'Person' }, + { id: 5, name: 'Dom', __typename: 'Person' }, + { id: 6, name: 'Sofia', __typename: 'Person' }, + ], + }; + + write( + store, + { query: Pagination, variables: { skip: 0, limit: 3 } }, + pageOne + ); + const pageOneResult = query(store, { + query: Pagination, + variables: { skip: 0, limit: 3 }, + }); + expect(pageOneResult.data).toEqual(pageOne); + + write( + store, + { query: Pagination, variables: { skip: 3, limit: 3 } }, + pageTwo + ); + + const pageTwoResult = query(store, { + query: Pagination, + variables: { skip: 3, limit: 3 }, + }); + + expect((pageTwoResult.data as any).persons).toEqual([ + ...pageOne.persons, + ...pageTwo.persons, + ]); + + const pageThreeResult = query(store, { + query: Pagination, + variables: { skip: 6, limit: 3 }, + }); + expect(pageThreeResult.data).toEqual(null); }); - - const page = withId => ({ - __typename: 'Query', - persons: [{ id: withId, name: withId, __typename: 'Person' }], - }); - - write( - store, - { query: Pagination, variables: { filter: 'one', skip: 0, limit: 1 } }, - page('one') - ); - - write( - store, - { query: Pagination, variables: { filter: 'two', skip: 1, limit: 1 } }, - page('two') - ); - - const resOne = query(store, { - query: Pagination, - variables: { filter: 'one', skip: 0, limit: 1 }, - }); - const resTwo = query(store, { - query: Pagination, - variables: { filter: 'two', skip: 1, limit: 1 }, - }); - const resThree = query(store, { - query: Pagination, - variables: { filter: 'three', skip: 2, limit: 1 }, - }); - - expect(resOne.data).toHaveProperty('persons[0].id', 'one'); - expect(resOne.data).toHaveProperty('persons.length', 1); - - expect(resTwo.data).toHaveProperty('persons[0].id', 'two'); - expect(resTwo.data).toHaveProperty('persons.length', 1); - - expect(resThree.data).toEqual(null); });