Jobber/orchestrator/src/server/services/demo-seed.test.ts
Shaheer Sarfaraz fe0aebe01a
Small bits and bobs, codebase quality (#129)
* initial change

* nav highlighting

* icon change

* deeeedoooop

* text

* show version number on all pages

* icon

* remove unused code

* add knip

* formatting

* remove unused code

* types fix

* remove notion completely from the codebase.

* update test for new url structure

* clean up the fucking shop boys

* make a "create job" factory and use that

* moar factories

* formatting
2026-02-10 20:01:58 +00:00

149 lines
4.8 KiB
TypeScript

import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
DEMO_DEFAULT_JOBS,
DEMO_DEFAULT_PIPELINE_RUNS,
DEMO_DEFAULT_SETTINGS,
DEMO_DEFAULT_STAGE_EVENTS,
} from "@server/config/demo-defaults";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const originalEnv = { ...process.env };
function sortedPairs(map: Record<string, string>) {
return Object.entries(map).sort(([a], [b]) => a.localeCompare(b));
}
describe.sequential("demo seed baseline", () => {
let tempDir: string;
let closeDb: (() => void) | null = null;
beforeEach(async () => {
vi.resetModules();
tempDir = await mkdtemp(join(tmpdir(), "job-ops-demo-seed-test-"));
process.env = {
...originalEnv,
DATA_DIR: tempDir,
NODE_ENV: "test",
MODEL: "test-model",
DEMO_MODE: "true",
};
await import("../db/migrate");
const dbMod = await import("../db/index");
closeDb = dbMod.closeDb;
});
afterEach(async () => {
if (closeDb) closeDb();
await rm(tempDir, { recursive: true, force: true });
process.env = { ...originalEnv };
});
it("buildDemoBaseline returns deterministic, schema-shaped fixtures", async () => {
const { buildDemoBaseline } = await import("./demo-seed");
const now = new Date("2026-02-05T12:00:00.000Z");
const baseline = buildDemoBaseline(now);
expect(baseline.resetAt).toBe(now.toISOString());
expect(Object.keys(baseline.settings).length).toBeGreaterThan(0);
expect(baseline.pipelineRuns).toHaveLength(
DEMO_DEFAULT_PIPELINE_RUNS.length,
);
expect(baseline.jobs).toHaveLength(DEMO_DEFAULT_JOBS.length);
expect(baseline.stageEvents).toHaveLength(DEMO_DEFAULT_STAGE_EVENTS.length);
const seededJobIds = baseline.jobs.map((job) => job.id).sort();
expect(seededJobIds).toEqual(DEMO_DEFAULT_JOBS.map((job) => job.id).sort());
});
it("resetDemoData restores settings and data to demo defaults", async () => {
const { db, schema } = await import("../db/index");
const { resetDemoData } = await import("./demo-mode");
const { setSetting, getAllSettings } = await import(
"../repositories/settings"
);
await resetDemoData();
await db.delete(schema.jobs);
await db.insert(schema.jobs).values({
id: "mutated-job",
source: "manual",
title: "Mutated Job",
employer: "Mutated Employer",
jobUrl: "https://demo.job-ops.local/jobs/mutated",
status: "discovered",
});
await setSetting("llmProvider", "openai");
await resetDemoData();
const allJobs = await db.select({ id: schema.jobs.id }).from(schema.jobs);
expect(allJobs.map((row) => row.id).sort()).toEqual(
DEMO_DEFAULT_JOBS.map((job) => job.id).sort(),
);
const allSettings = (await getAllSettings()) as Record<string, string>;
expect(sortedPairs(allSettings)).toEqual(
sortedPairs(DEMO_DEFAULT_SETTINGS as Record<string, string>),
);
});
it("reset is idempotent for logical baseline content", async () => {
const { db, schema } = await import("../db/index");
const { resetDemoData } = await import("./demo-mode");
const logicalSnapshot = async () => {
const [settingsRows, runRows, jobRows, stageRows] = await Promise.all([
db
.select({ key: schema.settings.key, value: schema.settings.value })
.from(schema.settings),
db
.select({
id: schema.pipelineRuns.id,
status: schema.pipelineRuns.status,
jobsDiscovered: schema.pipelineRuns.jobsDiscovered,
jobsProcessed: schema.pipelineRuns.jobsProcessed,
errorMessage: schema.pipelineRuns.errorMessage,
})
.from(schema.pipelineRuns),
db
.select({
id: schema.jobs.id,
status: schema.jobs.status,
source: schema.jobs.source,
title: schema.jobs.title,
employer: schema.jobs.employer,
})
.from(schema.jobs),
db
.select({
id: schema.stageEvents.id,
applicationId: schema.stageEvents.applicationId,
fromStage: schema.stageEvents.fromStage,
toStage: schema.stageEvents.toStage,
title: schema.stageEvents.title,
})
.from(schema.stageEvents),
]);
return {
settings: settingsRows.sort((a, b) => a.key.localeCompare(b.key)),
runs: runRows.sort((a, b) => a.id.localeCompare(b.id)),
jobs: jobRows.sort((a, b) => a.id.localeCompare(b.id)),
stageEvents: stageRows.sort((a, b) => a.id.localeCompare(b.id)),
};
};
await resetDemoData();
const first = await logicalSnapshot();
await resetDemoData();
const second = await logicalSnapshot();
expect(second).toEqual(first);
});
});