mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 23:56:07 +00:00
test: cover sqlite persisted enum parsing
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { afterEach, describe, expect, expectTypeOf, it } from "vitest";
|
||||
import { closeOpenClawAgentDatabasesForTest } from "../../state/openclaw-agent-db.js";
|
||||
import { closeOpenClawStateDatabaseForTest } from "../../state/openclaw-state-db.js";
|
||||
import type { VirtualAgentFsEntry } from "./agent-filesystem.js";
|
||||
import { parseVirtualAgentFsEntryKind } from "./agent-filesystem.js";
|
||||
import { createSqliteVirtualAgentFs } from "./virtual-agent-fs.sqlite.js";
|
||||
|
||||
function createTempStateDir(): string {
|
||||
@@ -16,6 +18,21 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("SqliteVirtualAgentFs", () => {
|
||||
it("types public results and rejects invalid persisted entry kinds", () => {
|
||||
const scratch = createSqliteVirtualAgentFs({
|
||||
agentId: "main",
|
||||
namespace: "scratch",
|
||||
env: { OPENCLAW_STATE_DIR: createTempStateDir() },
|
||||
});
|
||||
|
||||
expectTypeOf(scratch.stat("/tmp")).toEqualTypeOf<VirtualAgentFsEntry | null>();
|
||||
expect(parseVirtualAgentFsEntryKind("file")).toBe("file");
|
||||
expect(parseVirtualAgentFsEntryKind("directory")).toBe("directory");
|
||||
expect(() => parseVirtualAgentFsEntryKind("socket")).toThrow(
|
||||
"Invalid persisted VFS entry kind",
|
||||
);
|
||||
});
|
||||
|
||||
it("stores scratch files by agent and namespace", () => {
|
||||
const env = { OPENCLAW_STATE_DIR: createTempStateDir() };
|
||||
const mainScratch = createSqliteVirtualAgentFs({
|
||||
|
||||
@@ -196,4 +196,39 @@ describe("DebugProxyCaptureStore", () => {
|
||||
expect(store.readBlob(sharedPayload.dataBlobId ?? "")).toContain('"shared":true');
|
||||
expect(store.listSessions(10).map((session) => session.id)).toEqual(["session-b"]);
|
||||
});
|
||||
|
||||
it("purges sessions, events, and blobs in one store mutation", () => {
|
||||
const store = makeStore();
|
||||
store.upsertSession({
|
||||
id: "session-purge",
|
||||
startedAt: Date.now(),
|
||||
mode: "proxy-run",
|
||||
sourceScope: "openclaw",
|
||||
sourceProcess: "openclaw",
|
||||
dbPath: store.dbPath,
|
||||
blobDir: store.blobDir,
|
||||
});
|
||||
const payload = persistEventPayload(store, {
|
||||
data: "purge me",
|
||||
contentType: "text/plain",
|
||||
});
|
||||
store.recordEvent({
|
||||
sessionId: "session-purge",
|
||||
ts: Date.now(),
|
||||
sourceScope: "openclaw",
|
||||
sourceProcess: "openclaw",
|
||||
protocol: "https",
|
||||
direction: "outbound",
|
||||
kind: "request",
|
||||
flowId: "flow-purge",
|
||||
method: "POST",
|
||||
host: "api.example.com",
|
||||
path: "/v1/purge",
|
||||
...payload,
|
||||
});
|
||||
|
||||
expect(store.purgeAll()).toEqual({ sessions: 1, events: 1, blobs: 1 });
|
||||
expect(store.listSessions(10)).toEqual([]);
|
||||
expect(store.readBlob(payload.dataBlobId ?? "")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,12 @@ import {
|
||||
resolveTaskFlowRegistrySqlitePath,
|
||||
} from "./task-flow-registry.paths.js";
|
||||
import { configureTaskFlowRegistryRuntime } from "./task-flow-registry.store.js";
|
||||
import type { TaskFlowRecord } from "./task-flow-registry.types.js";
|
||||
import {
|
||||
parseOptionalTaskFlowSyncMode,
|
||||
parseTaskFlowStatus,
|
||||
type TaskFlowRecord,
|
||||
} from "./task-flow-registry.types.js";
|
||||
import { parseTaskNotifyPolicy } from "./task-registry.types.js";
|
||||
|
||||
function createStoredFlow(): TaskFlowRecord {
|
||||
return {
|
||||
@@ -125,6 +130,19 @@ describe("task-flow-registry store runtime", () => {
|
||||
expect(restoredFlow.goal).toBe("Restored flow");
|
||||
});
|
||||
|
||||
it("rejects invalid persisted flow enum values", () => {
|
||||
expect(parseOptionalTaskFlowSyncMode("managed")).toBe("managed");
|
||||
expect(parseOptionalTaskFlowSyncMode(null)).toBeUndefined();
|
||||
expect(parseTaskFlowStatus("waiting")).toBe("waiting");
|
||||
expect(parseTaskNotifyPolicy("state_changes")).toBe("state_changes");
|
||||
|
||||
expect(() => parseOptionalTaskFlowSyncMode("legacy")).toThrow(
|
||||
"Invalid persisted task flow sync mode",
|
||||
);
|
||||
expect(() => parseTaskFlowStatus("done")).toThrow("Invalid persisted task flow status");
|
||||
expect(() => parseTaskNotifyPolicy("verbose")).toThrow("Invalid persisted task notify policy");
|
||||
});
|
||||
|
||||
it("restores persisted wait-state, revision, and cancel intent from sqlite", async () => {
|
||||
await withFlowRegistryTempDir(async (root) => {
|
||||
process.env.OPENCLAW_STATE_DIR = root;
|
||||
|
||||
@@ -16,6 +16,14 @@ import {
|
||||
type TaskRegistryObserverEvent,
|
||||
} from "./task-registry.store.js";
|
||||
import type { TaskRecord } from "./task-registry.types.js";
|
||||
import {
|
||||
parseOptionalTaskTerminalOutcome,
|
||||
parseTaskDeliveryStatus,
|
||||
parseTaskNotifyPolicy,
|
||||
parseTaskRuntime,
|
||||
parseTaskScopeKind,
|
||||
parseTaskStatus,
|
||||
} from "./task-registry.types.js";
|
||||
|
||||
const ORIGINAL_STATE_DIR = process.env.OPENCLAW_STATE_DIR;
|
||||
|
||||
@@ -96,6 +104,25 @@ describe("task-registry store runtime", () => {
|
||||
expect(latestSnapshot.tasks.get("task-restored")?.task).toBe("Restored task");
|
||||
});
|
||||
|
||||
it("rejects invalid persisted task enum values", () => {
|
||||
expect(parseTaskRuntime("cron")).toBe("cron");
|
||||
expect(parseTaskScopeKind("system")).toBe("system");
|
||||
expect(parseTaskStatus("running")).toBe("running");
|
||||
expect(parseTaskDeliveryStatus("pending")).toBe("pending");
|
||||
expect(parseTaskNotifyPolicy("done_only")).toBe("done_only");
|
||||
expect(parseOptionalTaskTerminalOutcome("blocked")).toBe("blocked");
|
||||
expect(parseOptionalTaskTerminalOutcome(null)).toBeUndefined();
|
||||
|
||||
expect(() => parseTaskRuntime("timer")).toThrow("Invalid persisted task runtime");
|
||||
expect(() => parseTaskScopeKind("workspace")).toThrow("Invalid persisted task scope kind");
|
||||
expect(() => parseTaskStatus("done")).toThrow("Invalid persisted task status");
|
||||
expect(() => parseTaskDeliveryStatus("ok")).toThrow("Invalid persisted task delivery status");
|
||||
expect(() => parseTaskNotifyPolicy("verbose")).toThrow("Invalid persisted task notify policy");
|
||||
expect(() => parseOptionalTaskTerminalOutcome("failed")).toThrow(
|
||||
"Invalid persisted task terminal outcome",
|
||||
);
|
||||
});
|
||||
|
||||
it("emits incremental observer events for restore, mutation, and delete", () => {
|
||||
const events: TaskRegistryObserverEvent[] = [];
|
||||
configureTaskRegistryRuntime({
|
||||
|
||||
Reference in New Issue
Block a user