@@ -1032,7 +1032,7 @@ test.describe("CorpusChat", () => {
10321032 await component . unmount ( ) ;
10331033 } ) ;
10341034
1035- test ( "ASYNC_RESUME keeps the processing indicator visible " , async ( {
1035+ test ( "ASYNC_RESUME sequence completes with final message " , async ( {
10361036 mount,
10371037 page,
10381038 } ) => {
@@ -1235,34 +1235,89 @@ test.describe("CorpusChat", () => {
12351235 mount,
12361236 page,
12371237 } ) => {
1238+ // Mock for the debounced refetch with `title_Contains: "First"`. Returns
1239+ // only the "First Conversation" edge so we can positively assert that the
1240+ // debounced value flowed into the Apollo variables and produced a
1241+ // filter-aware result.
1242+ const filteredConversationsMock : MockedResponse = {
1243+ request : {
1244+ query : GET_CORPUS_CONVERSATIONS ,
1245+ variables : {
1246+ corpusId : TEST_CORPUS_ID ,
1247+ conversationType : "CHAT" ,
1248+ title_Contains : "First" ,
1249+ } ,
1250+ } ,
1251+ result : {
1252+ data : {
1253+ conversations : {
1254+ __typename : "ConversationTypeConnection" ,
1255+ pageInfo : {
1256+ __typename : "PageInfo" ,
1257+ hasNextPage : false ,
1258+ endCursor : null ,
1259+ } ,
1260+ edges : [
1261+ {
1262+ __typename : "ConversationTypeEdge" ,
1263+ node : {
1264+ __typename : "ConversationType" ,
1265+ id : TEST_CONVERSATION_ID ,
1266+ title : "First Conversation" ,
1267+ createdAt : new Date ( Date . now ( ) - 86400000 ) . toISOString ( ) ,
1268+ updatedAt : new Date ( Date . now ( ) - 86400000 ) . toISOString ( ) ,
1269+ chatMessages : {
1270+ __typename : "ChatMessageTypeConnection" ,
1271+ totalCount : 5 ,
1272+ } ,
1273+ creator : {
1274+ __typename : "UserType" ,
1275+ email : "user@example.com" ,
1276+ } ,
1277+ } ,
1278+ } ,
1279+ ] ,
1280+ } ,
1281+ } ,
1282+ } ,
1283+ } ;
1284+
12381285 const component = await mount (
12391286 < CorpusChatTestWrapper
1240- mocks = { [ conversationsWithDataMock , conversationsWithDataMock ] }
1287+ mocks = { [
1288+ conversationsWithDataMock ,
1289+ conversationsWithDataMock ,
1290+ filteredConversationsMock ,
1291+ ] }
12411292 corpusId = { TEST_CORPUS_ID }
12421293 />
12431294 ) ;
12441295
12451296 await expect ( page . getByText ( "First Conversation" ) ) . toBeVisible ( {
12461297 timeout : 20000 ,
12471298 } ) ;
1299+ // "Second Conversation" is present in the unfiltered mock — we will later
1300+ // assert it disappears after the debounce fires with the filter.
1301+ await expect ( page . getByText ( "Second Conversation" ) ) . toBeVisible ( ) ;
12481302
1249- // The conversation list has a title filter input. Any input that accepts
1250- // text can drive the title debounce state — we just need to cover the
1251- // debounce timer useEffect.
1252- //
1253- // NOTE: this is coverage-only; it does NOT assert filter semantics.
1254- // If the debounce timer is broken (e.g. the effect no longer fires),
1255- // this test will still pass — it exists to exercise the code path,
1256- // not to pin filter behaviour. Any behavioural regression should be
1257- // caught by a dedicated filter test added alongside that feature.
1258- const filterInputs = page . locator ( 'input[type="text"], input:not([type])' ) ;
1259- if ( ( await filterInputs . count ( ) ) > 0 ) {
1260- const first = filterInputs . first ( ) ;
1261- await first . fill ( "First" ) ;
1262- // Wait long enough for the 500ms debounce to elapse
1263- await page . waitForTimeout ( 700 ) ;
1264- }
1265-
1303+ // The conversation list has a collapsed search icon that expands to a
1304+ // text input. Click it to reveal the title filter input, then type to
1305+ // drive the 500ms debounce timer useEffect and refetch.
1306+ const searchButton = page . locator ( 'button[title="Search"]' ) ;
1307+ await expect ( searchButton ) . toBeVisible ( { timeout : 5000 } ) ;
1308+ await searchButton . click ( ) ;
1309+
1310+ const filterInput = page . locator ( 'input[placeholder="Search chats..."]' ) ;
1311+ await expect ( filterInput ) . toBeVisible ( { timeout : 5000 } ) ;
1312+ await filterInput . fill ( "First" ) ;
1313+
1314+ // After the 500ms debounce fires, the filtered mock takes effect: "Second
1315+ // Conversation" is dropped from the result. Asserting its disappearance
1316+ // proves the debounced value reached Apollo's variables — previously the
1317+ // test silently skipped entirely when the filter input was absent.
1318+ await expect ( page . getByText ( "Second Conversation" ) ) . not . toBeVisible ( {
1319+ timeout : 5000 ,
1320+ } ) ;
12661321 await expect ( page . getByText ( "First Conversation" ) ) . toBeVisible ( ) ;
12671322 await component . unmount ( ) ;
12681323 } ) ;
0 commit comments