mirror of
https://github.com/langgenius/dify.git
synced 2026-09-08 02:43:49 +08:00
test(knowledge_fs): restore parser branch coverage
This commit is contained in:
parent
979f09b30d
commit
63efda734c
@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": 5,
|
||||
"subtreeTree": "3915987c133895325c3953f994c5e81ac7aafdfe",
|
||||
"subtreeTree": "37121cd70481e76320d1f67060a3830c81450fdd",
|
||||
"openapiSha256": "2cf348c68bbe65dd51bbde9a0a4f91398beeebd79e89e9288c9386b26ae09796",
|
||||
"capabilityV2AuthManifestSha256": "fc0a47e23cce12544882f0298522b4933002e892b84ce1815df7e81d36a7a0c7",
|
||||
"capabilityV2AuthTestVectorSha256": "ae0de37b1ff05c40f905cf17a7b410d8971acacf64db07d5ee3d6fecfa559ce3",
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
- Added behavior tests for declared MIME types, octet-stream inference, native lightweight-text
|
||||
routing, and the browser file-picker contract. The new tests were observed failing before the
|
||||
implementation and passing afterward.
|
||||
- Added deadline and reasonless-abort coverage for the bounded Unstructured request lifecycle after
|
||||
the CI branch-coverage gate exposed the remaining paths.
|
||||
|
||||
## Why
|
||||
|
||||
@ -37,8 +39,8 @@ parser restores compatibility without adding a new parser, storage path, or netw
|
||||
|
||||
- `pnpm --filter @knowledge/api exec vitest run src/document-upload-utils.test.ts` — passed (21 tests).
|
||||
- `pnpm --filter @knowledge/parsers exec vitest run src/parser.test.ts` — passed (55 tests).
|
||||
- `pnpm --filter @knowledge/parsers test:coverage` — passed with 95.69% statements/lines,
|
||||
90.02% branches, and 97.52% functions.
|
||||
- `pnpm --filter @knowledge/parsers test:coverage` — passed with 95.99% statements/lines,
|
||||
90.10% branches, and 98.34% functions (62 tests).
|
||||
- `pnpm --filter @knowledge/api-app exec vitest run src/parser-options.test.ts` — passed (5 tests).
|
||||
- `vp test run --project unit features/new-rag/__tests__/documents-page.spec.tsx` — passed (203 tests).
|
||||
- KnowledgeFS typechecks — passed; the full Turbo test pipeline passed (22 tasks), including the API
|
||||
|
||||
@ -1819,6 +1819,35 @@ describe("parser adapters", () => {
|
||||
expect(sleepCalls).toBe(0);
|
||||
});
|
||||
|
||||
it.each([0, 1])(
|
||||
"uses the bounded default delay before retrying a transient provider failure (%d ms)",
|
||||
async (retryDelayMs) => {
|
||||
let fetchCalls = 0;
|
||||
const parser = createUnstructuredParserClient({
|
||||
endpoint: "https://unstructured.example.test",
|
||||
fetch: async () => {
|
||||
fetchCalls += 1;
|
||||
return new Response(JSON.stringify([{ text: "Recovered", type: "NarrativeText" }]), {
|
||||
status: fetchCalls === 1 ? 500 : 200,
|
||||
});
|
||||
},
|
||||
maxRetries: 1,
|
||||
retryDelayMs,
|
||||
});
|
||||
|
||||
await expect(
|
||||
parser.parse({
|
||||
body: new Uint8Array([1]),
|
||||
documentAssetId,
|
||||
filename: "delayed-retry.pdf",
|
||||
mimeType: "application/pdf",
|
||||
version: 1,
|
||||
}),
|
||||
).resolves.toMatchObject({ parser: "unstructured" });
|
||||
expect(fetchCalls).toBe(2);
|
||||
},
|
||||
);
|
||||
|
||||
it("preserves caller cancellation while an Unstructured request is active", async () => {
|
||||
const controller = new AbortController();
|
||||
let fetchStarted = false;
|
||||
@ -1849,6 +1878,102 @@ describe("parser adapters", () => {
|
||||
await expect(pending).rejects.toMatchObject({ name: "AbortError" });
|
||||
});
|
||||
|
||||
it("rejects an Unstructured request whose caller signal is already aborted", async () => {
|
||||
const controller = new AbortController();
|
||||
controller.abort();
|
||||
const parser = createUnstructuredParserClient({
|
||||
endpoint: "https://unstructured.example.test",
|
||||
fetch: async () => new Response("[]"),
|
||||
});
|
||||
|
||||
await expect(
|
||||
parser.parse({
|
||||
body: new Uint8Array([1]),
|
||||
documentAssetId,
|
||||
filename: "already-aborted.pdf",
|
||||
mimeType: "application/pdf",
|
||||
signal: controller.signal,
|
||||
version: 1,
|
||||
}),
|
||||
).rejects.toMatchObject({ name: "AbortError" });
|
||||
});
|
||||
|
||||
it("aborts an active Unstructured request when its deadline expires", async () => {
|
||||
const parser = createUnstructuredParserClient({
|
||||
endpoint: "https://unstructured.example.test",
|
||||
fetch: async (input) => {
|
||||
const request = input instanceof Request ? input : new Request(input);
|
||||
return await new Promise<Response>((_resolve, reject) => {
|
||||
request.signal.addEventListener("abort", () => reject(request.signal.reason), {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
},
|
||||
requestTimeoutMs: 1,
|
||||
});
|
||||
|
||||
await expect(
|
||||
parser.parse({
|
||||
body: new Uint8Array([1]),
|
||||
documentAssetId,
|
||||
filename: "timeout.pdf",
|
||||
mimeType: "application/pdf",
|
||||
version: 1,
|
||||
}),
|
||||
).rejects.toThrow("Unstructured parser request timed out after requestTimeoutMs=1");
|
||||
});
|
||||
|
||||
it("rejects a successful Unstructured response completed after its deadline", async () => {
|
||||
const parser = createUnstructuredParserClient({
|
||||
endpoint: "https://unstructured.example.test",
|
||||
fetch: async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 5));
|
||||
return new Response(JSON.stringify([{ text: "Too late", type: "NarrativeText" }]));
|
||||
},
|
||||
requestTimeoutMs: 1,
|
||||
});
|
||||
|
||||
await expect(
|
||||
parser.parse({
|
||||
body: new Uint8Array([1]),
|
||||
documentAssetId,
|
||||
filename: "late-success.pdf",
|
||||
mimeType: "application/pdf",
|
||||
version: 1,
|
||||
}),
|
||||
).rejects.toThrow("Unstructured parser request timed out after requestTimeoutMs=1");
|
||||
});
|
||||
|
||||
it("uses the standard AbortError when an abort event has no signal reason", async () => {
|
||||
const controller = new AbortController();
|
||||
let fetchStarted = false;
|
||||
const parser = createUnstructuredParserClient({
|
||||
endpoint: "https://unstructured.example.test",
|
||||
fetch: async (input) => {
|
||||
const request = input instanceof Request ? input : new Request(input);
|
||||
fetchStarted = true;
|
||||
return await new Promise<Response>((_resolve, reject) => {
|
||||
request.signal.addEventListener("abort", () => reject(request.signal.reason), {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
const pending = parser.parse({
|
||||
body: new Uint8Array([1]),
|
||||
documentAssetId,
|
||||
filename: "abort-event.pdf",
|
||||
mimeType: "application/pdf",
|
||||
signal: controller.signal,
|
||||
version: 1,
|
||||
});
|
||||
|
||||
await waitForCondition(() => fetchStarted);
|
||||
controller.signal.dispatchEvent(new Event("abort"));
|
||||
|
||||
await expect(pending).rejects.toMatchObject({ name: "AbortError" });
|
||||
});
|
||||
|
||||
it("validates Unstructured retry and resource bounds", () => {
|
||||
const base = {
|
||||
endpoint: "https://unstructured.example.test",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user