Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,14 @@ export class AuthorizationResultBasedKnexEntityLoader<
pageInfo,
};
}

/**
* Authorization-result-based version of the EnforcingKnexEntityLoader method by the same name.
* @returns The pagination cursor for the given entity.
*/
getPaginationCursorForEntity(entity: TEntity): string {
return this.knexDataManager.getCursorForEntityID(entity.getID());
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,18 @@ export class EnforcingKnexEntityLoader<
pageInfo: pageResult.pageInfo,
};
}

/**
* Get cursor for a given entity that matches what loadPageAsync would produce.
* Useful for constructing pagination cursors for entities returned from other loader methods that can then be passed to loadPageAsync for pagination.
* Most commonly used for testing pagination behavior.
*
* @param entity - The entity to get the pagination cursor for.
* @returns The pagination cursor for the given entity.
*/
getPaginationCursorForEntity(entity: TEntity): string {
return this.knexEntityLoader.getPaginationCursorForEntity(entity);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,52 @@ describe('postgres entity integration', () => {
expect(secondPage.pageInfo.hasPreviousPage).toBe(false);
});

it('getPaginationCursorForEntity produces cursor usable with loadPageAsync', async () => {
const vc = new ViewerContext(
createKnexIntegrationTestEntityCompanionProvider(knexInstance),
);

// Load first page to get the third entity (Charlie)
const firstPage = await PostgresTestEntity.knexLoader(vc).loadPageAsync({
first: 3,
pagination: {
strategy: PaginationStrategy.STANDARD,
orderBy: [{ fieldName: 'name', order: OrderByOrdering.ASCENDING }],
},
});

const charlieEntity = firstPage.edges[2]!.node;
const cursorFromPage = firstPage.edges[2]!.cursor;

// Get cursor using getPaginationCursorForEntity
const cursorFromMethod =
PostgresTestEntity.knexLoader(vc).getPaginationCursorForEntity(charlieEntity);

// cursors should be equal for both loaders
expect(cursorFromMethod).toEqual(
PostgresTestEntity.knexLoaderWithAuthorizationResults(vc).getPaginationCursorForEntity(
charlieEntity,
),
);

expect(cursorFromMethod).toBe(cursorFromPage);

// Use the cursor from getPaginationCursorForEntity to paginate
const nextPage = await PostgresTestEntity.knexLoader(vc).loadPageAsync({
first: 3,
after: cursorFromMethod,
pagination: {
strategy: PaginationStrategy.STANDARD,
orderBy: [{ fieldName: 'name', order: OrderByOrdering.ASCENDING }],
},
});

expect(nextPage.edges).toHaveLength(3);
expect(nextPage.edges[0]?.node.getField('name')).toBe('David');
expect(nextPage.edges[1]?.node.getField('name')).toBe('Eve');
expect(nextPage.edges[2]?.node.getField('name')).toBe('Frank');
});

it('performs backward pagination with last/before', async () => {
const vc = new ViewerContext(
createKnexIntegrationTestEntityCompanionProvider(knexInstance),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,10 @@ export class EntityKnexDataManager<
}
}

getCursorForEntityID(entityID: TFields[TIDField]): string {
return this.encodeOpaqueCursor(entityID);
}

/**
* Internal method for loading a page with cursor-based pagination.
* Shared logic for both regular and search pagination.
Expand Down