Skip to content

Commit

Permalink
Save Role seeds between integration tests (#834)
Browse files Browse the repository at this point in the history
  • Loading branch information
devneill authored Sep 14, 2024
1 parent 7932179 commit 98702a6
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 79 deletions.
49 changes: 48 additions & 1 deletion prisma/migrations/20230914194400_init/migration.sql
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,53 @@ CREATE INDEX "_RoleToUser_B_index" ON "_RoleToUser"("B");
-- Hey there, Kent here! This is how you can reliably seed your database with
-- some data. You edit the migration.sql file and that will handle it for you.

-- The user Roles and Permissions are seeded here.
-- If you'd like to customise roles and permissions, you can edit and add the code below to your `prisma/seed.ts` file.
-- Seed your development database with `npx prisma db seed`
-- Create a sql dump of your database with `sqlite3 prisma/data.db .dump > seed.sql`
-- Replace the SQL below with your new Roles & Permissions related SQL from `seed.sql`

-- console.time('🔑 Created permissions...')
-- const entities = ['user', 'note']
-- const actions = ['create', 'read', 'update', 'delete']
-- const accesses = ['own', 'any'] as const

-- let permissionsToCreate = []
-- for (const entity of entities) {
-- for (const action of actions) {
-- for (const access of accesses) {
-- permissionsToCreate.push({ entity, action, access })
-- }
-- }
-- }
-- await prisma.permission.createMany({ data: permissionsToCreate })
-- console.timeEnd('🔑 Created permissions...')

-- console.time('👑 Created roles...')
-- await prisma.role.create({
-- data: {
-- name: 'admin',
-- permissions: {
-- connect: await prisma.permission.findMany({
-- select: { id: true },
-- where: { access: 'any' },
-- }),
-- },
-- },
-- })
-- await prisma.role.create({
-- data: {
-- name: 'user',
-- permissions: {
-- connect: await prisma.permission.findMany({
-- select: { id: true },
-- where: { access: 'own' },
-- }),
-- },
-- },
-- })
-- console.timeEnd('👑 Created roles...')

INSERT INTO Permission VALUES('clnf2zvli0000pcou3zzzzome','create','user','own','',1696625465526,1696625465526);
INSERT INTO Permission VALUES('clnf2zvll0001pcouly1310ku','create','user','any','',1696625465529,1696625465529);
INSERT INTO Permission VALUES('clnf2zvll0002pcouka7348re','read','user','own','',1696625465530,1696625465530);
Expand Down Expand Up @@ -208,4 +255,4 @@ INSERT INTO _PermissionToRole VALUES('clnf2zvlo0006pcouyoptc5jp','clnf2zvlx000hp
INSERT INTO _PermissionToRole VALUES('clnf2zvlp0008pcou9r0fhbm8','clnf2zvlx000hpcou5dfrbegs');
INSERT INTO _PermissionToRole VALUES('clnf2zvlq000apcouxnspejs9','clnf2zvlx000hpcou5dfrbegs');
INSERT INTO _PermissionToRole VALUES('clnf2zvlr000cpcouy1vp6oeg','clnf2zvlx000hpcou5dfrbegs');
INSERT INTO _PermissionToRole VALUES('clnf2zvls000epcou4ts5ui8f','clnf2zvlx000hpcou5dfrbegs');
INSERT INTO _PermissionToRole VALUES('clnf2zvls000epcou4ts5ui8f','clnf2zvlx000hpcou5dfrbegs');
45 changes: 2 additions & 43 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { promiseHash } from 'remix-utils/promise'
import { prisma } from '#app/utils/db.server.ts'
import { MOCK_CODE_GITHUB } from '#app/utils/providers/constants'
import {
cleanupDb,
createPassword,
createUser,
getNoteImages,
getUserImages,
img,
resetDb,
} from '#tests/db-utils.ts'
import { insertGitHubUser } from '#tests/mocks/github.ts'

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

console.time('🧹 Cleaned up the database...')
await cleanupDb(prisma)
await resetDb()
console.timeEnd('🧹 Cleaned up the database...')

console.time('🔑 Created permissions...')
const entities = ['user', 'note']
const actions = ['create', 'read', 'update', 'delete']
const accesses = ['own', 'any'] as const

let permissionsToCreate = []
for (const entity of entities) {
for (const action of actions) {
for (const access of accesses) {
permissionsToCreate.push({ entity, action, access })
}
}
}
await prisma.permission.createMany({ data: permissionsToCreate })
console.timeEnd('🔑 Created permissions...')

console.time('👑 Created roles...')
await prisma.role.create({
data: {
name: 'admin',
permissions: {
connect: await prisma.permission.findMany({
select: { id: true },
where: { access: 'any' },
}),
},
},
})
await prisma.role.create({
data: {
name: 'user',
permissions: {
connect: await prisma.permission.findMany({
select: { id: true },
where: { access: 'own' },
}),
},
},
})
console.timeEnd('👑 Created roles...')

const totalUsers = 5
console.time(`👤 Created ${totalUsers} users...`)
const noteImages = await getNoteImages()
Expand Down
31 changes: 13 additions & 18 deletions tests/db-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { faker } from '@faker-js/faker'
import { type PrismaClient } from '@prisma/client'

Check warning on line 3 in tests/db-utils.ts

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

'PrismaClient' is defined but never used. Allowed unused vars must match /^ignored/u
import bcrypt from 'bcryptjs'
import { UniqueEnforcer } from 'enforce-unique'
import { execaCommand } from 'execa'

const uniqueUsernameEnforcer = new UniqueEnforcer()

Expand Down Expand Up @@ -115,23 +116,17 @@ export async function img({
}
}

export async function cleanupDb(prisma: PrismaClient) {
const tables = await prisma.$queryRaw<
{ name: string }[]
>`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_migrations';`
export async function resetDb(dbPath?: string) {
const databaseUrl = dbPath ? { DATABASE_URL: `file:${dbPath}` } : {}

try {
// Disable FK constraints to avoid relation conflicts during deletion
await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = OFF`)
await prisma.$transaction([
// Delete all rows from each table, preserving table structures
...tables.map(({ name }) =>
prisma.$executeRawUnsafe(`DELETE from "${name}"`),
),
])
} catch (error) {
console.error('Error cleaning up database:', error)
} finally {
await prisma.$executeRawUnsafe(`PRAGMA foreign_keys = ON`)
}
await execaCommand(
'npx prisma migrate reset --force --skip-seed --skip-generate',
{
stdio: 'inherit',
env: {
...process.env,
...databaseUrl,
},
},
)
}
8 changes: 2 additions & 6 deletions tests/setup/db-setup.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import path from 'node:path'
import fsExtra from 'fs-extra'
import { afterAll, afterEach, beforeAll } from 'vitest'
import { cleanupDb } from '#tests/db-utils.ts'
import { BASE_DATABASE_PATH } from './global-setup.ts'
import { BASE_DATABASE_PATH, setup } from './global-setup.ts'

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

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

afterAll(async () => {
Expand Down
13 changes: 2 additions & 11 deletions tests/setup/global-setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'node:path'
import { execaCommand } from 'execa'
import fsExtra from 'fs-extra'
import { resetDb } from '#tests/db-utils.js'

export const BASE_DATABASE_PATH = path.join(
process.cwd(),
Expand All @@ -22,14 +22,5 @@ export async function setup() {
}
}

await execaCommand(
'npx prisma migrate reset --force --skip-seed --skip-generate',
{
stdio: 'inherit',
env: {
...process.env,
DATABASE_URL: `file:${BASE_DATABASE_PATH}`,
},
},
)
await resetDb(BASE_DATABASE_PATH)
}

0 comments on commit 98702a6

Please sign in to comment.