mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 04:15:48 -06:00
test(e2e): read shared auth store after onboarding
This commit is contained in:
@@ -1,6 +1,28 @@
|
||||
// Shared auth profile store assertions for install/onboard E2E proof.
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import { isRecord } from "../../lib/record-shared.mjs";
|
||||
|
||||
export function readSharedAuthProfileStoreText(stateDir) {
|
||||
const dbPath = path.join(stateDir, "state", "openclaw.sqlite");
|
||||
if (!fs.existsSync(dbPath)) {
|
||||
return "";
|
||||
}
|
||||
let db;
|
||||
try {
|
||||
db = new DatabaseSync(dbPath, { readOnly: true });
|
||||
const row = db
|
||||
.prepare("SELECT store_json FROM auth_profile_stores WHERE store_key = ?")
|
||||
.get("shared");
|
||||
return typeof row?.store_json === "string" ? row.store_json : "";
|
||||
} catch {
|
||||
return "";
|
||||
} finally {
|
||||
db?.close();
|
||||
}
|
||||
}
|
||||
|
||||
function hasExpectedOpenAiEnvRef(profile) {
|
||||
if (!isRecord(profile)) {
|
||||
return false;
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import { assertOpenAiEnvAuthProfileStore } from "../auth-profile-store-assertions.mjs";
|
||||
import {
|
||||
assertOpenAiEnvAuthProfileStore,
|
||||
readSharedAuthProfileStoreText,
|
||||
} from "../auth-profile-store-assertions.mjs";
|
||||
import {
|
||||
assertPathInside,
|
||||
configPath,
|
||||
@@ -125,24 +127,7 @@ if (providerRuntime && providerRuntime !== "codex") {
|
||||
throw new Error(`unexpected OpenAI provider runtime: ${providerRuntime}`);
|
||||
}
|
||||
|
||||
function readAuthProfileStoreText(agentDir) {
|
||||
const dbPath = path.join(agentDir, "openclaw-agent.sqlite");
|
||||
if (!fs.existsSync(dbPath)) {
|
||||
throw new Error("auth profile SQLite store was not persisted");
|
||||
}
|
||||
let db;
|
||||
try {
|
||||
db = new DatabaseSync(dbPath, { readOnly: true });
|
||||
const row = db
|
||||
.prepare("SELECT store_json FROM auth_profile_store WHERE store_key = ?")
|
||||
.get("primary");
|
||||
return typeof row?.store_json === "string" ? row.store_json : "";
|
||||
} finally {
|
||||
db?.close();
|
||||
}
|
||||
}
|
||||
|
||||
const authRaw = readAuthProfileStoreText(path.join(stateDir(), "agents", "main", "agent"));
|
||||
const authRaw = readSharedAuthProfileStoreText(stateDir());
|
||||
if (!authRaw) {
|
||||
throw new Error("auth profile SQLite store row was not persisted");
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
// Assertions for npm onboard channel-agent E2E scenarios.
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import {
|
||||
assertAgentReplyContainsMarker,
|
||||
assertOpenAiRequestLogUsed,
|
||||
} from "../agent-turn-output.mjs";
|
||||
import { assertOpenAiEnvAuthProfileStore } from "../auth-profile-store-assertions.mjs";
|
||||
import {
|
||||
assertOpenAiEnvAuthProfileStore,
|
||||
readSharedAuthProfileStoreText,
|
||||
} from "../auth-profile-store-assertions.mjs";
|
||||
import { readPositiveIntEnv } from "../env-limits.mjs";
|
||||
import {
|
||||
applyMockOpenAiModelConfig,
|
||||
@@ -77,25 +79,6 @@ function extractStatusSection(text, title) {
|
||||
return stripAnsi(section.join("\n"));
|
||||
}
|
||||
|
||||
function readSharedAuthProfileStoreText(stateDir) {
|
||||
const dbPath = path.join(stateDir, "state", "openclaw.sqlite");
|
||||
if (!fs.existsSync(dbPath)) {
|
||||
return "";
|
||||
}
|
||||
let db;
|
||||
try {
|
||||
db = new DatabaseSync(dbPath, { readOnly: true });
|
||||
const row = db
|
||||
.prepare("SELECT store_json FROM auth_profile_stores WHERE store_key = ?")
|
||||
.get("shared");
|
||||
return typeof row?.store_json === "string" ? row.store_json : "";
|
||||
} catch {
|
||||
return "";
|
||||
} finally {
|
||||
db?.close();
|
||||
}
|
||||
}
|
||||
|
||||
function assertOnboardState() {
|
||||
const home = process.argv[3];
|
||||
const stateDir = path.join(home, ".openclaw");
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
// Assertions for release scenario E2E packages and plugin state.
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import {
|
||||
assertAgentReplyContainsMarker,
|
||||
assertOpenAiRequestLogUsed,
|
||||
} from "../agent-turn-output.mjs";
|
||||
import { assertOpenAiEnvAuthProfileStore } from "../auth-profile-store-assertions.mjs";
|
||||
import {
|
||||
assertOpenAiEnvAuthProfileStore,
|
||||
readSharedAuthProfileStoreText,
|
||||
} from "../auth-profile-store-assertions.mjs";
|
||||
import {
|
||||
applyMockOpenAiModelConfig,
|
||||
parseMockOpenAiPort,
|
||||
@@ -49,39 +51,16 @@ function authProfilesPath() {
|
||||
);
|
||||
}
|
||||
|
||||
function authProfilesDatabasePath() {
|
||||
return path.join(
|
||||
process.env.HOME ?? "",
|
||||
".openclaw",
|
||||
"agents",
|
||||
"main",
|
||||
"agent",
|
||||
"openclaw-agent.sqlite",
|
||||
);
|
||||
}
|
||||
|
||||
function readAuthProfileStoreSqliteText() {
|
||||
const dbPath = authProfilesDatabasePath();
|
||||
if (!fs.existsSync(dbPath)) {
|
||||
return "";
|
||||
}
|
||||
let db;
|
||||
try {
|
||||
db = new DatabaseSync(dbPath, { readOnly: true });
|
||||
const row = db
|
||||
.prepare("SELECT store_json FROM auth_profile_store WHERE store_key = ?")
|
||||
.get("primary");
|
||||
return typeof row?.store_json === "string" ? row.store_json : "";
|
||||
} catch {
|
||||
return "";
|
||||
} finally {
|
||||
db?.close();
|
||||
}
|
||||
function stateDir() {
|
||||
return process.env.OPENCLAW_STATE_DIR ?? path.dirname(configPath());
|
||||
}
|
||||
|
||||
function readStateText() {
|
||||
const paths = [configPath(), authProfilesPath()].filter((file) => fs.existsSync(file));
|
||||
return [...paths.map((file) => fs.readFileSync(file, "utf8")), readAuthProfileStoreSqliteText()]
|
||||
return [
|
||||
...paths.map((file) => fs.readFileSync(file, "utf8")),
|
||||
readSharedAuthProfileStoreText(stateDir()),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
}
|
||||
@@ -96,7 +75,7 @@ function configureMockOpenAi() {
|
||||
function assertOpenAiEnvRef() {
|
||||
const rawKey = process.argv[3];
|
||||
assert(fs.existsSync(configPath()), "openclaw.json missing");
|
||||
assertOpenAiEnvAuthProfileStore(readAuthProfileStoreSqliteText(), {
|
||||
assertOpenAiEnvAuthProfileStore(readSharedAuthProfileStoreText(stateDir()), {
|
||||
missingMessage: "OpenAI env ref was not persisted",
|
||||
envRefMessage: "OpenAI env ref was not persisted",
|
||||
rawKeyMessage: "raw OpenAI key was persisted",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Codex Install Assertions tests cover Codex plugin install E2E helpers.
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
@@ -50,12 +50,13 @@ function writeJson(filePath: string, value: unknown) {
|
||||
writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
||||
}
|
||||
|
||||
function writeAuthProfileStoreSqlite(agentDir: string) {
|
||||
mkdirSync(agentDir, { recursive: true });
|
||||
const db = new DatabaseSync(path.join(agentDir, "openclaw-agent.sqlite"));
|
||||
function writeAuthProfileStoreSqlite(stateDir: string) {
|
||||
const databasePath = path.join(stateDir, "state", "openclaw.sqlite");
|
||||
mkdirSync(path.dirname(databasePath), { recursive: true });
|
||||
const db = new DatabaseSync(databasePath);
|
||||
try {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS auth_profile_store (
|
||||
CREATE TABLE IF NOT EXISTS auth_profile_stores (
|
||||
store_key TEXT NOT NULL PRIMARY KEY,
|
||||
store_json TEXT NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
@@ -63,11 +64,11 @@ function writeAuthProfileStoreSqlite(agentDir: string) {
|
||||
`);
|
||||
db.prepare(
|
||||
`
|
||||
INSERT INTO auth_profile_store (store_key, store_json, updated_at)
|
||||
INSERT INTO auth_profile_stores (store_key, store_json, updated_at)
|
||||
VALUES (?, ?, ?)
|
||||
`,
|
||||
).run(
|
||||
"primary",
|
||||
"shared",
|
||||
JSON.stringify({
|
||||
version: 1,
|
||||
profiles: {
|
||||
@@ -574,7 +575,7 @@ function createCodexInstallFixture(root: string) {
|
||||
writeJson("/tmp/openclaw-plugins-list.json", {
|
||||
plugins: [{ id: "codex", enabled: true, status: "loaded" }],
|
||||
});
|
||||
writeAuthProfileStoreSqlite(path.join(stateDir, "agents", "main", "agent"));
|
||||
writeAuthProfileStoreSqlite(stateDir);
|
||||
}
|
||||
|
||||
describe("Codex install helpers", () => {
|
||||
@@ -692,6 +693,9 @@ describe("Codex install helpers", () => {
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stderr).toBe("");
|
||||
expect(
|
||||
existsSync(path.join(root, "state", "agents", "main", "agent", "openclaw-agent.sqlite")),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects on-demand fixtures without the canonical SQLite install record", () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Release Scenarios Assertions tests cover release scenarios assertions script behavior.
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
@@ -32,12 +32,13 @@ function runAssertion(args: string[], env?: NodeJS.ProcessEnv) {
|
||||
});
|
||||
}
|
||||
|
||||
function writeAuthProfileStoreSqlite(agentDir: string, store: unknown) {
|
||||
mkdirSync(agentDir, { recursive: true });
|
||||
const db = new DatabaseSync(path.join(agentDir, "openclaw-agent.sqlite"));
|
||||
function writeAuthProfileStoreSqlite(stateDir: string, store: unknown) {
|
||||
const databasePath = path.join(stateDir, "state", "openclaw.sqlite");
|
||||
mkdirSync(path.dirname(databasePath), { recursive: true });
|
||||
const db = new DatabaseSync(databasePath);
|
||||
try {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS auth_profile_store (
|
||||
CREATE TABLE IF NOT EXISTS auth_profile_stores (
|
||||
store_key TEXT NOT NULL PRIMARY KEY,
|
||||
store_json TEXT NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
@@ -45,10 +46,10 @@ function writeAuthProfileStoreSqlite(agentDir: string, store: unknown) {
|
||||
`);
|
||||
db.prepare(
|
||||
`
|
||||
INSERT INTO auth_profile_store (store_key, store_json, updated_at)
|
||||
INSERT INTO auth_profile_stores (store_key, store_json, updated_at)
|
||||
VALUES (?, ?, ?)
|
||||
`,
|
||||
).run("primary", JSON.stringify(store), Date.now());
|
||||
).run("shared", JSON.stringify(store), Date.now());
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
@@ -196,7 +197,6 @@ describe("release scenario assertions", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-scenarios-"));
|
||||
const home = path.join(root, "home");
|
||||
const stateDir = path.join(home, ".openclaw");
|
||||
const agentDir = path.join(stateDir, "agents", "main", "agent");
|
||||
const configPath = path.join(stateDir, "openclaw.json");
|
||||
|
||||
try {
|
||||
@@ -207,7 +207,7 @@ describe("release scenario assertions", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
writeAuthProfileStoreSqlite(agentDir, {
|
||||
writeAuthProfileStoreSqlite(stateDir, {
|
||||
version: 1,
|
||||
profiles: {
|
||||
"openai:api-key": {
|
||||
@@ -221,10 +221,14 @@ describe("release scenario assertions", () => {
|
||||
const result = runAssertion(["assert-openai-env-ref", "sk-test-raw-key"], {
|
||||
HOME: home,
|
||||
OPENCLAW_CONFIG_PATH: configPath,
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
});
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stderr).toBe("");
|
||||
expect(
|
||||
existsSync(path.join(stateDir, "agents", "main", "agent", "openclaw-agent.sqlite")),
|
||||
).toBe(false);
|
||||
} finally {
|
||||
rmSync(root, { force: true, recursive: true });
|
||||
}
|
||||
@@ -234,7 +238,6 @@ describe("release scenario assertions", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-scenarios-"));
|
||||
const home = path.join(root, "home");
|
||||
const stateDir = path.join(home, ".openclaw");
|
||||
const agentDir = path.join(stateDir, "agents", "main", "agent");
|
||||
const configPath = path.join(stateDir, "openclaw.json");
|
||||
|
||||
try {
|
||||
@@ -245,7 +248,7 @@ describe("release scenario assertions", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
writeAuthProfileStoreSqlite(agentDir, {
|
||||
writeAuthProfileStoreSqlite(stateDir, {
|
||||
version: 1,
|
||||
profiles: {
|
||||
"openai:api-key": { note: "OPENAI_API_KEY" },
|
||||
@@ -255,6 +258,7 @@ describe("release scenario assertions", () => {
|
||||
const result = runAssertion(["assert-openai-env-ref", "sk-test-raw-key"], {
|
||||
HOME: home,
|
||||
OPENCLAW_CONFIG_PATH: configPath,
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
});
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
@@ -268,7 +272,6 @@ describe("release scenario assertions", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-scenarios-"));
|
||||
const home = path.join(root, "home");
|
||||
const stateDir = path.join(home, ".openclaw");
|
||||
const agentDir = path.join(stateDir, "agents", "main", "agent");
|
||||
const configPath = path.join(stateDir, "openclaw.json");
|
||||
|
||||
try {
|
||||
@@ -279,7 +282,7 @@ describe("release scenario assertions", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
writeAuthProfileStoreSqlite(agentDir, {
|
||||
writeAuthProfileStoreSqlite(stateDir, {
|
||||
version: 1,
|
||||
profiles: {
|
||||
"openai:api-key": {
|
||||
@@ -293,6 +296,7 @@ describe("release scenario assertions", () => {
|
||||
const result = runAssertion(["assert-openai-env-ref", "sk-test-raw-key"], {
|
||||
HOME: home,
|
||||
OPENCLAW_CONFIG_PATH: configPath,
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
});
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
@@ -306,7 +310,6 @@ describe("release scenario assertions", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-scenarios-"));
|
||||
const home = path.join(root, "home");
|
||||
const stateDir = path.join(home, ".openclaw");
|
||||
const agentDir = path.join(stateDir, "agents", "main", "agent");
|
||||
const configPath = path.join(stateDir, "openclaw.json");
|
||||
|
||||
try {
|
||||
@@ -322,7 +325,7 @@ describe("release scenario assertions", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
writeAuthProfileStoreSqlite(agentDir, {
|
||||
writeAuthProfileStoreSqlite(stateDir, {
|
||||
version: 1,
|
||||
profiles: {
|
||||
"openai:api-key": {
|
||||
@@ -336,6 +339,7 @@ describe("release scenario assertions", () => {
|
||||
const result = runAssertion(["assert-openai-env-ref", "sk-test-raw-key"], {
|
||||
HOME: home,
|
||||
OPENCLAW_CONFIG_PATH: configPath,
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
});
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
|
||||
Reference in New Issue
Block a user