test: add backend API contract coverage

This commit is contained in:
t8y2 2026-05-10 22:34:37 +08:00
parent 6addbea72d
commit c43ab681cd
4 changed files with 33 additions and 23 deletions

View File

@ -261,7 +261,7 @@ async function listenProgress(id: string, handler: (next: SqlFileProgress) => vo
if (isTauriRuntime()) {
return listenSqlFileProgress(handler);
}
const { listenSqlFileProgressById } = await import("@/lib/http");
const { listenSqlFileProgressById } = await import("@/lib/httpSqlFileProgress");
return listenSqlFileProgressById(id, handler);
}

View File

@ -382,31 +382,10 @@ export async function listenSqlFileProgress(_handler: (progress: SqlFileProgress
// For HTTP mode we need an executionId, but the tauri API does not take one.
// The SSE endpoint requires a specific executionId. As a workaround we return
// a no-op unlisten; callers that need progress in web mode should use
// listenSqlFileProgressById instead.
// the web-specific SQL file progress listener instead.
return () => {};
}
/**
* Web-specific: listen to SQL file execution progress for a given executionId via SSE.
*/
export function listenSqlFileProgressById(
executionId: string,
handler: (progress: SqlFileProgress) => void,
): () => void {
const es = new EventSource(`/api/sql-file/progress/${executionId}`);
es.onmessage = (e) => {
const progress: SqlFileProgress = JSON.parse(e.data);
handler(progress);
if (progress.status === "done" || progress.status === "error" || progress.status === "cancelled") {
es.close();
}
};
es.onerror = () => {
es.close();
};
return () => es.close();
}
// ---------------------------------------------------------------------------
// Data Transfer
// ---------------------------------------------------------------------------

View File

@ -0,0 +1,19 @@
import type { SqlFileProgress } from "./tauri";
export function listenSqlFileProgressById(
executionId: string,
handler: (progress: SqlFileProgress) => void,
): () => void {
const es = new EventSource(`/api/sql-file/progress/${executionId}`);
es.onmessage = (e) => {
const progress: SqlFileProgress = JSON.parse(e.data);
handler(progress);
if (progress.status === "done" || progress.status === "error" || progress.status === "cancelled") {
es.close();
}
};
es.onerror = () => {
es.close();
};
return () => es.close();
}

View File

@ -0,0 +1,12 @@
import { readFileSync } from "node:fs";
import { strict as assert } from "node:assert";
import test from "node:test";
function exportedFunctions(path: string): string[] {
const source = readFileSync(path, "utf8");
return [...source.matchAll(/^export (?:async )?function (\w+)/gm)].map((match) => match[1]).sort();
}
test("Tauri and HTTP backends expose the same API functions", () => {
assert.deepEqual(exportedFunctions("src/lib/http.ts"), exportedFunctions("src/lib/tauri.ts"));
});