Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
at main 14 kB view raw
1import { gql } from '@urql/core'; 2import { it, expect, describe } from 'vitest'; 3import { __initAnd_query as query } from '../operations/query'; 4import { __initAnd_write as write } from '../operations/write'; 5import { Store } from '../store/store'; 6import { MergeMode, simplePagination } from './simplePagination'; 7 8describe('as resolver', () => { 9 it('works with forward pagination', () => { 10 const Pagination = gql` 11 query ($skip: Number, $limit: Number) { 12 __typename 13 persons(skip: $skip, limit: $limit) { 14 __typename 15 id 16 name 17 } 18 } 19 `; 20 21 const store = new Store({ 22 resolvers: { 23 Query: { 24 persons: simplePagination(), 25 }, 26 }, 27 }); 28 29 const pageOne = { 30 __typename: 'Query', 31 persons: [ 32 { id: 1, name: 'Jovi', __typename: 'Person' }, 33 { id: 2, name: 'Phil', __typename: 'Person' }, 34 { id: 3, name: 'Andy', __typename: 'Person' }, 35 ], 36 }; 37 38 const pageTwo = { 39 __typename: 'Query', 40 persons: [ 41 { id: 4, name: 'Kadi', __typename: 'Person' }, 42 { id: 5, name: 'Dom', __typename: 'Person' }, 43 { id: 6, name: 'Sofia', __typename: 'Person' }, 44 ], 45 }; 46 47 write( 48 store, 49 { query: Pagination, variables: { skip: 0, limit: 3 } }, 50 pageOne 51 ); 52 const pageOneResult = query(store, { 53 query: Pagination, 54 variables: { skip: 0, limit: 3 }, 55 }); 56 expect(pageOneResult.data).toEqual(pageOne); 57 58 write( 59 store, 60 { query: Pagination, variables: { skip: 3, limit: 3 } }, 61 pageTwo 62 ); 63 64 const pageTwoResult = query(store, { 65 query: Pagination, 66 variables: { skip: 3, limit: 3 }, 67 }); 68 expect((pageTwoResult.data as any).persons).toEqual([ 69 ...pageOne.persons, 70 ...pageTwo.persons, 71 ]); 72 73 const pageThreeResult = query(store, { 74 query: Pagination, 75 variables: { skip: 6, limit: 3 }, 76 }); 77 expect(pageThreeResult.data).toEqual(null); 78 }); 79 80 it('works with backwards pagination', () => { 81 const Pagination = gql` 82 query ($skip: Number, $limit: Number) { 83 __typename 84 persons(skip: $skip, limit: $limit) { 85 __typename 86 id 87 name 88 } 89 } 90 `; 91 92 const store = new Store({ 93 resolvers: { 94 Query: { 95 persons: simplePagination({ mergeMode: 'before' }), 96 }, 97 }, 98 }); 99 100 const pageOne = { 101 __typename: 'Query', 102 persons: [ 103 { id: 7, name: 'Jovi', __typename: 'Person' }, 104 { id: 8, name: 'Phil', __typename: 'Person' }, 105 { id: 9, name: 'Andy', __typename: 'Person' }, 106 ], 107 }; 108 109 const pageTwo = { 110 __typename: 'Query', 111 persons: [ 112 { id: 4, name: 'Kadi', __typename: 'Person' }, 113 { id: 5, name: 'Dom', __typename: 'Person' }, 114 { id: 6, name: 'Sofia', __typename: 'Person' }, 115 ], 116 }; 117 118 write( 119 store, 120 { query: Pagination, variables: { skip: 0, limit: 3 } }, 121 pageOne 122 ); 123 const pageOneResult = query(store, { 124 query: Pagination, 125 variables: { skip: 0, limit: 3 }, 126 }); 127 expect(pageOneResult.data).toEqual(pageOne); 128 129 write( 130 store, 131 { query: Pagination, variables: { skip: 3, limit: 3 } }, 132 pageTwo 133 ); 134 135 const pageTwoResult = query(store, { 136 query: Pagination, 137 variables: { skip: 3, limit: 3 }, 138 }); 139 expect((pageTwoResult.data as any).persons).toEqual([ 140 ...pageTwo.persons, 141 ...pageOne.persons, 142 ]); 143 144 const pageThreeResult = query(store, { 145 query: Pagination, 146 variables: { skip: 6, limit: 3 }, 147 }); 148 expect(pageThreeResult.data).toEqual(null); 149 }); 150 151 it('handles duplicates', () => { 152 const Pagination = gql` 153 query ($skip: Number, $limit: Number) { 154 __typename 155 persons(skip: $skip, limit: $limit) { 156 __typename 157 id 158 name 159 } 160 } 161 `; 162 163 const store = new Store({ 164 resolvers: { 165 Query: { 166 persons: simplePagination(), 167 }, 168 }, 169 }); 170 171 const pageOne = { 172 __typename: 'Query', 173 persons: [ 174 { id: 1, name: 'Jovi', __typename: 'Person' }, 175 { id: 2, name: 'Phil', __typename: 'Person' }, 176 { id: 3, name: 'Andy', __typename: 'Person' }, 177 ], 178 }; 179 180 const pageTwo = { 181 __typename: 'Query', 182 persons: [ 183 { id: 3, name: 'Andy', __typename: 'Person' }, 184 { id: 4, name: 'Kadi', __typename: 'Person' }, 185 { id: 5, name: 'Dom', __typename: 'Person' }, 186 ], 187 }; 188 189 write( 190 store, 191 { query: Pagination, variables: { skip: 0, limit: 3 } }, 192 pageOne 193 ); 194 write( 195 store, 196 { query: Pagination, variables: { skip: 2, limit: 3 } }, 197 pageTwo 198 ); 199 200 const result = query(store, { 201 query: Pagination, 202 variables: { skip: 2, limit: 3 }, 203 }); 204 expect(result.data).toEqual({ 205 __typename: 'Query', 206 persons: [...pageOne.persons, pageTwo.persons[1], pageTwo.persons[2]], 207 }); 208 }); 209 210 it('should not return previous result when adding a parameter', () => { 211 const Pagination = gql` 212 query ($skip: Number, $limit: Number, $filter: String) { 213 __typename 214 persons(skip: $skip, limit: $limit, filter: $filter) { 215 __typename 216 id 217 name 218 } 219 } 220 `; 221 222 const store = new Store({ 223 resolvers: { 224 Query: { 225 persons: simplePagination(), 226 }, 227 }, 228 }); 229 230 const pageOne = { 231 __typename: 'Query', 232 persons: [ 233 { id: 1, name: 'Jovi', __typename: 'Person' }, 234 { id: 2, name: 'Phil', __typename: 'Person' }, 235 { id: 3, name: 'Andy', __typename: 'Person' }, 236 ], 237 }; 238 239 const emptyPage = { 240 __typename: 'Query', 241 persons: [], 242 }; 243 244 write( 245 store, 246 { query: Pagination, variables: { skip: 0, limit: 3 } }, 247 pageOne 248 ); 249 write( 250 store, 251 { query: Pagination, variables: { skip: 0, limit: 3, filter: 'b' } }, 252 emptyPage 253 ); 254 255 const res = query(store, { 256 query: Pagination, 257 variables: { skip: 0, limit: 3, filter: 'b' }, 258 }); 259 expect(res.data).toEqual({ __typename: 'Query', persons: [] }); 260 }); 261 262 it('should preserve the correct order in forward pagination', () => { 263 const Pagination = gql` 264 query ($skip: Number, $limit: Number) { 265 __typename 266 persons(skip: $skip, limit: $limit) { 267 __typename 268 id 269 name 270 } 271 } 272 `; 273 274 const store = new Store({ 275 resolvers: { 276 Query: { 277 persons: simplePagination({ mergeMode: 'after' }), 278 }, 279 }, 280 }); 281 282 const pageOne = { 283 __typename: 'Query', 284 persons: [ 285 { id: 1, name: 'Jovi', __typename: 'Person' }, 286 { id: 2, name: 'Phil', __typename: 'Person' }, 287 { id: 3, name: 'Andy', __typename: 'Person' }, 288 ], 289 }; 290 291 const pageTwo = { 292 __typename: 'Query', 293 persons: [ 294 { id: 4, name: 'Kadi', __typename: 'Person' }, 295 { id: 5, name: 'Dom', __typename: 'Person' }, 296 { id: 6, name: 'Sofia', __typename: 'Person' }, 297 ], 298 }; 299 300 write( 301 store, 302 { query: Pagination, variables: { skip: 3, limit: 3 } }, 303 pageTwo 304 ); 305 write( 306 store, 307 { query: Pagination, variables: { skip: 0, limit: 3 } }, 308 pageOne 309 ); 310 311 const result = query(store, { 312 query: Pagination, 313 variables: { skip: 3, limit: 3 }, 314 }); 315 expect(result.data).toEqual({ 316 __typename: 'Query', 317 persons: [...pageOne.persons, ...pageTwo.persons], 318 }); 319 }); 320 321 it('should preserve the correct order in backward pagination', () => { 322 const Pagination = gql` 323 query ($skip: Number, $limit: Number) { 324 __typename 325 persons(skip: $skip, limit: $limit) { 326 __typename 327 id 328 name 329 } 330 } 331 `; 332 333 const store = new Store({ 334 resolvers: { 335 Query: { 336 persons: simplePagination({ mergeMode: 'before' }), 337 }, 338 }, 339 }); 340 341 const pageOne = { 342 __typename: 'Query', 343 persons: [ 344 { id: 7, name: 'Jovi', __typename: 'Person' }, 345 { id: 8, name: 'Phil', __typename: 'Person' }, 346 { id: 9, name: 'Andy', __typename: 'Person' }, 347 ], 348 }; 349 350 const pageTwo = { 351 __typename: 'Query', 352 persons: [ 353 { id: 4, name: 'Kadi', __typename: 'Person' }, 354 { id: 5, name: 'Dom', __typename: 'Person' }, 355 { id: 6, name: 'Sofia', __typename: 'Person' }, 356 ], 357 }; 358 359 write( 360 store, 361 { query: Pagination, variables: { skip: 3, limit: 3 } }, 362 pageTwo 363 ); 364 write( 365 store, 366 { query: Pagination, variables: { skip: 0, limit: 3 } }, 367 pageOne 368 ); 369 370 const result = query(store, { 371 query: Pagination, 372 variables: { skip: 3, limit: 3 }, 373 }); 374 375 expect(result.data).toEqual({ 376 __typename: 'Query', 377 persons: [...pageTwo.persons, ...pageOne.persons], 378 }); 379 }); 380 381 it('prevents overlapping of pagination on different arguments', () => { 382 const Pagination = gql` 383 query ($skip: Number, $limit: Number, $filter: string) { 384 __typename 385 persons(skip: $skip, limit: $limit, filter: $filter) { 386 __typename 387 id 388 name 389 } 390 } 391 `; 392 393 const store = new Store({ 394 resolvers: { 395 Query: { 396 persons: simplePagination(), 397 }, 398 }, 399 }); 400 401 const page = withId => ({ 402 __typename: 'Query', 403 persons: [{ id: withId, name: withId, __typename: 'Person' }], 404 }); 405 406 write( 407 store, 408 { query: Pagination, variables: { filter: 'one', skip: 0, limit: 1 } }, 409 page('one') 410 ); 411 412 write( 413 store, 414 { query: Pagination, variables: { filter: 'two', skip: 1, limit: 1 } }, 415 page('two') 416 ); 417 418 const resOne = query(store, { 419 query: Pagination, 420 variables: { filter: 'one', skip: 0, limit: 1 }, 421 }); 422 const resTwo = query(store, { 423 query: Pagination, 424 variables: { filter: 'two', skip: 1, limit: 1 }, 425 }); 426 const resThree = query(store, { 427 query: Pagination, 428 variables: { filter: 'three', skip: 2, limit: 1 }, 429 }); 430 431 expect(resOne.data).toHaveProperty('persons[0].id', 'one'); 432 expect(resOne.data).toHaveProperty('persons.length', 1); 433 434 expect(resTwo.data).toHaveProperty('persons[0].id', 'two'); 435 expect(resTwo.data).toHaveProperty('persons.length', 1); 436 437 expect(resThree.data).toEqual(null); 438 }); 439}); 440 441describe('as directive', () => { 442 it('works with forward pagination', () => { 443 const Pagination = gql` 444 query ($skip: Number, $limit: Number) { 445 __typename 446 persons(skip: $skip, limit: $limit) @_simplePagination { 447 __typename 448 id 449 name 450 } 451 } 452 `; 453 454 const store = new Store({ 455 directives: { 456 simplePagination: () => simplePagination(), 457 }, 458 }); 459 460 const pageOne = { 461 __typename: 'Query', 462 persons: [ 463 { id: 1, name: 'Jovi', __typename: 'Person' }, 464 { id: 2, name: 'Phil', __typename: 'Person' }, 465 { id: 3, name: 'Andy', __typename: 'Person' }, 466 ], 467 }; 468 469 const pageTwo = { 470 __typename: 'Query', 471 persons: [ 472 { id: 4, name: 'Kadi', __typename: 'Person' }, 473 { id: 5, name: 'Dom', __typename: 'Person' }, 474 { id: 6, name: 'Sofia', __typename: 'Person' }, 475 ], 476 }; 477 478 write( 479 store, 480 { query: Pagination, variables: { skip: 0, limit: 3 } }, 481 pageOne 482 ); 483 const pageOneResult = query(store, { 484 query: Pagination, 485 variables: { skip: 0, limit: 3 }, 486 }); 487 expect(pageOneResult.data).toEqual(pageOne); 488 489 write( 490 store, 491 { query: Pagination, variables: { skip: 3, limit: 3 } }, 492 pageTwo 493 ); 494 495 const pageTwoResult = query(store, { 496 query: Pagination, 497 variables: { skip: 3, limit: 3 }, 498 }); 499 500 expect((pageTwoResult.data as any).persons).toEqual([ 501 ...pageOne.persons, 502 ...pageTwo.persons, 503 ]); 504 505 const pageThreeResult = query(store, { 506 query: Pagination, 507 variables: { skip: 6, limit: 3 }, 508 }); 509 expect(pageThreeResult.data).toEqual(null); 510 }); 511 512 it('works with backwards pagination', () => { 513 const Pagination = gql` 514 query ($skip: Number, $limit: Number) { 515 __typename 516 persons(skip: $skip, limit: $limit) 517 @_simplePagination(mergeMode: "before") { 518 __typename 519 id 520 name 521 } 522 } 523 `; 524 525 const store = new Store({ 526 directives: { 527 simplePagination: directiveArguments => 528 simplePagination({ 529 mergeMode: directiveArguments!.mergeMode as MergeMode, 530 }), 531 }, 532 }); 533 534 const pageOne = { 535 __typename: 'Query', 536 persons: [ 537 { id: 7, name: 'Jovi', __typename: 'Person' }, 538 { id: 8, name: 'Phil', __typename: 'Person' }, 539 { id: 9, name: 'Andy', __typename: 'Person' }, 540 ], 541 }; 542 543 const pageTwo = { 544 __typename: 'Query', 545 persons: [ 546 { id: 4, name: 'Kadi', __typename: 'Person' }, 547 { id: 5, name: 'Dom', __typename: 'Person' }, 548 { id: 6, name: 'Sofia', __typename: 'Person' }, 549 ], 550 }; 551 552 write( 553 store, 554 { query: Pagination, variables: { skip: 0, limit: 3 } }, 555 pageOne 556 ); 557 const pageOneResult = query(store, { 558 query: Pagination, 559 variables: { skip: 0, limit: 3 }, 560 }); 561 expect(pageOneResult.data).toEqual(pageOne); 562 563 write( 564 store, 565 { query: Pagination, variables: { skip: 3, limit: 3 } }, 566 pageTwo 567 ); 568 569 const pageTwoResult = query(store, { 570 query: Pagination, 571 variables: { skip: 3, limit: 3 }, 572 }); 573 expect((pageTwoResult.data as any).persons).toEqual([ 574 ...pageTwo.persons, 575 ...pageOne.persons, 576 ]); 577 578 const pageThreeResult = query(store, { 579 query: Pagination, 580 variables: { skip: 6, limit: 3 }, 581 }); 582 expect(pageThreeResult.data).toEqual(null); 583 }); 584});