mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-11 23:03:53 +08:00
重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。
同时收敛启动与运维脚本默认行为(含 wiki worker)、更新 Admin 可观测性与相关测试,降低首轮时延并提高运行稳定性。 Made-with: Cursor
This commit is contained in:
parent
4a23b715a2
commit
dbbe3add6a
14438 changed files with 2693620 additions and 2546 deletions
91
openclaw/extensions/qa-lab/src/lab-server-ui.test.ts
Normal file
91
openclaw/extensions/qa-lab/src/lab-server-ui.test.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import {
|
||||
detectContentType,
|
||||
missingUiHtml,
|
||||
resolveUiAssetVersion,
|
||||
tryResolveUiAsset,
|
||||
} from "./lab-server-ui.js";
|
||||
|
||||
const cleanups: Array<() => Promise<void>> = [];
|
||||
|
||||
afterEach(async () => {
|
||||
while (cleanups.length > 0) {
|
||||
await cleanups.pop()?.();
|
||||
}
|
||||
});
|
||||
|
||||
describe("qa-lab server ui helpers", () => {
|
||||
it("detects basic UI asset content types", () => {
|
||||
expect(detectContentType("index.html")).toBe("text/html; charset=utf-8");
|
||||
expect(detectContentType("styles.css")).toBe("text/css; charset=utf-8");
|
||||
expect(detectContentType("main.js")).toBe("text/javascript; charset=utf-8");
|
||||
expect(detectContentType("icon.svg")).toBe("image/svg+xml");
|
||||
});
|
||||
|
||||
it("renders the missing-ui placeholder html", () => {
|
||||
expect(missingUiHtml()).toContain("QA Lab UI not built");
|
||||
expect(missingUiHtml()).toContain("pnpm qa:lab:build");
|
||||
});
|
||||
|
||||
it("hashes built UI assets and changes when bundle contents change", async () => {
|
||||
const uiDistDir = await mkdtemp(path.join(os.tmpdir(), "qa-lab-ui-dist-"));
|
||||
cleanups.push(async () => {
|
||||
await rm(uiDistDir, { recursive: true, force: true });
|
||||
});
|
||||
await writeFile(
|
||||
path.join(uiDistDir, "index.html"),
|
||||
"<!doctype html><html><head><title>QA Lab</title></head><body><div id='app'></div></body></html>",
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const version1 = resolveUiAssetVersion(uiDistDir);
|
||||
expect(version1).toMatch(/^[0-9a-f]{12}$/);
|
||||
|
||||
await writeFile(
|
||||
path.join(uiDistDir, "index.html"),
|
||||
"<!doctype html><html><head><title>QA Lab Updated</title></head><body><div id='app'></div></body></html>",
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const version2 = resolveUiAssetVersion(uiDistDir);
|
||||
expect(version2).toMatch(/^[0-9a-f]{12}$/);
|
||||
expect(version2).not.toBe(version1);
|
||||
});
|
||||
|
||||
it("never resolves sibling files outside the UI dist root", async () => {
|
||||
const rootDir = await mkdtemp(path.join(os.tmpdir(), "qa-lab-ui-boundary-"));
|
||||
cleanups.push(async () => {
|
||||
await rm(rootDir, { recursive: true, force: true });
|
||||
});
|
||||
const uiDistDir = path.join(rootDir, "dist");
|
||||
const siblingDir = path.join(rootDir, "dist-other");
|
||||
await mkdir(uiDistDir, { recursive: true });
|
||||
await mkdir(siblingDir, { recursive: true });
|
||||
await writeFile(
|
||||
path.join(uiDistDir, "index.html"),
|
||||
"<!doctype html><html><body>bundle-root</body></html>",
|
||||
"utf8",
|
||||
);
|
||||
await writeFile(path.join(siblingDir, "secret.txt"), "sibling-secret", "utf8");
|
||||
|
||||
expect(tryResolveUiAsset("/", uiDistDir, rootDir)).toBe(path.join(uiDistDir, "index.html"));
|
||||
expect(tryResolveUiAsset("/../dist-other/secret.txt", uiDistDir, rootDir)).toBeNull();
|
||||
});
|
||||
|
||||
it("rejects malformed percent-encoded UI asset paths", async () => {
|
||||
const uiDistDir = await mkdtemp(path.join(os.tmpdir(), "qa-lab-ui-malformed-"));
|
||||
cleanups.push(async () => {
|
||||
await rm(uiDistDir, { recursive: true, force: true });
|
||||
});
|
||||
await writeFile(
|
||||
path.join(uiDistDir, "index.html"),
|
||||
"<!doctype html><html><body>bundle-root</body></html>",
|
||||
"utf8",
|
||||
);
|
||||
|
||||
expect(tryResolveUiAsset("/%E0%A4", uiDistDir, uiDistDir)).toBeNull();
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue