| 1 | import { describe |
| 2 |
| 3 | import { sliceConnection } from './connection.js'; |
| 4 |
| 5 | describe('sliceConnection', () => { |
| 6 | const items = ['a', 'b', 'c', 'd', 'e']; |
| 7 |
| 8 | it("gives each edge a cursor that resumes after that edge's node", () => { |
| 9 | const { edges } = sliceConnection(items, { first: 3, after: null }); |
| 10 | expect(edges!.map((edge) => edge.node)).toEqual(['a', 'b', 'c']); |
| 11 | expect( |
| 12 | sliceConnection(items, { first: 1, after: edges![1]!.cursor }).nodes, |
| 13 | ).toEqual(['c']); |
| 14 | const { edges: tail } = sliceConnection(items, { last: 2 }); |
| 15 | expect( |
| 16 | sliceConnection(items, { first: 1, after: tail![0]!.cursor }).nodes, |
| 17 | ).toEqual(['e']); |
| 18 | }); |
| 19 |
| 20 | it('pages forward with the endCursor it hands out', () => { |
| 21 | const first = sliceConnection(items, { first: 2 }); |
| 22 | expect(first).toMatchObject({ |
| 23 | nodes: ['a', 'b'], |
| 24 | totalCount: 5, |
| 25 | pageInfo: { hasNextPage: true, hasPreviousPage: false }, |
| 26 | }); |
| 27 | const second = sliceConnection(items, { |
| 28 | first: 2, |
| 29 | after: first.pageInfo.endCursor, |
| 30 | }); |
| 31 | expect(second).toMatchObject({ |
| 32 | nodes: ['c', 'd'], |
| 33 | pageInfo: { hasNextPage: true, hasPreviousPage: true }, |
| 34 | }); |
| 35 | const last = sliceConnection(items, { |
| 36 | first: 2, |
| 37 | after: second.pageInfo.endCursor, |
| 38 | }); |
| 39 | expect(last).toMatchObject({ |
| 40 | nodes: ['e'], |
| 41 | pageInfo: { hasNextPage: false }, |
| 42 | }); |
| 43 | }); |
| 44 |
| 45 | it('takes the tail for last, and answers an empty list without a cursor', () => { |
| 46 | expect(sliceConnection(items, { last: 2 })).toMatchObject({ |
| 47 | nodes: ['d', 'e'], |
| 48 | pageInfo: { hasNextPage: false, hasPreviousPage: true }, |
| 49 | }); |
| 50 | expect(sliceConnection([], { first: 10 }).pageInfo).toMatchObject({ |
| 51 | hasNextPage: false, |
| 52 | endCursor: null, |
| 53 | }); |
| 54 | }); |
| 55 |
| 56 | it('treats a negative or garbage cursor as the start, and a negative page size as empty', () => { |
| 57 | const cursor = (offset: string) => |
| 58 | Buffer.from(offset).toString('base64url'); |
| 59 | expect( |
| 60 | sliceConnection(items, { first: 2, after: cursor('-2') }), |
| 61 | ).toMatchObject({ |
| 62 | nodes: ['a', 'b'], |
| 63 | pageInfo: { hasPreviousPage: false }, |
| 64 | }); |
| 65 | expect( |
| 66 | sliceConnection(items, { first: 2, after: 'not-a-cursor' }).nodes, |
| 67 | ).toEqual(['a', 'b']); |
| 68 | expect(sliceConnection(items, { first: -1 }).nodes).toEqual([]); |
| 69 | expect(sliceConnection(items, { last: -1 }).nodes).toEqual([]); |
| 70 | }); |
| 71 | }); |