mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 18:34:33 +00:00
refactor(test): streamline env setup in auth and gateway e2e
This commit is contained in:
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
|
|||||||
import os from "node:os";
|
import os from "node:os";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
import { captureEnv } from "../test-utils/env.js";
|
import { withEnvAsync } from "../test-utils/env.js";
|
||||||
import {
|
import {
|
||||||
type AuthProfileStore,
|
type AuthProfileStore,
|
||||||
ensureAuthProfileStore,
|
ensureAuthProfileStore,
|
||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
import { CHUTES_TOKEN_ENDPOINT } from "./chutes-oauth.js";
|
import { CHUTES_TOKEN_ENDPOINT } from "./chutes-oauth.js";
|
||||||
|
|
||||||
describe("auth-profiles (chutes)", () => {
|
describe("auth-profiles (chutes)", () => {
|
||||||
let envSnapshot: ReturnType<typeof captureEnv> | undefined;
|
|
||||||
let tempDir: string | null = null;
|
let tempDir: string | null = null;
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -20,67 +19,66 @@ describe("auth-profiles (chutes)", () => {
|
|||||||
await fs.rm(tempDir, { recursive: true, force: true });
|
await fs.rm(tempDir, { recursive: true, force: true });
|
||||||
tempDir = null;
|
tempDir = null;
|
||||||
}
|
}
|
||||||
envSnapshot?.restore();
|
|
||||||
envSnapshot = undefined;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("refreshes expired Chutes OAuth credentials", async () => {
|
it("refreshes expired Chutes OAuth credentials", async () => {
|
||||||
envSnapshot = captureEnv([
|
|
||||||
"OPENCLAW_STATE_DIR",
|
|
||||||
"OPENCLAW_AGENT_DIR",
|
|
||||||
"PI_CODING_AGENT_DIR",
|
|
||||||
"CHUTES_CLIENT_ID",
|
|
||||||
]);
|
|
||||||
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-chutes-"));
|
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-chutes-"));
|
||||||
process.env.OPENCLAW_STATE_DIR = tempDir;
|
const agentDir = path.join(tempDir, "agents", "main", "agent");
|
||||||
process.env.OPENCLAW_AGENT_DIR = path.join(tempDir, "agents", "main", "agent");
|
await withEnvAsync(
|
||||||
process.env.PI_CODING_AGENT_DIR = process.env.OPENCLAW_AGENT_DIR;
|
{
|
||||||
|
OPENCLAW_STATE_DIR: tempDir,
|
||||||
const authProfilePath = path.join(tempDir, "agents", "main", "agent", "auth-profiles.json");
|
OPENCLAW_AGENT_DIR: agentDir,
|
||||||
await fs.mkdir(path.dirname(authProfilePath), { recursive: true });
|
PI_CODING_AGENT_DIR: agentDir,
|
||||||
|
CHUTES_CLIENT_ID: undefined,
|
||||||
const store: AuthProfileStore = {
|
|
||||||
version: 1,
|
|
||||||
profiles: {
|
|
||||||
"chutes:default": {
|
|
||||||
type: "oauth",
|
|
||||||
provider: "chutes",
|
|
||||||
access: "at_old",
|
|
||||||
refresh: "rt_old",
|
|
||||||
expires: Date.now() - 60_000,
|
|
||||||
clientId: "cid_test",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
async () => {
|
||||||
await fs.writeFile(authProfilePath, `${JSON.stringify(store)}\n`);
|
const authProfilePath = path.join(agentDir, "auth-profiles.json");
|
||||||
|
await fs.mkdir(path.dirname(authProfilePath), { recursive: true });
|
||||||
|
|
||||||
const fetchSpy = vi.fn(async (input: string | URL) => {
|
const store: AuthProfileStore = {
|
||||||
const url = typeof input === "string" ? input : input.toString();
|
version: 1,
|
||||||
if (url !== CHUTES_TOKEN_ENDPOINT) {
|
profiles: {
|
||||||
return new Response("not found", { status: 404 });
|
"chutes:default": {
|
||||||
}
|
type: "oauth",
|
||||||
return new Response(
|
provider: "chutes",
|
||||||
JSON.stringify({
|
access: "at_old",
|
||||||
access_token: "at_new",
|
refresh: "rt_old",
|
||||||
expires_in: 3600,
|
expires: Date.now() - 60_000,
|
||||||
}),
|
clientId: "cid_test",
|
||||||
{ status: 200, headers: { "Content-Type": "application/json" } },
|
},
|
||||||
);
|
},
|
||||||
});
|
};
|
||||||
vi.stubGlobal("fetch", fetchSpy);
|
await fs.writeFile(authProfilePath, `${JSON.stringify(store)}\n`);
|
||||||
|
|
||||||
const loaded = ensureAuthProfileStore();
|
const fetchSpy = vi.fn(async (input: string | URL) => {
|
||||||
const resolved = await resolveApiKeyForProfile({
|
const url = typeof input === "string" ? input : input.toString();
|
||||||
store: loaded,
|
if (url !== CHUTES_TOKEN_ENDPOINT) {
|
||||||
profileId: "chutes:default",
|
return new Response("not found", { status: 404 });
|
||||||
});
|
}
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
access_token: "at_new",
|
||||||
|
expires_in: 3600,
|
||||||
|
}),
|
||||||
|
{ status: 200, headers: { "Content-Type": "application/json" } },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
vi.stubGlobal("fetch", fetchSpy);
|
||||||
|
|
||||||
expect(resolved?.apiKey).toBe("at_new");
|
const loaded = ensureAuthProfileStore();
|
||||||
expect(fetchSpy).toHaveBeenCalled();
|
const resolved = await resolveApiKeyForProfile({
|
||||||
|
store: loaded,
|
||||||
|
profileId: "chutes:default",
|
||||||
|
});
|
||||||
|
|
||||||
const persisted = JSON.parse(await fs.readFile(authProfilePath, "utf8")) as {
|
expect(resolved?.apiKey).toBe("at_new");
|
||||||
profiles?: Record<string, { access?: string }>;
|
expect(fetchSpy).toHaveBeenCalled();
|
||||||
};
|
|
||||||
expect(persisted.profiles?.["chutes:default"]?.access).toBe("at_new");
|
const persisted = JSON.parse(await fs.readFile(authProfilePath, "utf8")) as {
|
||||||
|
profiles?: Record<string, { access?: string }>;
|
||||||
|
};
|
||||||
|
expect(persisted.profiles?.["chutes:default"]?.access).toBe("at_new");
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { resolveCanvasHostUrl } from "../infra/canvas-host-url.js";
|
|||||||
import { GatewayLockError } from "../infra/gateway-lock.js";
|
import { GatewayLockError } from "../infra/gateway-lock.js";
|
||||||
import { getActivePluginRegistry, setActivePluginRegistry } from "../plugins/runtime.js";
|
import { getActivePluginRegistry, setActivePluginRegistry } from "../plugins/runtime.js";
|
||||||
import { createOutboundTestPlugin } from "../test-utils/channel-plugins.js";
|
import { createOutboundTestPlugin } from "../test-utils/channel-plugins.js";
|
||||||
import { captureEnv } from "../test-utils/env.js";
|
import { withEnvAsync } from "../test-utils/env.js";
|
||||||
import { createTempHomeEnv } from "../test-utils/temp-home.js";
|
import { createTempHomeEnv } from "../test-utils/temp-home.js";
|
||||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
||||||
import { createRegistry } from "./server.e2e-registry-helpers.js";
|
import { createRegistry } from "./server.e2e-registry-helpers.js";
|
||||||
@@ -263,25 +263,21 @@ describe("gateway server models + voicewake", () => {
|
|||||||
|
|
||||||
describe("gateway server misc", () => {
|
describe("gateway server misc", () => {
|
||||||
test("hello-ok advertises the gateway port for canvas host", async () => {
|
test("hello-ok advertises the gateway port for canvas host", async () => {
|
||||||
const envSnapshot = captureEnv(["OPENCLAW_CANVAS_HOST_PORT", "OPENCLAW_GATEWAY_TOKEN"]);
|
await withEnvAsync({ OPENCLAW_GATEWAY_TOKEN: "secret" }, async () => {
|
||||||
try {
|
|
||||||
process.env.OPENCLAW_GATEWAY_TOKEN = "secret";
|
|
||||||
testTailnetIPv4.value = "100.64.0.1";
|
testTailnetIPv4.value = "100.64.0.1";
|
||||||
testState.gatewayBind = "lan";
|
testState.gatewayBind = "lan";
|
||||||
const canvasPort = await getFreePort();
|
const canvasPort = await getFreePort();
|
||||||
testState.canvasHostPort = canvasPort;
|
testState.canvasHostPort = canvasPort;
|
||||||
process.env.OPENCLAW_CANVAS_HOST_PORT = String(canvasPort);
|
await withEnvAsync({ OPENCLAW_CANVAS_HOST_PORT: String(canvasPort) }, async () => {
|
||||||
|
const testPort = await getFreePort();
|
||||||
const testPort = await getFreePort();
|
const canvasHostUrl = resolveCanvasHostUrl({
|
||||||
const canvasHostUrl = resolveCanvasHostUrl({
|
canvasPort,
|
||||||
canvasPort,
|
requestHost: `100.64.0.1:${testPort}`,
|
||||||
requestHost: `100.64.0.1:${testPort}`,
|
localAddress: "127.0.0.1",
|
||||||
localAddress: "127.0.0.1",
|
});
|
||||||
|
expect(canvasHostUrl).toBe(`http://100.64.0.1:${canvasPort}`);
|
||||||
});
|
});
|
||||||
expect(canvasHostUrl).toBe(`http://100.64.0.1:${canvasPort}`);
|
});
|
||||||
} finally {
|
|
||||||
envSnapshot.restore();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("send dedupes by idempotencyKey", { timeout: 60_000 }, async () => {
|
test("send dedupes by idempotencyKey", { timeout: 60_000 }, async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user