Skip to content

Commit d5afca7

Browse files
committed
use custom db reset
1 parent ee9ec4e commit d5afca7

File tree

4 files changed

+65
-20
lines changed

4 files changed

+65
-20
lines changed

prisma/seed.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { promiseHash } from 'remix-utils/promise'
33
import { prisma } from '#app/utils/db.server.ts'
44
import { MOCK_CODE_GITHUB } from '#app/utils/providers/constants'
55
import {
6+
cleanupDb,
67
createPassword,
78
createUser,
89
getNoteImages,
910
getUserImages,
1011
img,
11-
resetDb,
1212
} from '#tests/db-utils.ts'
1313
import { insertGitHubUser } from '#tests/mocks/github.ts'
1414

@@ -17,7 +17,7 @@ async function seed() {
1717
console.time(`🌱 Database has been seeded`)
1818

1919
console.time('🧹 Cleaned up the database...')
20-
await resetDb()
20+
await cleanupDb(prisma)
2121
console.timeEnd('🧹 Cleaned up the database...')
2222

2323
const totalUsers = 5

tests/db-utils.ts

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { spawnSync } from 'node:child_process'
21
import fs from 'node:fs'
32
import { faker } from '@faker-js/faker'
3+
import { type PrismaClient } from '@prisma/client'
44
import bcrypt from 'bcryptjs'
55
import { UniqueEnforcer } from 'enforce-unique'
66

@@ -115,17 +115,50 @@ export async function img({
115115
}
116116
}
117117

118-
export async function resetDb(dbPath?: string) {
119-
const databaseUrl = dbPath ? { DATABASE_URL: `file:${dbPath}` } : {}
120-
121-
spawnSync(
122-
'npx',
123-
['prisma', 'migrate', 'reset', '--force', '--skip-seed', '--skip-generate'],
124-
{
125-
env: {
126-
...process.env,
127-
...databaseUrl,
128-
},
129-
},
130-
)
118+
export async function cleanupDb(prisma: PrismaClient) {
119+
const tables = await prisma.$queryRaw<
120+
{ name: string }[]
121+
>`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_migrations';`
122+
123+
const migrationPaths = fs
124+
.readdirSync('prisma/migrations')
125+
.filter((dir) => dir !== 'migration_lock.toml')
126+
.map((dir) => `prisma/migrations/${dir}/migration.sql`)
127+
128+
const migrations = migrationPaths.map((path) => {
129+
// Parse the sql into individual statements
130+
const sql = fs
131+
.readFileSync(path)
132+
.toString()
133+
.split(';')
134+
.map((statement) => (statement += ';'))
135+
136+
// Remove empty last line
137+
sql.pop()
138+
139+
return sql
140+
})
141+
142+
try {
143+
// Disable FK constraints to avoid relation conflicts during deletion
144+
await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = OFF`)
145+
await prisma.$transaction([
146+
// Delete all tables except the ones that are excluded above
147+
...tables.map(({ name }) =>
148+
prisma.$executeRawUnsafe(`DROP TABLE "${name}"`),
149+
),
150+
])
151+
152+
// Run the migrations sequentially
153+
for (const migration of migrations) {
154+
await prisma.$transaction([
155+
// Run each sql statement in the migration
156+
...migration.map((sql) => prisma.$executeRawUnsafe(sql)),
157+
])
158+
}
159+
} catch (error) {
160+
console.error('Error cleaning up database:', error)
161+
} finally {
162+
await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = ON`)
163+
}
131164
}

tests/setup/db-setup.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'node:path'
22
import fsExtra from 'fs-extra'
33
import { afterAll, afterEach, beforeAll } from 'vitest'
4-
import { resetDb } from '#tests/db-utils.js'
4+
import { cleanupDb } from '#tests/db-utils.ts'
55
import { BASE_DATABASE_PATH } from './global-setup.ts'
66

77
const databaseFile = `./tests/prisma/data.${process.env.VITEST_POOL_ID || 0}.db`
@@ -12,8 +12,11 @@ beforeAll(async () => {
1212
await fsExtra.copyFile(BASE_DATABASE_PATH, databasePath)
1313
})
1414

15+
// we *must* use dynamic imports here so the process.env.DATABASE_URL is set
16+
// before prisma is imported and initialized
1517
afterEach(async () => {
16-
await resetDb()
18+
const { prisma } = await import('#app/utils/db.server.ts')
19+
await cleanupDb(prisma)
1720
})
1821

1922
afterAll(async () => {

tests/setup/global-setup.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from 'node:path'
2+
import { execaCommand } from 'execa'
23
import fsExtra from 'fs-extra'
3-
import { resetDb } from '#tests/db-utils.js'
44

55
export const BASE_DATABASE_PATH = path.join(
66
process.cwd(),
@@ -22,5 +22,14 @@ export async function setup() {
2222
}
2323
}
2424

25-
await resetDb(BASE_DATABASE_PATH)
25+
await execaCommand(
26+
'npx prisma migrate reset --force --skip-seed --skip-generate',
27+
{
28+
stdio: 'inherit',
29+
env: {
30+
...process.env,
31+
DATABASE_URL: `file:${BASE_DATABASE_PATH}`,
32+
},
33+
},
34+
)
2635
}

0 commit comments

Comments
 (0)