Drives all infra src files to 100% (env.ts, db/client.ts, db/ensure-dir.ts, db/migrate.ts, db/seed.ts, routes/health.ts). - env.test.ts: dev defaults when unset, overrides when set (PORT coerced), CORS_ORIGINS parsing (trim + drop empties) and empty-fallback. - db.test.ts: runMigrations idempotency; ensureDbDir no-op for non-file URLs and bare filenames (branch coverage). - seed.test.ts: production guard — no dev users seeded when NODE_ENV=production. - c8-ignore the migrate.ts/seed.ts CLI direct-run blocks (unreachable under vitest). No lifecycle test (infra domain, per plan). No bugs found — infra code correct; only coverage gaps. All 112 API tests green; typecheck + oxlint clean.
65 lines
2.2 KiB
TypeScript
65 lines
2.2 KiB
TypeScript
import { describe, it, expect, beforeEach } from 'vitest';
|
|
import { inArray, eq } from 'drizzle-orm';
|
|
import { seed } from '../src/db/seed';
|
|
import { db } from '../src/db/client';
|
|
import { activities, user } from '../src/db/schema';
|
|
import { resetDb } from './helpers';
|
|
|
|
const SEED_NAMES = ['Leerrand', 'Frezen', 'Slijpen', 'Bekleden', 'Afwerken', 'Printen'];
|
|
|
|
describe('seed', () => {
|
|
it('seeds the reference activities idempotently', async () => {
|
|
await seed();
|
|
const first = await db.select().from(activities).where(inArray(activities.name, SEED_NAMES));
|
|
const countFirst = first.length;
|
|
|
|
await seed();
|
|
const second = await db.select().from(activities).where(inArray(activities.name, SEED_NAMES));
|
|
|
|
expect(second.length).toBe(countFirst);
|
|
expect(countFirst).toBe(SEED_NAMES.length);
|
|
|
|
const printen = await db.select().from(activities).where(eq(activities.name, 'Printen'));
|
|
expect(printen).toHaveLength(1);
|
|
expect(printen[0]?.insoleTypes).toEqual(['3D']);
|
|
});
|
|
|
|
it('seeds the dev worker + dev admin idempotently with correct roles', async () => {
|
|
await seed();
|
|
const w = await db.select().from(user).where(eq(user.email, 'worker@solelog.local'));
|
|
const a = await db.select().from(user).where(eq(user.email, 'admin@solelog.local'));
|
|
expect(w).toHaveLength(1);
|
|
expect(a).toHaveLength(1);
|
|
expect((a[0] as { role?: string }).role).toBe('admin');
|
|
|
|
await seed();
|
|
expect(await db.select().from(user).where(eq(user.email, 'admin@solelog.local'))).toHaveLength(
|
|
1,
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('seed — production guard', () => {
|
|
beforeEach(resetDb);
|
|
|
|
it('seeds reference activities but never the dev users when NODE_ENV=production', async () => {
|
|
const prev = process.env.NODE_ENV;
|
|
process.env.NODE_ENV = 'production';
|
|
try {
|
|
await seed();
|
|
} finally {
|
|
if (prev === undefined) delete process.env.NODE_ENV;
|
|
else process.env.NODE_ENV = prev;
|
|
}
|
|
|
|
const devUsers = await db
|
|
.select()
|
|
.from(user)
|
|
.where(inArray(user.email, ['worker@solelog.local', 'admin@solelog.local']));
|
|
expect(devUsers).toHaveLength(0);
|
|
|
|
const acts = await db.select().from(activities).where(inArray(activities.name, SEED_NAMES));
|
|
expect(acts.length).toBe(SEED_NAMES.length);
|
|
});
|
|
});
|