mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-04 14:57:42 +00:00
🧪 test: Decouple lazy provisioning assertions from tool completion
The lazy specs asserted the fake-model completion text before checking the fake servers. Provisioning fires at ON_TOOL_EXECUTE, before the tool itself runs, so assert it directly and independent of the tool result: - code: poll the fake code server for the original filename (uploadCodeEnvFile preserves it). - RAG: correlate on file_id from the upload response — uploadVectors streams from a temp path, so the fake RAG records provision-<file_id>.csv, not the original.
This commit is contained in:
parent
6f8f6a57f8
commit
f620673d97
2 changed files with 14 additions and 11 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { expect, test } from '@playwright/test';
|
||||
import type { UploadedFile } from './helpers';
|
||||
import {
|
||||
MOCK_ENDPOINTS,
|
||||
NEW_CHAT_PATH,
|
||||
|
|
@ -106,14 +107,13 @@ test.describe('file provisioning — lazy (unified upload, at tool-execute)', ()
|
|||
await expect(page.getByRole('button', { name: fileName })).toBeVisible({ timeout: 15000 });
|
||||
|
||||
// A tool run triggers lazy provisioning: the fake model emits an execute_code call.
|
||||
// Provisioning fires at ON_TOOL_EXECUTE, before the execute_code tool itself runs,
|
||||
// so assert it reached the code env independent of the tool's own result.
|
||||
await sendMessage(page, `E2E_EXECUTE_CODE:${uniqueName('run')}`);
|
||||
await expect(
|
||||
page.getByTestId('messages-view').getByText(/E2E execute_code complete:/),
|
||||
).toBeVisible({ timeout: 30000 });
|
||||
|
||||
await expect
|
||||
.poll(async () => (await getCodeProvisionedUploads(page)).map((u) => u.filename), {
|
||||
timeout: 15000,
|
||||
timeout: 30000,
|
||||
})
|
||||
.toContain(fileName);
|
||||
});
|
||||
|
|
@ -134,19 +134,21 @@ test.describe('file provisioning — lazy (unified upload, at tool-execute)', ()
|
|||
content: 'k,v\nfoo,bar\n',
|
||||
});
|
||||
expect(response.ok()).toBeTruthy();
|
||||
// uploadVectors streams from a temp path, so the fake RAG records the file_id,
|
||||
// not the original filename — correlate on the id from the upload response.
|
||||
const fileId = ((await response.json()) as UploadedFile).file_id;
|
||||
expect(fileId, 'upload response should include a file_id').toBeTruthy();
|
||||
expect(
|
||||
(await getRagEmbedded(page)).map((e) => e.filename),
|
||||
(await getRagEmbedded(page)).map((e) => e.file_id),
|
||||
'unified upload must not embed until file_search runs',
|
||||
).not.toContain(fileName);
|
||||
).not.toContain(fileId);
|
||||
await expect(page.getByRole('button', { name: fileName })).toBeVisible({ timeout: 15000 });
|
||||
|
||||
// Embedding fires at ON_TOOL_EXECUTE, independent of the file_search tool result.
|
||||
await sendMessage(page, `E2E_FILE_SEARCH:${uniqueName('q')}`);
|
||||
await expect(
|
||||
page.getByTestId('messages-view').getByText(/E2E file_search complete:/),
|
||||
).toBeVisible({ timeout: 30000 });
|
||||
|
||||
await expect
|
||||
.poll(async () => (await getRagEmbedded(page)).map((e) => e.filename), { timeout: 15000 })
|
||||
.toContain(fileName);
|
||||
.poll(async () => (await getRagEmbedded(page)).map((e) => e.file_id), { timeout: 30000 })
|
||||
.toContain(fileId);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -243,6 +243,7 @@ export async function resetProvisioning(page: Page): Promise<void> {
|
|||
|
||||
/** Shape of a file record as returned by POST /api/files and GET /api/files. */
|
||||
export type UploadedFile = {
|
||||
file_id?: string;
|
||||
filename?: string;
|
||||
type?: string;
|
||||
llmDeliveryPath?: string;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue