@@ -22,9 +22,9 @@ import { describe, it } from "@logtape/testing-node/autoload";
2222
2323import { withTestHarness } from "./harness.test.ts" ;
2424
25- const accepted = new Date ( "2026-06-24T00:00:00.000Z" ) ;
26- const created = new Date ( "2026-06-24T00:00:00.000Z" ) ;
27- const expires = new Date ( "2026-07-24T00:00:00.000Z" ) ;
25+ const accepted = Temporal . Instant . from ( "2026-06-24T00:00:00.000Z" ) ;
26+ const created = Temporal . Instant . from ( "2026-06-24T00:00:00.000Z" ) ;
27+ const expires = Temporal . Instant . from ( "2026-07-24T00:00:00.000Z" ) ;
2828const ok = 200 ;
2929
3030const accountId = "00000000-0000-4000-8000-000000000001" ;
@@ -116,8 +116,8 @@ const accountInstancesResponse = {
116116 totalCount : 1 ,
117117 edges : [
118118 {
119- created : "2026-06-24T00:00:00.000Z" ,
120- accepted : "2026-06-24T00:00:00.000Z" ,
119+ created : created . toString ( ) ,
120+ accepted : accepted . toString ( ) ,
121121 admin : true ,
122122 node : {
123123 uuid : acceptedInstanceId ,
@@ -463,3 +463,54 @@ async function seedLocalInstances(db: Database): Promise<void> {
463463 } ,
464464 ] ) ;
465465}
466+
467+ // Cursor requests depend on the preceding page.
468+ // oxlint-disable no-await-in-loop
469+ it ( "paginates both membership connections with identical microsecond timestamps" , async ( ) => {
470+ await withTestHarness ( async ( { db, post } ) => {
471+ await seedMembershipGraph ( db ) ;
472+ await db . update ( schema . instanceMembers ) . set ( {
473+ accepted,
474+ created : Temporal . Instant . from ( "2026-09-14T12:00:00.123456Z" ) ,
475+ } ) ;
476+ const auth = await createSession ( db ) ;
477+ for ( const scenario of [
478+ {
479+ type : "Account" ,
480+ id : accountId ,
481+ field : "instances" ,
482+ ids : [ pendingInstanceId , acceptedInstanceId ] ,
483+ } ,
484+ {
485+ type : "Instance" ,
486+ id : acceptedInstanceId ,
487+ field : "members" ,
488+ ids : [ pendingMemberId , memberId , accountId ] ,
489+ } ,
490+ ] ) {
491+ const seen : string [ ] = [ ] ;
492+ let after : string | null = null ;
493+ for ( const expected of scenario . ids ) {
494+ const response = await post (
495+ {
496+ query : `query($id: ID!, $after: String) { node(id: $id) { ... on ${ scenario . type } { ${ scenario . field } (first: 1, after: $after) { edges { cursor node { uuid } } pageInfo { hasNextPage } } } } }` ,
497+ variables : { id : btoa ( `${ scenario . type } :${ scenario . id } ` ) , after } ,
498+ } ,
499+ auth ,
500+ ) ;
501+ const body = await response . json ( ) ;
502+ assert . equal ( body . errors , undefined ) ;
503+ const connection = body . data . node [ scenario . field ] ;
504+ assert . equal ( connection . edges . length , 1 ) ;
505+ assert . equal ( connection . edges [ 0 ] . node . uuid , expected ) ;
506+ seen . push ( connection . edges [ 0 ] . node . uuid ) ;
507+ assert . equal (
508+ connection . pageInfo . hasNextPage ,
509+ seen . length < scenario . ids . length ,
510+ ) ;
511+ after = connection . edges [ 0 ] . cursor ;
512+ }
513+ assert . deepEqual ( seen , scenario . ids ) ;
514+ }
515+ } ) ;
516+ } ) ;
0 commit comments