Skip to content

Commit 0fa8a20

Browse files
committed
reset test db with prisma reset
reset test db with prisma reset reset test db with prisma reset use custom db reset in `cleanupDb` use ; instead of ); for end of sql splitting reset test db with prisma reset use custom db reset in `cleanupDb` use ; instead of ); for end of sql splitting run prisma reset between tests reset test db with prisma reset use custom db reset in `cleanupDb` use ; instead of ); for end of sql splitting run prisma reset between tests use prisma reset for seeding add instructions for customising Role and Permission seeds
1 parent 1058b3a commit 0fa8a20

File tree

5 files changed

+68
-107
lines changed

5 files changed

+68
-107
lines changed

prisma/migrations/20230914194400_init/migration.sql

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,53 @@ CREATE INDEX "_RoleToUser_B_index" ON "_RoleToUser"("B");
173173
-- Hey there, Kent here! This is how you can reliably seed your database with
174174
-- some data. You edit the migration.sql file and that will handle it for you.
175175

176+
-- The user Roles and Permissions are seeded here.
177+
-- If you'd like to customise roles and permissions, you can edit and add the code below to your `prisma/seed.ts` file.
178+
-- Seed your development database with `npx prisma db seed`
179+
-- Create a sql dump of your database with `sqlite3 prisma/data.db .dump > seed.sql`
180+
-- Replace the SQL below with your new Roles & Permissions related SQL from `seed.sql`
181+
182+
-- console.time('🔑 Created permissions...')
183+
-- const entities = ['user', 'note']
184+
-- const actions = ['create', 'read', 'update', 'delete']
185+
-- const accesses = ['own', 'any'] as const
186+
187+
-- let permissionsToCreate = []
188+
-- for (const entity of entities) {
189+
-- for (const action of actions) {
190+
-- for (const access of accesses) {
191+
-- permissionsToCreate.push({ entity, action, access })
192+
-- }
193+
-- }
194+
-- }
195+
-- await prisma.permission.createMany({ data: permissionsToCreate })
196+
-- console.timeEnd('🔑 Created permissions...')
197+
198+
-- console.time('👑 Created roles...')
199+
-- await prisma.role.create({
200+
-- data: {
201+
-- name: 'admin',
202+
-- permissions: {
203+
-- connect: await prisma.permission.findMany({
204+
-- select: { id: true },
205+
-- where: { access: 'any' },
206+
-- }),
207+
-- },
208+
-- },
209+
-- })
210+
-- await prisma.role.create({
211+
-- data: {
212+
-- name: 'user',
213+
-- permissions: {
214+
-- connect: await prisma.permission.findMany({
215+
-- select: { id: true },
216+
-- where: { access: 'own' },
217+
-- }),
218+
-- },
219+
-- },
220+
-- })
221+
-- console.timeEnd('👑 Created roles...')
222+
176223
INSERT INTO Permission VALUES('clnf2zvli0000pcou3zzzzome','create','user','own','',1696625465526,1696625465526);
177224
INSERT INTO Permission VALUES('clnf2zvll0001pcouly1310ku','create','user','any','',1696625465529,1696625465529);
178225
INSERT INTO Permission VALUES('clnf2zvll0002pcouka7348re','read','user','own','',1696625465530,1696625465530);
@@ -208,4 +255,4 @@ INSERT INTO _PermissionToRole VALUES('clnf2zvlo0006pcouyoptc5jp','clnf2zvlx000hp
208255
INSERT INTO _PermissionToRole VALUES('clnf2zvlp0008pcou9r0fhbm8','clnf2zvlx000hpcou5dfrbegs');
209256
INSERT INTO _PermissionToRole VALUES('clnf2zvlq000apcouxnspejs9','clnf2zvlx000hpcou5dfrbegs');
210257
INSERT INTO _PermissionToRole VALUES('clnf2zvlr000cpcouy1vp6oeg','clnf2zvlx000hpcou5dfrbegs');
211-
INSERT INTO _PermissionToRole VALUES('clnf2zvls000epcou4ts5ui8f','clnf2zvlx000hpcou5dfrbegs');
258+
INSERT INTO _PermissionToRole VALUES('clnf2zvls000epcou4ts5ui8f','clnf2zvlx000hpcou5dfrbegs');

prisma/seed.ts

Lines changed: 2 additions & 43 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,
76
createPassword,
87
createUser,
98
getNoteImages,
109
getUserImages,
1110
img,
11+
resetDb,
1212
} from '#tests/db-utils.ts'
1313
import { insertGitHubUser } from '#tests/mocks/github.ts'
1414

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

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

23-
console.time('🔑 Created permissions...')
24-
const entities = ['user', 'note']
25-
const actions = ['create', 'read', 'update', 'delete']
26-
const accesses = ['own', 'any'] as const
27-
28-
let permissionsToCreate = []
29-
for (const entity of entities) {
30-
for (const action of actions) {
31-
for (const access of accesses) {
32-
permissionsToCreate.push({ entity, action, access })
33-
}
34-
}
35-
}
36-
await prisma.permission.createMany({ data: permissionsToCreate })
37-
console.timeEnd('🔑 Created permissions...')
38-
39-
console.time('👑 Created roles...')
40-
await prisma.role.create({
41-
data: {
42-
name: 'admin',
43-
permissions: {
44-
connect: await prisma.permission.findMany({
45-
select: { id: true },
46-
where: { access: 'any' },
47-
}),
48-
},
49-
},
50-
})
51-
await prisma.role.create({
52-
data: {
53-
name: 'user',
54-
permissions: {
55-
connect: await prisma.permission.findMany({
56-
select: { id: true },
57-
where: { access: 'own' },
58-
}),
59-
},
60-
},
61-
})
62-
console.timeEnd('👑 Created roles...')
63-
6423
const totalUsers = 5
6524
console.time(`👤 Created ${totalUsers} users...`)
6625
const noteImages = await getNoteImages()

tests/db-utils.ts

Lines changed: 14 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { faker } from '@faker-js/faker'
33
import { type PrismaClient } from '@prisma/client'
44
import bcrypt from 'bcryptjs'
55
import { UniqueEnforcer } from 'enforce-unique'
6+
import { execaCommand } from 'execa'
67

78
const uniqueUsernameEnforcer = new UniqueEnforcer()
89

@@ -115,50 +116,17 @@ export async function img({
115116
}
116117
}
117118

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-
}
119+
export async function resetDb(dbPath?: string) {
120+
const databaseUrl = dbPath ? { DATABASE_URL: `file:${dbPath}` } : {}
121+
122+
await execaCommand(
123+
'npx prisma migrate reset --force --skip-seed --skip-generate',
124+
{
125+
stdio: 'inherit',
126+
env: {
127+
...process.env,
128+
...databaseUrl,
129+
},
130+
},
131+
)
164132
}

tests/setup/db-setup.ts

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

76
const databaseFile = `./tests/prisma/data.${process.env.VITEST_POOL_ID || 0}.db`
87
const databasePath = path.join(process.cwd(), databaseFile)
@@ -12,11 +11,8 @@ beforeAll(async () => {
1211
await fsExtra.copyFile(BASE_DATABASE_PATH, databasePath)
1312
})
1413

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

2218
afterAll(async () => {

tests/setup/global-setup.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from 'node:path'
2-
import { execaCommand } from 'execa'
32
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,14 +22,5 @@ export async function setup() {
2222
}
2323
}
2424

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-
)
25+
await resetDb(BASE_DATABASE_PATH)
3526
}

0 commit comments

Comments
 (0)