GitNexus/gitnexus/test/unit/convex-metadata-persistence-contract.test.ts
azizur100389 9d4f029001
fix(impact): mark Convex caller results incomplete (#3044)
* fix(impact): mark Convex caller results incomplete

* fix(storage): align Convex Const persistence
2026-08-26 12:54:00 +01:00

123 lines
4.4 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest';
import { CONST_SCHEMA, FUNCTION_SCHEMA } from '../../src/core/lbug/schema.js';
interface FakeQueryResult {
getAll: () => Promise<unknown[]>;
close: () => void;
}
function makeConfigMock() {
const queries: string[] = [];
const queryResult: FakeQueryResult = { getAll: async () => [], close: vi.fn() };
const conn = {
query: vi.fn(async (cypher: string) => {
queries.push(cypher);
return queryResult;
}),
close: vi.fn(async () => {}),
};
const db = { close: vi.fn(async () => {}) };
return {
queries,
mock: {
openLbugConnection: vi.fn(async () => ({ db, conn })),
closeLbugConnection: async () => {
await conn.close();
await db.close();
},
isDbBusyError: vi.fn(() => false),
isOpenRetryExhausted: vi.fn(() => false),
isWalCorruptionError: vi.fn(() => false),
toNativeSafePath: (value: string) => value,
resolveNativeSafeStorageDir: (value: string) => value,
WAL_RECOVERY_SUGGESTION: 'run analyze --force',
waitForWindowsHandleRelease: vi.fn(async () => true),
},
};
}
const endpoint = {
id: 'Const:src/endpoints.ts:getUser',
name: 'getUser',
filePath: 'src/endpoints.ts',
startLine: 1,
endLine: 3,
isExported: true,
content: 'query({ handler: getUser })',
convexEndpointFactory: 'query',
};
describe('Convex endpoint metadata persistence contract', () => {
afterEach(() => {
vi.doUnmock('../../src/core/lbug/lbug-config.js');
vi.resetModules();
vi.clearAllMocks();
});
it('keeps the Const schema and COPY column list aligned', async () => {
const { getCopyQuery } = await import('../../src/core/lbug/lbug-adapter.js');
const copyQuery = getCopyQuery('Const', '/tmp/const.csv');
const functionCopyQuery = getCopyQuery('Function', '/tmp/function.csv');
expect(CONST_SCHEMA).toContain('convexEndpointFactory STRING');
expect(FUNCTION_SCHEMA).toContain('convexEndpointFactory STRING');
expect(CONST_SCHEMA).not.toContain('isExported BOOLEAN');
expect(copyQuery).toContain('content, description, convexEndpointFactory');
expect(functionCopyQuery).toContain('isExported, content, description, convexEndpointFactory');
expect(copyQuery).not.toContain('isExported');
});
it('persists the property through single-node CREATE', async () => {
const { mock, queries } = makeConfigMock();
vi.doMock('../../src/core/lbug/lbug-config.js', () => mock);
const { insertNodeToLbug } = await import('../../src/core/lbug/lbug-adapter.js');
await expect(insertNodeToLbug('Const', endpoint, '/tmp/convex-create/lbug')).resolves.toBe(
true,
);
const createQuery = queries.find((query) => query.startsWith('CREATE (n:Const'));
expect(createQuery).toContain("convexEndpointFactory: 'query'");
expect(createQuery).not.toContain('isExported');
await expect(
insertNodeToLbug(
'Function',
{ ...endpoint, id: 'Function:src/endpoints.ts:getUser' },
'/tmp/convex-create/lbug',
),
).resolves.toBe(true);
const functionQuery = queries.find((query) => query.startsWith('CREATE (n:Function'));
expect(functionQuery).toContain("convexEndpointFactory: 'query'");
expect(functionQuery).toContain('isExported: true');
});
it('persists the property through incremental MERGE', async () => {
const { mock, queries } = makeConfigMock();
vi.doMock('../../src/core/lbug/lbug-config.js', () => mock);
const { batchInsertNodesToLbug } = await import('../../src/core/lbug/lbug-adapter.js');
await expect(
batchInsertNodesToLbug([{ label: 'Const', properties: endpoint }], '/tmp/convex-merge/lbug'),
).resolves.toEqual({ inserted: 1, failed: 0 });
const mergeQuery = queries.find((query) => query.startsWith('MERGE (n:Const'));
expect(mergeQuery).toContain("n.convexEndpointFactory = 'query'");
expect(mergeQuery).not.toContain('isExported');
await expect(
batchInsertNodesToLbug(
[
{
label: 'Function',
properties: { ...endpoint, id: 'Function:src/endpoints.ts:getUser' },
},
],
'/tmp/convex-merge/lbug',
),
).resolves.toEqual({ inserted: 1, failed: 0 });
const functionQuery = queries.find((query) => query.startsWith('MERGE (n:Function'));
expect(functionQuery).toContain("n.convexEndpointFactory = 'query'");
expect(functionQuery).toContain('n.isExported = true');
});
});