@accounter/server
Version:
Accounter GraphQL server
127 lines (112 loc) • 4.47 kB
text/typescript
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { TestDatabase, isPoolHealthy } from './helpers/db-setup.js';
import { assertLatestMigrationApplied } from './helpers/migration-verification.js';
import { seedAdminCore } from '../../scripts/seed-admin-context.js';
import { qualifyTable } from './helpers/test-db-config.js';
import { buildAdminContextFromDb } from './helpers/admin-context-builder.js';
/**
* Smoke test for DB test harness
* Verifies the full bootstrap pipeline: connect → seed → query
*
* NOTE: We assume migrations were run via `yarn db:init` beforehand.
*/
describe('DB Test Harness Bootstrap', () => {
let db: TestDatabase;
const EXPECTED_TAX_CATEGORIES = 20;
beforeAll(async () => {
db = new TestDatabase();
await db.connect();
});
afterAll(async () => {
await db.close();
});
it('connects to database', () => {
const pool = db.getPool();
expect(pool).toBeDefined();
const m = isPoolHealthy(pool);
expect(m.total).toBeGreaterThanOrEqual(0);
});
it('is at latest migration (schema ready)', async () =>
db.withTransaction(async client => {
await assertLatestMigrationApplied(client);
}));
it('has admin business after seeding', async () =>
db.withTransaction(async client => {
await seedAdminCore(client);
const result = await client.query(
`SELECT fe.id, fe.name
FROM ${qualifyTable('financial_entities')} fe
JOIN ${qualifyTable('businesses')} b ON fe.id = b.id
WHERE fe.name = 'Admin Business'`,
);
expect(result.rows).toHaveLength(1);
expect(result.rows[0].name).toBe('Admin Business');
expect(result.rows[0].id).toBeDefined();
}));
it('has 3 authorities after seeding', async () =>
db.withTransaction(async client => {
await seedAdminCore(client);
const result = await client.query(
`SELECT COUNT(*)
FROM ${qualifyTable('financial_entities')} fe
JOIN ${qualifyTable('businesses')} b ON fe.id = b.id
WHERE fe.name IN ('VAT', 'Tax', 'Social Security')`,
);
const count = parseInt(result.rows[0].count, 10);
expect(count).toBe(3);
}));
it('has expected tax categories', async () =>
db.withTransaction(async client => {
await seedAdminCore(client);
const adminContext = await buildAdminContextFromDb(client);
const result = await client.query(
`SELECT COUNT(tc.*) FROM ${qualifyTable('tax_categories')} tc
LEFT JOIN ${qualifyTable('financial_entities')} fe USING (id)
WHERE fe.owner_id = $1`,
[adminContext.ownerId]
);
const count = parseInt(result.rows[0].count, 10);
expect(count).toBeGreaterThanOrEqual(EXPECTED_TAX_CATEGORIES);
}));
it('has user_context after seeding', async () =>
db.withTransaction(async client => {
await seedAdminCore(client);
const adminContext = await buildAdminContextFromDb(client);
const result = await client.query(
`SELECT owner_id, vat_business_id FROM ${qualifyTable('user_context')} WHERE owner_id = $1 LIMIT 1`,
[adminContext.ownerId]
);
expect(result.rows).toHaveLength(1);
expect(result.rows[0].owner_id).toBeDefined();
expect(result.rows[0].vat_business_id).toBeDefined();
}));
it('rolls back changes between transactions (independent)', async () => {
const TEMP_NAME = 'Temporary Test Entity (Rollback)';
await db.withTransaction(async client => {
const insertResult = await client.query(
`INSERT INTO ${qualifyTable('financial_entities')} (name, type)
VALUES ($1, 'business')
RETURNING id`,
[TEMP_NAME],
);
const entityId = insertResult.rows[0].id;
await client.query(
`INSERT INTO ${qualifyTable('businesses')} (id, owner_id) VALUES ($1, $2)`,
[entityId, entityId],
);
const selectInTx = await client.query(
`SELECT COUNT(*) FROM ${qualifyTable('financial_entities')} WHERE name = $1`,
[TEMP_NAME],
);
expect(parseInt(selectInTx.rows[0].count, 10)).toBe(1);
});
await db.withTransaction(async client => {
const result = await client.query(
`SELECT COUNT(*) FROM ${qualifyTable('financial_entities')} WHERE name = $1`,
[TEMP_NAME],
);
const count = parseInt(result.rows[0].count, 10);
expect(count).toBe(0);
});
});
});