82 lines
2.9 KiB
TypeScript
82 lines
2.9 KiB
TypeScript
import type pg from 'pg';
|
|
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
import { createPool } from '../../infrastructure/db/pool.js';
|
|
import {
|
|
getTestDbUrl,
|
|
recreateDatabase,
|
|
runMigrations,
|
|
} from '../../infrastructure/db/tests/db-test-support.js';
|
|
import { DEFAULT_STORE_ID } from '../../modules/inventory/index.js';
|
|
|
|
const hasDb = Boolean(process.env.TEST_DATABASE_URL);
|
|
|
|
describe.skipIf(!hasDb)('F-144 reporting store/VAT/cost/shipping snapshots (real PostgreSQL)', () => {
|
|
const url = hasDb ? getTestDbUrl() : '';
|
|
let pool: pg.Pool;
|
|
|
|
beforeAll(async () => {
|
|
await recreateDatabase(url);
|
|
await runMigrations(url, 'up');
|
|
pool = createPool(url);
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await pool.end();
|
|
});
|
|
|
|
async function columnInfo(table: string, column: string) {
|
|
return pool.query(
|
|
'SELECT column_name, is_nullable, column_default FROM information_schema.columns WHERE table_name = $1 AND column_name = $2',
|
|
[table, column],
|
|
);
|
|
}
|
|
|
|
it('adds store_id to orders_orders as NOT NULL w/ default store + FK + index (AC1)', async () => {
|
|
const col = (await columnInfo('orders_orders', 'store_id')).rows[0];
|
|
expect(col).toBeDefined();
|
|
expect(col.is_nullable).toBe('NO');
|
|
expect(col.column_default).toMatch(DEFAULT_STORE_ID);
|
|
|
|
const fk = (
|
|
await pool.query(
|
|
"SELECT conname, contype FROM pg_constraint WHERE conrelid = 'orders_orders'::regclass AND conname = 'orders_orders_store_id_fkey'",
|
|
)
|
|
).rows[0];
|
|
expect(fk).toBeDefined();
|
|
expect(fk.contype).toBe('f'); // foreign key
|
|
|
|
const idx = (
|
|
await pool.query(
|
|
"SELECT indexname FROM pg_indexes WHERE tablename = 'orders_orders' AND indexname = 'orders_orders_store_id_created_at_idx'",
|
|
)
|
|
).rows[0];
|
|
expect(idx).toBeDefined();
|
|
|
|
// New inserts inherit the default store without app-layer changes.
|
|
// `source = 'pos'` is provided to satisfy the 047 CHECK
|
|
// (source = 'pos' OR user_id IS NOT NULL) without touching store_id.
|
|
const inserted = (
|
|
await pool.query("INSERT INTO orders_orders (source) VALUES ('pos') RETURNING store_id, shipping_cents")
|
|
).rows[0];
|
|
expect(inserted.store_id).toBe(DEFAULT_STORE_ID);
|
|
expect(inserted.shipping_cents).toBe(0);
|
|
});
|
|
|
|
it('adds shipping_cents to orders_orders as NOT NULL DEFAULT 0 (AC2)', async () => {
|
|
const col = (await columnInfo('orders_orders', 'shipping_cents')).rows[0];
|
|
expect(col).toBeDefined();
|
|
expect(col.is_nullable).toBe('NO');
|
|
expect(col.column_default).toContain('0');
|
|
});
|
|
|
|
it('adds cost_at_sale_cents and vat_rate snapshots to orders_items as nullable — no history rewrite (AC3)', async () => {
|
|
const cost = (await columnInfo('orders_items', 'cost_at_sale_cents')).rows[0];
|
|
expect(cost).toBeDefined();
|
|
expect(cost.is_nullable).toBe('YES');
|
|
|
|
const vat = (await columnInfo('orders_items', 'vat_rate')).rows[0];
|
|
expect(vat).toBeDefined();
|
|
expect(vat.is_nullable).toBe('YES');
|
|
});
|
|
});
|