mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-19 08:28:06 +02:00
156 lines
4.4 KiB
TypeScript
156 lines
4.4 KiB
TypeScript
import { mkdtemp, rm } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
import { SqliteLocalIngestStore } from '../../../src/context/ingest/sqlite-local-ingest-store.js';
|
|
import type { LocalIngestRunRecord } from '../../../src/context/ingest/local-stage-ingest.js';
|
|
|
|
function runRecord(overrides: Partial<LocalIngestRunRecord> = {}): LocalIngestRunRecord {
|
|
return {
|
|
runId: 'local-run-1',
|
|
jobId: 'local-run-1',
|
|
status: 'done',
|
|
adapter: 'fake',
|
|
connectionId: 'warehouse',
|
|
sourceDir: '/tmp/source',
|
|
syncId: '2026-04-27-120000-local-run-1',
|
|
startedAt: '2026-04-27T12:00:00.000Z',
|
|
completedAt: '2026-04-27T12:00:01.000Z',
|
|
progress: 1,
|
|
done: true,
|
|
previousRunId: null,
|
|
diffSummary: {
|
|
added: 1,
|
|
modified: 0,
|
|
deleted: 0,
|
|
unchanged: 0,
|
|
},
|
|
diffPaths: {
|
|
added: ['orders/orders.json'],
|
|
modified: [],
|
|
deleted: [],
|
|
unchanged: [],
|
|
},
|
|
workUnitCount: 1,
|
|
rawFileCount: 1,
|
|
workUnits: [
|
|
{
|
|
unitKey: 'fake-orders',
|
|
rawFiles: ['orders/orders.json'],
|
|
peerFileIndex: [],
|
|
dependencyPaths: [],
|
|
},
|
|
],
|
|
evictionDeletedRawPaths: [],
|
|
errors: [],
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
describe('SqliteLocalIngestStore', () => {
|
|
let tempDir: string;
|
|
let dbPath: string;
|
|
|
|
beforeEach(async () => {
|
|
tempDir = await mkdtemp(join(tmpdir(), 'ktx-sqlite-local-ingest-'));
|
|
dbPath = join(tempDir, '.ktx', 'db.sqlite');
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await rm(tempDir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('persists and reads a local ingest run by id', () => {
|
|
const store = new SqliteLocalIngestStore({ dbPath });
|
|
const record = runRecord();
|
|
|
|
store.saveCompletedRun({
|
|
record,
|
|
rawContentHashes: {
|
|
'orders/orders.json': 'hash-1',
|
|
},
|
|
});
|
|
|
|
expect(store.findRunById('local-run-1')).toEqual(record);
|
|
expect(store.findRunById('missing-run')).toBeNull();
|
|
});
|
|
|
|
it('returns the latest completed report for the same connection and adapter', () => {
|
|
const store = new SqliteLocalIngestStore({ dbPath });
|
|
const first = runRecord({
|
|
runId: 'local-run-1',
|
|
jobId: 'local-run-1',
|
|
completedAt: '2026-04-27T12:00:00.000Z',
|
|
});
|
|
const second = runRecord({
|
|
runId: 'local-run-2',
|
|
jobId: 'local-run-2',
|
|
syncId: '2026-04-27-120500-local-run-2',
|
|
completedAt: '2026-04-27T12:05:00.000Z',
|
|
previousRunId: 'local-run-1',
|
|
});
|
|
const otherAdapter = runRecord({
|
|
runId: 'metabase-run-1',
|
|
jobId: 'metabase-run-1',
|
|
adapter: 'metabase',
|
|
syncId: '2026-04-27-121000-metabase-run-1',
|
|
completedAt: '2026-04-27T12:10:00.000Z',
|
|
});
|
|
|
|
store.saveCompletedRun({
|
|
record: first,
|
|
rawContentHashes: {
|
|
'orders/orders.json': 'hash-1',
|
|
},
|
|
});
|
|
store.saveCompletedRun({
|
|
record: second,
|
|
rawContentHashes: {
|
|
'orders/orders.json': 'hash-2',
|
|
'orders/payments.json': 'hash-3',
|
|
},
|
|
});
|
|
store.saveCompletedRun({
|
|
record: otherAdapter,
|
|
rawContentHashes: {
|
|
'cards/revenue.json': 'hash-4',
|
|
},
|
|
});
|
|
|
|
expect(store.findLatestCompletedReport('warehouse', 'fake')).toMatchObject({
|
|
runId: 'local-run-2',
|
|
previousRunId: 'local-run-1',
|
|
rawContentHashes: {
|
|
'orders/orders.json': 'hash-2',
|
|
'orders/payments.json': 'hash-3',
|
|
},
|
|
});
|
|
expect(store.findLatestCompletedReport('warehouse', 'fake', { excludeRunId: 'local-run-2' })).toMatchObject({
|
|
runId: 'local-run-1',
|
|
rawContentHashes: {
|
|
'orders/orders.json': 'hash-1',
|
|
},
|
|
});
|
|
expect(store.findLatestCompletedReport('warehouse', 'fake', { excludeRunId: 'local-run-1' })).toMatchObject({
|
|
runId: 'local-run-2',
|
|
rawContentHashes: {
|
|
'orders/orders.json': 'hash-2',
|
|
'orders/payments.json': 'hash-3',
|
|
},
|
|
});
|
|
expect(store.findLatestCompletedReport('warehouse', 'metabase')).toMatchObject({
|
|
runId: 'metabase-run-1',
|
|
rawContentHashes: {
|
|
'cards/revenue.json': 'hash-4',
|
|
},
|
|
});
|
|
expect(store.findLatestCompletedReport('missing', 'fake')).toBeNull();
|
|
});
|
|
|
|
it('ignores malformed run ids when reading status', () => {
|
|
const store = new SqliteLocalIngestStore({ dbPath });
|
|
|
|
expect(store.findRunById('../escape')).toBeNull();
|
|
expect(store.findRunById('')).toBeNull();
|
|
});
|
|
});
|