You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Test files hand-roll CREATE TABLE DDL per backend, duplicating src/db/schema/. That DDL drifts from the real schema: a single schema column-add breaks N tests, and the PG/MySQL copies (only run in CI) diverge silently — this is exactly how the #3495 PostgreSQL test-table gap slipped past local runs.
A shared helper was introduced to fix this by construction:
src/server/test-helpers/testDb.ts — createTestDb() runs the real SQLite migration registry (baseline 001 + every ALTER) against a fresh :memory: database, returning { sqlite, db, close }. Every test gets the exact production schema; a schema change is a single edit with zero test-DDL to update.
This issue tracks migrating the remaining 32 files that still hand-roll DDL. It's deferred because it's an incremental, individually-verified effort (see "friction" below), not a safe bulk find-replace.
Migration recipe (per file)
Imports: drop drizzle from the drizzle-orm/better-sqlite3 import (keep the BetterSQLite3Database type); add import { createTestDb } from '../../server/test-helpers/testDb.js'; (adjust relative path).
Replace the beforeEach DB setup:
// before: new Database(':memory:') + db.exec(CREATE TABLE ...) + drizzle(db, { schema })constt=createTestDb();db=t.sqlite;drizzleDb=t.db;// ... construct repo as before
Adjust reference-data seeding (the friction — see below).
Verify: npx vitest run <file> → green, then tsc --noEmit, then the full suite.
Per-file friction / gotchas
Reference-data seeds must satisfy the full schema's NOT NULL / PK columns. The hand-rolled tables were simplified; the real schema is stricter. E.g. seeding nodes requires sourceId (composite PK (nodeNum, sourceId) from migration 029) andcreatedAt/updatedAt NOT NULL. The minimal INSERT INTO nodes (nodeNum, nodeId) the old tests used will fail — use:
FKs are not enforced (better-sqlite3 defaults PRAGMA foreign_keys=OFF, and migration 041 dropped the telemetry→nodes FK), so reference rows are only needed where a test reads joined/enriched data.
Multi-backend files (PG/MySQL DDL, run only in CI) are NOT covered by createTestDb() (SQLite-only). Either leave their per-backend DDL, or extend the helper with PG/MySQL variants in a separate effort.
Remaining files (32)
SQLite-only — drop-in candidates (25)
db/repositories/analysis.test.ts (8 separate DB setups — heavier)
db/repositories/auth.test.ts
db/repositories/auth.migration.test.ts (verify it's not asserting historical migration state)
Multi-backend — needs PG/MySQL handling, NOT a plain createTestDb() swap (4)
db/repositories/misc.test.ts
db/repositories/neighbors.test.ts
db/repositories/notifications.test.ts
db/repositories/traceroutes.test.ts
Intentionally NOT migrated (2)
db/repositories/telemetry.multidb.test.ts — multi-backend by design (exercises per-backend DDL on purpose).
db/repositories/schemaIntegrity.test.ts — asserts the hand-rolled DDL aligns with the schema; migrating it would defeat its purpose.
Suggested approach
Batch by domain (nodes, auth, channels, meshcore, services, database facade), one small PR each, verifying the file's tests + full suite per batch. Tackle the simple single-DB repo tests first; leave the facade (database.*) and analysis.test.ts for last (multiple/heavier setups). For the multi-backend files, decide separately whether to extend createTestDb() with PG/MySQL variants.
Refs: #3498, #3500. Part of the section-B refactors from the systemic review.
Background
Test files hand-roll
CREATE TABLEDDL per backend, duplicatingsrc/db/schema/. That DDL drifts from the real schema: a single schema column-add breaks N tests, and the PG/MySQL copies (only run in CI) diverge silently — this is exactly how the #3495 PostgreSQL test-table gap slipped past local runs.A shared helper was introduced to fix this by construction:
src/server/test-helpers/testDb.ts—createTestDb()runs the real SQLite migration registry (baseline 001 + every ALTER) against a fresh:memory:database, returning{ sqlite, db, close }. Every test gets the exact production schema; a schema change is a single edit with zero test-DDL to update.This issue tracks migrating the remaining 32 files that still hand-roll DDL. It's deferred because it's an incremental, individually-verified effort (see "friction" below), not a safe bulk find-replace.
Migration recipe (per file)
drizzlefrom thedrizzle-orm/better-sqlite3import (keep theBetterSQLite3Databasetype); addimport { createTestDb } from '../../server/test-helpers/testDb.js';(adjust relative path).beforeEachDB setup:npx vitest run <file>→ green, thentsc --noEmit, then the full suite.Per-file friction / gotchas
nodesrequiressourceId(composite PK(nodeNum, sourceId)from migration 029) andcreatedAt/updatedAtNOT NULL. The minimalINSERT INTO nodes (nodeNum, nodeId)the old tests used will fail — use:PRAGMA foreign_keys=OFF, and migration 041 dropped the telemetry→nodes FK), so reference rows are only needed where a test reads joined/enriched data.CREATE INDEX/table that the migrations now provide should be removed (e.g. the migration-032 dedupe index — see the refactor(test): shared createTestDb helper from migration registry (section B2, part 1) #3498 review). Leaving it is harmless (IF NOT EXISTS) but confusing.createTestDb()(SQLite-only). Either leave their per-backend DDL, or extend the helper with PG/MySQL variants in a separate effort.Remaining files (32)
SQLite-only — drop-in candidates (25)
db/repositories/analysis.test.ts(8 separate DB setups — heavier)db/repositories/auth.test.tsdb/repositories/auth.migration.test.ts(verify it's not asserting historical migration state)db/repositories/autoFavoriteTargets.perSource.test.tsdb/repositories/channelDatabase.test.tsdb/repositories/channels.test.tsdb/repositories/embedProfiles.test.tsdb/repositories/ignoredNodes.test.tsdb/repositories/meshcore.test.tsdb/repositories/meshcorePacketLog.perSource.test.tsdb/repositories/messages.bigint.test.ts(seeds nodes with longName/shortName)db/repositories/messages.migration.test.tsdb/repositories/misc.packetlog.test.ts(3 DB setups)db/repositories/nodes.test.tsdb/repositories/nodes.invalidNodeNum.test.tsdb/repositories/nodes.pruneOutsideBbox.test.tsdb/repositories/perSource.test.tsdb/repositories/settings.test.tsdb/repositories/sources.test.tsserver/services/appriseNotificationService.test.tsserver/services/pushNotificationService.test.tsserver/services/solarMonitoringService.test.tsservices/database.test.ts(facade — heavier; verify it doesn't already self-init a DB)services/database.audit.test.tsservices/database.extended.test.ts,services/database.unread.test.tsMulti-backend — needs PG/MySQL handling, NOT a plain createTestDb() swap (4)
db/repositories/misc.test.tsdb/repositories/neighbors.test.tsdb/repositories/notifications.test.tsdb/repositories/traceroutes.test.tsIntentionally NOT migrated (2)
db/repositories/telemetry.multidb.test.ts— multi-backend by design (exercises per-backend DDL on purpose).db/repositories/schemaIntegrity.test.ts— asserts the hand-rolled DDL aligns with the schema; migrating it would defeat its purpose.Suggested approach
Batch by domain (nodes, auth, channels, meshcore, services, database facade), one small PR each, verifying the file's tests + full suite per batch. Tackle the simple single-DB repo tests first; leave the facade (
database.*) andanalysis.test.tsfor last (multiple/heavier setups). For the multi-backend files, decide separately whether to extendcreateTestDb()with PG/MySQL variants.Refs: #3498, #3500. Part of the section-B refactors from the systemic review.