Files
Jyotisha/frontend/tests/people-pagination-lifecycle.test.tsx
T
jesse-uxandClaude Code 4d801e53c3
Independent Staging Quality Gate / validate (push) Successful in 16m28s
Independent Staging Quality Gate / publish (push) Successful in 3m33s
fix: integrate people archive, report reader and western chart corrections
Validate on Linux Node 22 and PostgreSQL 17: 3894 frontend tests and 64 database tests pass, with no removed test names or new failures. Preserve static Home, bounded gzip, assertion-change records and manual acceptance gaps.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-25 20:41:16 +08:00

36 lines
2.8 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import React,{useState,useRef} from 'react';
import {useSessionManagement, type SessionManagementParams} from '../src/hooks/use-session-management.ts';
import {createClientLifecycleHarness} from './react-client-lifecycle-test-support.ts';
import {bindCurrentSubjectAccount,setCurrentSubject,resetSubjectCatalogForTests} from '../src/lib/current-subject.ts';
import {emptyProfile,previewModelCatalog, type ChatSession} from '../src/lib/home-types.ts';
Object.assign(globalThis,{React});
test("late pagination cannot erase the newly selected person cursor", async () => {
const h=createClientLifecycleHarness();
const noop=()=>{};let api!:ReturnType<typeof useSessionManagement>;
const account={user:{id:'fictional-owner'},profile:emptyProfile};
let resolveOld!:(r:Response)=>void;
const old=new Promise<Response>(r=>resolveOld=r);
const urls:string[]=[];
const originalFetch=globalThis.fetch;
globalThis.fetch=async(input)=>{const url=String(input);urls.push(url);if(url.includes('subject=person-A'))return old;return new Response(JSON.stringify({sessions:[],nextCursor:'B-page-2'}));};
resetSubjectCatalogForTests();bindCurrentSubjectAccount('fictional-owner',['person-A','person-B']);setCurrentSubject('person-A');
function Probe(){
const [sessions,setSessions]=useState<ChatSession[]>([]);const [active,setActive]=useState('');
const ref=useRef<(search: string) => void>(noop);
const args=new Proxy({account,accountId:'fictional-owner',activeSession:undefined,activeSessionId:active,activeSessionIdRef:{current:active},applySessionPopStateRef:ref,cancellationPending:false,chartLibrary:[],creatingSession:false,modelCatalog:previewModelCatalog,modelPersistence:{current:null},modelSelectionVersions:{current:new Map()},modelSyncFailures:{current:new Set()},pendingSessionId:null,profile:emptyProfile,rectificationSessionId:null,sessionDetailInFlight:{current:new Set()},sessionSelectionSource:{current:'user'},sessions,sessionsRef:{current:sessions},setActiveSessionId:setActive,setSessions,uiPreview:{current:false}},{get:(obj,key)=>Reflect.get(obj,key)??noop});
api=useSessionManagement(args as unknown as SessionManagementParams);return null;
}
try{
await h.render(React.createElement(Probe));
await h.update(()=>api.setSessionsCursor('A-page-2'));
let running!:Promise<void>;await h.update(()=>{running=api.loadMoreSessions();});
await h.update(()=>setCurrentSubject('person-B'));await h.idle();
assert.equal(api.sessionsCursor,'B-page-2');
await h.update(()=>resolveOld(new Response(JSON.stringify({sessions:[],nextCursor:null}))));await running;await h.idle();
assert.equal(api.sessionsCursor,'B-page-2');
assert.deepEqual(h.errors,[]);
}finally{await h.close();globalThis.fetch=originalFetch;resetSubjectCatalogForTests();}
});