mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix(test): repair e2e standalone regressions
This commit is contained in:
@@ -115,7 +115,7 @@ describe("Telegram message dispatch replay guard", () => {
|
||||
await expect(reader.warmup("default")).resolves.toBe(keys.length);
|
||||
});
|
||||
|
||||
it("falls back to same-process replay protection when plugin-state cannot open", async () => {
|
||||
it("falls back to same-process replay protection when plugin-state is unavailable", async () => {
|
||||
setTelegramMessageDispatchDedupeStoreForTest(undefined);
|
||||
const errors: unknown[] = [];
|
||||
const storePath = createStorePath();
|
||||
@@ -142,7 +142,7 @@ describe("Telegram message dispatch replay guard", () => {
|
||||
}),
|
||||
).resolves.toEqual({ kind: "duplicate" });
|
||||
await expect(guard.hasRecent(first.key, { namespace: "default" })).resolves.toBe(true);
|
||||
expect(errors.length).toBeGreaterThan(0);
|
||||
expect(errors).toEqual([]);
|
||||
});
|
||||
|
||||
it("keeps same-process replay protection when plugin-state commit fails", async () => {
|
||||
|
||||
@@ -11,7 +11,7 @@ import type {
|
||||
PluginStateSyncKeyedStore,
|
||||
} from "openclaw/plugin-sdk/plugin-state-runtime";
|
||||
import { normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { getTelegramRuntime } from "./runtime.js";
|
||||
import { getOptionalTelegramRuntime } from "./runtime.js";
|
||||
|
||||
const TELEGRAM_MESSAGE_DISPATCH_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
||||
export const TELEGRAM_MESSAGE_DISPATCH_DEDUPE_NAMESPACE = "telegram.message-dispatch-dedupe";
|
||||
@@ -53,14 +53,14 @@ export type TelegramMessageDispatchClaim =
|
||||
| { kind: "duplicate" }
|
||||
| { kind: "invalid" };
|
||||
|
||||
function openDispatchDedupeStore(): TelegramMessageDispatchDedupeStore {
|
||||
return (
|
||||
dispatchDedupeStoreForTest ??
|
||||
getTelegramRuntime().state.openKeyedStore<TelegramMessageDispatchDedupeRecord>({
|
||||
function openDispatchDedupeStore(): TelegramMessageDispatchDedupeStore | undefined {
|
||||
if (dispatchDedupeStoreForTest) {
|
||||
return dispatchDedupeStoreForTest;
|
||||
}
|
||||
return getOptionalTelegramRuntime()?.state.openKeyedStore<TelegramMessageDispatchDedupeRecord>({
|
||||
namespace: TELEGRAM_MESSAGE_DISPATCH_DEDUPE_NAMESPACE,
|
||||
maxEntries: TELEGRAM_MESSAGE_DISPATCH_DEDUPE_MAX_ENTRIES,
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function resolveDispatchScopeKey(storePath: string): string {
|
||||
|
||||
@@ -108,6 +108,24 @@ function tarballFileName(manifest: PackageManifest): string {
|
||||
return `${manifest.name.replace(/^@/, "").replace("/", "-")}-${manifest.version}.tgz`;
|
||||
}
|
||||
|
||||
async function createPackStagingRoot(packageRoot: string, destinationRoot: string): Promise<string> {
|
||||
const manifest = await readPackageManifest(packageRoot);
|
||||
const packageSlug = manifest.name.replace(/^@/, "").replace("/", "-");
|
||||
const stagingRoot = path.join(destinationRoot, `pack-${packageSlug}`);
|
||||
await fs.mkdir(stagingRoot, { recursive: true });
|
||||
await fs.writeFile(path.join(stagingRoot, "package.json"), JSON.stringify(manifest, null, 2));
|
||||
const files = Array.isArray(manifest.files) ? manifest.files : [];
|
||||
for (const entry of files) {
|
||||
if (typeof entry !== "string") {
|
||||
continue;
|
||||
}
|
||||
await fs.cp(path.join(packageRoot, entry), path.join(stagingRoot, entry), {
|
||||
recursive: true,
|
||||
});
|
||||
}
|
||||
return stagingRoot;
|
||||
}
|
||||
|
||||
function closeServer(server: Server): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
server.close((error) => (error ? reject(error) : resolve()));
|
||||
@@ -204,8 +222,9 @@ describe("OpenClaw SDK package e2e", () => {
|
||||
});
|
||||
}
|
||||
for (const packageRoot of packageRoots) {
|
||||
await runCommand("pnpm", ["pack", "--pack-destination", tempDir], {
|
||||
cwd: packageRoot,
|
||||
const stagingRoot = await createPackStagingRoot(packageRoot, tempDir);
|
||||
await runCommand("npm", ["pack", "--ignore-scripts", "--pack-destination", tempDir], {
|
||||
cwd: stagingRoot,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,14 @@ async function restoreCliRunnerPrepareDeps() {
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
const { setCliRunnerTestDeps } = await import("./cli-runner.js");
|
||||
const { setCliRunnerPrepareTestDeps } = await import("./cli-runner/prepare.js");
|
||||
setCliRunnerTestDeps({
|
||||
// Bundle MCP wiring is the behavior under test; transcript flush has
|
||||
// dedicated coverage and the fake Claude binary does not write real
|
||||
// Claude transcript files.
|
||||
claudeCliSessionTranscriptHasContent: vi.fn(async () => true),
|
||||
});
|
||||
setCliRunnerPrepareTestDeps({
|
||||
// This test validates downstream bundle MCP config injection. The generic
|
||||
// OpenClaw loopback tool inventory is covered by prepare-level tests and is
|
||||
@@ -91,7 +98,9 @@ beforeEach(async () => {
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const { restoreCliRunnerTestDeps } = await import("./cli-runner.js");
|
||||
cliBackendsTesting.resetDepsForTest();
|
||||
restoreCliRunnerTestDeps();
|
||||
await restoreCliRunnerPrepareDeps();
|
||||
await resetBundleMcpPluginState();
|
||||
});
|
||||
|
||||
@@ -13,13 +13,14 @@ import "./doctor.fast-path-mocks.js";
|
||||
|
||||
let doctorCommand: typeof import("./doctor.js").doctorCommand;
|
||||
|
||||
const CODEX_PROVIDER_ID = "openai";
|
||||
const OPENAI_PROVIDER_ID = "openai";
|
||||
const LEGACY_CODEX_PROVIDER_ID = "openai-codex";
|
||||
const CODEX_PROFILE_ID = "openai:user@example.com";
|
||||
const CODEX_PROFILE_EMAIL = "user@example.com";
|
||||
|
||||
function configCodexOAuthProfile() {
|
||||
return {
|
||||
provider: CODEX_PROVIDER_ID,
|
||||
provider: OPENAI_PROVIDER_ID,
|
||||
mode: "oauth",
|
||||
email: CODEX_PROFILE_EMAIL,
|
||||
};
|
||||
@@ -28,7 +29,7 @@ function configCodexOAuthProfile() {
|
||||
function storedCodexOAuthProfile() {
|
||||
return {
|
||||
type: "oauth",
|
||||
provider: CODEX_PROVIDER_ID,
|
||||
provider: OPENAI_PROVIDER_ID,
|
||||
access: "access-token",
|
||||
refresh: "refresh-token",
|
||||
expires: Date.now() + 60_000,
|
||||
@@ -51,7 +52,7 @@ function mockCodexProviderSnapshot(params: {
|
||||
config: {
|
||||
models: {
|
||||
providers: {
|
||||
[CODEX_PROVIDER_ID]: params.provider,
|
||||
[LEGACY_CODEX_PROVIDER_ID]: params.provider,
|
||||
},
|
||||
},
|
||||
...(params.withConfigOAuth
|
||||
@@ -194,7 +195,7 @@ describe("doctor command", () => {
|
||||
expect(warned).toBe(true);
|
||||
});
|
||||
|
||||
it("warns when a legacy OpenAI provider override shadows configured Codex OAuth", async () => {
|
||||
it("warns when a legacy Codex provider override shadows configured Codex OAuth", async () => {
|
||||
mockCodexProviderSnapshot({
|
||||
provider: {
|
||||
api: "openai-responses",
|
||||
@@ -206,10 +207,10 @@ describe("doctor command", () => {
|
||||
|
||||
await runDoctorNonInteractive();
|
||||
|
||||
expect(hasCodexOAuthWarning("models.providers.openai")).toBe(true);
|
||||
expect(hasCodexOAuthWarning("models.providers.openai-codex")).toBe(true);
|
||||
});
|
||||
|
||||
it("warns when a legacy OpenAI provider override shadows stored Codex OAuth", async () => {
|
||||
it("warns when a legacy Codex provider override shadows stored Codex OAuth", async () => {
|
||||
mockCodexProviderSnapshot({
|
||||
provider: {
|
||||
api: "openai-responses",
|
||||
@@ -222,7 +223,7 @@ describe("doctor command", () => {
|
||||
|
||||
await runDoctorNonInteractive();
|
||||
|
||||
expect(hasCodexOAuthWarning("models.providers.openai")).toBe(true);
|
||||
expect(hasCodexOAuthWarning("models.providers.openai-codex")).toBe(true);
|
||||
});
|
||||
|
||||
it("warns when an inline OpenAI model keeps the legacy OpenAI transport", async () => {
|
||||
@@ -275,7 +276,7 @@ describe("doctor command", () => {
|
||||
expect(hasCodexOAuthWarning()).toBe(false);
|
||||
});
|
||||
|
||||
it("does not warn about an OpenAI provider override without Codex OAuth", async () => {
|
||||
it("does not warn about a legacy Codex provider override without Codex OAuth", async () => {
|
||||
mockCodexProviderSnapshot({
|
||||
provider: {
|
||||
api: "openai-responses",
|
||||
|
||||
Reference in New Issue
Block a user