Skip to content

Commit 230a585

Browse files
LoicMahieumickhansen
authored andcommitted
relay: pageInfo: fix hasNextPage and implement hasPreviousPage (#251)
* test: relay: add case `support pagination with where` * relay: fix `hasPreviousPage`
1 parent ea7533a commit 230a585

File tree

2 files changed

+90
-4
lines changed

2 files changed

+90
-4
lines changed

src/relay.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,19 @@ export function sequelizeConnection({name, nodeType, target, orderBy: orderByEnu
268268
if (model.sequelize.dialect.name === 'postgres' && (args.first || args.last)) {
269269
if (fullCount === null || fullCount === undefined) throw new Error('No fullcount available');
270270
}
271-
let hasMorePages = false;
271+
let hasNextPage = false;
272+
let hasPreviousPage = false;
272273
if (args.first || args.last) {
274+
const count = parseInt(args.first || args.last, 10);
273275
let index = cursor ? Number(cursor.index) : 0;
274-
hasMorePages = index + 1 + parseInt(args.first || args.last, 10) < fullCount;
276+
if (index !== 0) index++;
277+
278+
hasNextPage = index + 1 + count <= fullCount;
279+
hasPreviousPage = index - count >= 0;
280+
281+
if (args.last) {
282+
[hasNextPage, hasPreviousPage] = [hasPreviousPage, hasNextPage];
283+
}
275284
}
276285

277286
return {
@@ -282,8 +291,8 @@ export function sequelizeConnection({name, nodeType, target, orderBy: orderByEnu
282291
pageInfo: {
283292
startCursor: firstEdge ? firstEdge.cursor : null,
284293
endCursor: lastEdge ? lastEdge.cursor : null,
285-
hasPreviousPage: hasMorePages,
286-
hasNextPage: hasMorePages
294+
hasNextPage: hasNextPage,
295+
hasPreviousPage: hasPreviousPage
287296
}
288297
};
289298
}

test/integration/relay/connection.test.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ if (helper.sequelize.dialect.name === 'postgres') {
463463
}
464464
pageInfo {
465465
hasNextPage
466+
hasPreviousPage
466467
endCursor
467468
}
468469
}
@@ -474,14 +475,17 @@ if (helper.sequelize.dialect.name === 'postgres') {
474475
let firstResult = await query();
475476
verify(firstResult, firstThree);
476477
expect(firstResult.data.user.tasks.pageInfo.hasNextPage).to.equal(true);
478+
expect(firstResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(false);
477479

478480
let nextResult = await query(firstResult.data.user.tasks.pageInfo.endCursor);
479481
verify(nextResult, nextThree);
480482
expect(nextResult.data.user.tasks.pageInfo.hasNextPage).to.equal(true);
483+
expect(nextResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(true);
481484

482485
let lastResult = await query(nextResult.data.user.tasks.edges[2].cursor);
483486
verify(lastResult, lastThree);
484487
expect(lastResult.data.user.tasks.pageInfo.hasNextPage).to.equal(false);
488+
expect(lastResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(true);
485489
});
486490

487491
it('should support in-query slicing and pagination with first and CUSTOM orderBy', async function () {
@@ -553,6 +557,7 @@ if (helper.sequelize.dialect.name === 'postgres') {
553557
}
554558
pageInfo {
555559
hasNextPage
560+
hasPreviousPage
556561
endCursor
557562
}
558563
}
@@ -564,14 +569,82 @@ if (helper.sequelize.dialect.name === 'postgres') {
564569
let firstResult = await query();
565570
verify(firstResult, firstThree);
566571
expect(firstResult.data.user.tasks.pageInfo.hasNextPage).to.equal(true);
572+
expect(firstResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(false);
567573

568574
let nextResult = await query(firstResult.data.user.tasks.pageInfo.endCursor);
569575
verify(nextResult, nextThree);
570576
expect(nextResult.data.user.tasks.pageInfo.hasNextPage).to.equal(true);
577+
expect(nextResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(true);
571578

572579
let lastResult = await query(nextResult.data.user.tasks.edges[2].cursor);
573580
verify(lastResult, lastThree);
574581
expect(lastResult.data.user.tasks.pageInfo.hasNextPage).to.equal(false);
582+
expect(lastResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(true);
583+
});
584+
585+
it('should support pagination with where', async function () {
586+
const completedTasks = this.userA.tasks.filter(task => task.completed)
587+
588+
expect(completedTasks.length).to.equal(4);
589+
590+
let firstThree = completedTasks.slice(0, 3);
591+
let nextThree = completedTasks.slice(3, 6);
592+
593+
expect(firstThree.length).to.equal(3);
594+
expect(nextThree.length).to.equal(1);
595+
596+
let verify = function (result, expectedTasks) {
597+
if (result.errors) throw new Error(result.errors[0].stack);
598+
599+
var resultTasks = result.data.user.tasks.edges.map(function (edge) {
600+
return edge.node;
601+
});
602+
603+
let resultIds = resultTasks.map((task) => {
604+
return parseInt(fromGlobalId(task.id).id, 10);
605+
}).sort();
606+
607+
let expectedIds = expectedTasks.map(function (task) {
608+
return task.get('id');
609+
}).sort();
610+
611+
expect(resultTasks.length).to.equal(expectedTasks.length);
612+
expect(resultIds).to.deep.equal(expectedIds);
613+
};
614+
615+
let query = (after) => {
616+
return graphql(this.schema, `
617+
{
618+
user(id: ${this.userA.id}) {
619+
tasks(first: 3, ${after ? 'after: "' + after + '", ' : ''} completed: true) {
620+
edges {
621+
cursor
622+
node {
623+
id
624+
name
625+
}
626+
}
627+
pageInfo {
628+
hasNextPage
629+
hasPreviousPage
630+
endCursor
631+
}
632+
}
633+
}
634+
}
635+
`, null, {});
636+
};
637+
638+
639+
let firstResult = await query();
640+
verify(firstResult, firstThree);
641+
expect(firstResult.data.user.tasks.pageInfo.hasNextPage).to.equal(true);
642+
expect(firstResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(false);
643+
644+
let nextResult = await query(firstResult.data.user.tasks.pageInfo.endCursor);
645+
verify(nextResult, nextThree);
646+
expect(nextResult.data.user.tasks.pageInfo.hasNextPage).to.equal(false);
647+
expect(nextResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(true);
575648
});
576649

577650
it('should support in-query slicing with user provided args/where', async function () {
@@ -663,6 +736,7 @@ if (helper.sequelize.dialect.name === 'postgres') {
663736
}
664737
}
665738
pageInfo {
739+
hasNextPage
666740
hasPreviousPage
667741
endCursor
668742
}
@@ -674,14 +748,17 @@ if (helper.sequelize.dialect.name === 'postgres') {
674748

675749
let firstResult = await query();
676750
verify(firstResult, firstThree);
751+
expect(firstResult.data.user.tasks.pageInfo.hasNextPage).to.equal(false);
677752
expect(firstResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(true);
678753

679754
let nextResult = await query(firstResult.data.user.tasks.pageInfo.endCursor);
680755
verify(nextResult, nextThree);
756+
expect(nextResult.data.user.tasks.pageInfo.hasNextPage).to.equal(true);
681757
expect(nextResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(true);
682758

683759
let lastResult = await query(nextResult.data.user.tasks.edges[2].cursor);
684760
verify(lastResult, lastThree);
761+
expect(lastResult.data.user.tasks.pageInfo.hasNextPage).to.equal(true);
685762
expect(lastResult.data.user.tasks.pageInfo.hasPreviousPage).to.equal(false);
686763
});
687764

0 commit comments

Comments
 (0)