Files
Neon-Desk/lib/server/repos/issuer-overlays.test.ts

141 lines
4.0 KiB
TypeScript

import { afterAll, beforeAll, beforeEach, describe, expect, it } from "bun:test";
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { Database } from "bun:sqlite";
import { __dbInternals } from "@/lib/server/db";
import type {
IssuerOverlayDefinition,
IssuerOverlayDiagnostics,
IssuerOverlayStats,
} from "@/lib/server/db/schema";
import {
ensureIssuerOverlayRow,
getIssuerOverlay,
listIssuerOverlayRevisions,
publishIssuerOverlayRevision,
} from "./issuer-overlays";
let tempDir: string | null = null;
let sqliteClient: Database | null = null;
function resetDbSingletons() {
const globalState = globalThis as typeof globalThis & {
__fiscalSqliteClient?: Database;
__fiscalDrizzleDb?: unknown;
__financialIngestionSchemaStatus?: unknown;
};
globalState.__fiscalSqliteClient?.close();
globalState.__fiscalSqliteClient = undefined;
globalState.__fiscalDrizzleDb = undefined;
globalState.__financialIngestionSchemaStatus = undefined;
}
function sampleDefinition(): IssuerOverlayDefinition {
return {
version: "fiscal-v1",
ticker: "AAPL",
pack: "core",
mappings: [
{
surface_key: "revenue",
statement: "income",
allowed_source_concepts: ["aapl:ServicesRevenue", "aapl:ProductRevenue"],
allowed_authoritative_concepts: [],
},
],
};
}
function sampleDiagnostics(): IssuerOverlayDiagnostics {
return {
pack: "core",
sampledSnapshotIds: [11, 12],
acceptedMappings: [
{
qname: "aapl:ServicesRevenue",
surface_key: "revenue",
statement: "income",
reason: "local_name_match",
source_snapshot_ids: [11, 12],
},
],
rejectedMappings: [],
};
}
function sampleStats(): IssuerOverlayStats {
return {
pack: "core",
sampledSnapshotCount: 2,
sampledSnapshotIds: [11, 12],
acceptedMappingCount: 1,
rejectedMappingCount: 0,
publishedRevisionNumber: null,
};
}
describe("issuer overlay repo", () => {
beforeAll(async () => {
tempDir = mkdtempSync(join(tmpdir(), "fiscal-issuer-overlay-"));
const env = process.env as Record<string, string | undefined>;
env.DATABASE_URL = `file:${join(tempDir, "repo.sqlite")}`;
env.NODE_ENV = "test";
resetDbSingletons();
sqliteClient = new Database(join(tempDir, "repo.sqlite"), { create: true });
sqliteClient.exec("PRAGMA foreign_keys = ON;");
__dbInternals.ensureLocalSqliteSchema(sqliteClient);
const globalState = globalThis as typeof globalThis & {
__fiscalSqliteClient?: Database;
__fiscalDrizzleDb?: unknown;
};
globalState.__fiscalSqliteClient = sqliteClient;
globalState.__fiscalDrizzleDb = undefined;
});
afterAll(() => {
sqliteClient?.close();
resetDbSingletons();
if (tempDir) {
rmSync(tempDir, { recursive: true, force: true });
}
});
beforeEach(() => {
sqliteClient?.exec("DELETE FROM issuer_overlay;");
sqliteClient?.exec("DELETE FROM issuer_overlay_revision;");
});
it("creates an empty overlay row on ensure", async () => {
const overlay = await ensureIssuerOverlayRow("aapl");
expect(overlay?.ticker).toBe("AAPL");
expect(overlay?.status).toBe("empty");
expect(overlay?.active_revision).toBeNull();
});
it("publishes and deduplicates overlay revisions by content hash", async () => {
const first = await publishIssuerOverlayRevision({
ticker: "AAPL",
definition: sampleDefinition(),
diagnostics: sampleDiagnostics(),
stats: sampleStats(),
});
const second = await publishIssuerOverlayRevision({
ticker: "AAPL",
definition: sampleDefinition(),
diagnostics: sampleDiagnostics(),
stats: sampleStats(),
});
const overlay = await getIssuerOverlay("AAPL");
const revisions = await listIssuerOverlayRevisions("AAPL");
expect(first.published).toBe(true);
expect(second.published).toBe(false);
expect(overlay?.active_revision?.id).toBe(first.revision.id);
expect(revisions).toHaveLength(1);
});
});