Skip to content

Commit e3a040a

Browse files
update testing-express example
1 parent 167245a commit e3a040a

File tree

10 files changed

+86
-30
lines changed

10 files changed

+86
-30
lines changed

orm/testing-express/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE"

orm/testing-express/jest.config.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
const path = require('path')
2-
const { defaults } = require('jest-config')
1+
import { fileURLToPath } from 'node:url'
2+
import { dirname, join } from 'node:path'
3+
4+
const __filename = fileURLToPath(import.meta.url)
5+
const __dirname = dirname(__filename)
36

47
/** @type {import('@jest/types').Config.InitialOptions} */
58
const config = {
6-
preset: 'ts-jest',
7-
moduleFileExtensions: [...defaults.moduleFileExtensions, 'mjs'],
8-
testEnvironment: path.join(__dirname, 'prisma', 'prisma-test-environment.mjs'),
9+
preset: 'ts-jest/presets/default-esm',
10+
moduleFileExtensions: ['js', 'json', 'ts', 'mjs'],
11+
testEnvironment: join(__dirname, 'prisma', 'prisma-test-environment.mjs'),
912
setupFilesAfterEnv: ['<rootDir>/setupTests.ts'],
13+
extensionsToTreatAsEsm: ['.ts'],
14+
moduleNameMapper: {
15+
'^(\\.{1,2}/.*)\\.js$': '$1',
16+
},
1017
}
1118

12-
module.exports = config
19+
export default config

orm/testing-express/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
"name": "testing-express",
33
"version": "1.0.0",
44
"license": "MIT",
5+
"type": "module",
56
"scripts": {
67
"dev": "tsx src/index.ts",
7-
"test": "jest --detectOpenHandles"
8+
"test": "NODE_OPTIONS=--experimental-vm-modules jest --detectOpenHandles"
89
},
910
"prettier": {
1011
"semi": false,
@@ -14,7 +15,7 @@
1415
"@prisma/client": "^6.17.1",
1516
"@prisma/extension-accelerate": "^2.0.2",
1617
"@types/node": "22.15.32",
17-
"dotenv": "^16.4.7",
18+
"dotenv": "^16.6.1",
1819
"express": "5.1.0",
1920
"jest-config": "29.7.0"
2021
},

orm/testing-express/prisma/prisma-test-environment.mjs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import fs from 'fs'
44
import { nanoid } from 'nanoid'
55
import { TestEnvironment } from 'jest-environment-node'
66
import { exec } from 'child_process'
7+
import { promisify } from 'util'
78
import { fileURLToPath } from 'url'
9+
import "dotenv/config"
10+
11+
const execAsync = promisify(exec)
812

913
// fix for 'How to fix "__dirname is not defined in ES module scope"'
1014
const __filename = fileURLToPath(import.meta.url);
@@ -24,20 +28,22 @@ class PrismaTestEnvironment extends TestEnvironment {
2428
constructor(config, _context) {
2529
super(config, _context)
2630

27-
// Generate a unique sqlite identifier for this test context
31+
// Generate a unique database file for this test context
2832
this.dbName = `test_${nanoid()}.db`
29-
process.env.DB_URL = `file:${this.dbName}`
30-
this.global.process.env.DB_URL = `file:${this.dbName}`
33+
const dbUrl = `file:${this.dbName}`
34+
process.env.DATABASE_URL = dbUrl
35+
this.global.process.env.DATABASE_URL = dbUrl
3136
this.dbPath = path.join(__dirname, this.dbName)
3237
}
3338

3439
async setup() {
3540
// Run the migrations to ensure our schema has the required structure
36-
await exec(`${prismaBinary} db push `)
41+
await execAsync(`${prismaBinary} db push --skip-generate`)
3742
return super.setup()
3843
}
3944

4045
async teardown() {
46+
// Clean up the test database file
4147
try {
4248
await fs.promises.unlink(this.dbPath)
4349
} catch (error) {
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
generator client {
2-
provider = "prisma-client"
3-
output = "./generated"
4-
engineType = "client"
2+
provider = "prisma-client-js"
3+
output = "./generated"
54
}
65

76
datasource db {
8-
provider = "postgresql"
7+
provider = "sqlite"
98
url = env("DATABASE_URL")
109
}
1110

1211
model User {
13-
id Int @default(autoincrement()) @id
12+
id Int @id @default(autoincrement())
1413
name String?
1514
email String @unique
1615
}

orm/testing-express/setupTests.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
import { jest } from '@jest/globals'
2+
13
jest.setTimeout(10000)

orm/testing-express/src/app.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import 'dotenv/config'
2-
import { PrismaClient } from '../prisma/generated/client'
3-
import { withAccelerate } from '@prisma/extension-accelerate'
2+
import { PrismaClient } from '../prisma/generated/client.js'
43
import express from 'express'
54

6-
export const prisma = new PrismaClient().$extends(withAccelerate())
5+
export const prisma = new PrismaClient()
76
export const app = express()
87

98
app.use(express.json())

orm/testing-express/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { app } from './app'
1+
import { app } from './app.js'
22

33
app.listen(3000, () =>
44
console.log(`

orm/testing-express/tests/user.test.ts

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
import { test, expect, afterAll, beforeEach } from '@jest/globals'
12
import request from 'supertest'
2-
import { app, prisma } from '../src/app'
3+
import { app, prisma } from '../src/app.js'
4+
5+
beforeEach(async () => {
6+
// Clean up the database before each test
7+
await prisma.user.deleteMany()
8+
})
39

410
afterAll(async () => {
511
await prisma.$disconnect()
@@ -19,23 +25,53 @@ test('a user is added successfully', async () => {
1925
.expect(200)
2026

2127
expect(response.body.id).toBeDefined()
28+
expect(response.body.name).toBe(user.name)
29+
expect(response.body.email).toBe(user.email)
2230
}, 60000)
2331

24-
test('a user with the same email is rejected', () => {
25-
return request(app)
32+
test('a user with the same email is rejected', async () => {
33+
// First, create a user
34+
await request(app)
2635
.post('/user')
2736
.send(user)
2837
.set('Accept', 'application/json')
29-
.expect('Content-Type', /json/)
30-
.expect(409)
38+
.expect(200)
39+
40+
// Then try to create another user with the same email
41+
const duplicateResponse = await request(app)
42+
.post('/user')
43+
.send(user)
44+
.set('Accept', 'application/json')
45+
46+
expect(duplicateResponse.status).toBe(409)
47+
expect(duplicateResponse.body.error).toBe('User already exists!')
3148
}, 60000)
3249

3350
test('correct list of users returned', async () => {
51+
// Create multiple users
52+
const users = [
53+
{ name: 'user 1', email: '[email protected]' },
54+
{ name: 'user 2', email: '[email protected]' },
55+
{ name: 'user 3', email: '[email protected]' }
56+
]
57+
58+
for (const userData of users) {
59+
await request(app)
60+
.post('/user')
61+
.send(userData)
62+
.set('Accept', 'application/json')
63+
.expect(200)
64+
}
65+
66+
// Get all users
3467
const response = await request(app)
3568
.get('/user')
3669
.expect('Content-Type', /json/)
3770
.expect(200)
3871

3972
expect(response.body).toBeDefined()
40-
expect(response.body.length).toBeGreaterThan(1)
73+
expect(response.body.length).toBe(3)
74+
expect(response.body[0].email).toBeDefined()
75+
expect(response.body[1].email).toBeDefined()
76+
expect(response.body[2].email).toBeDefined()
4177
}, 60000)

orm/testing-express/tsconfig.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
"sourceMap": true,
44
"outDir": "dist",
55
"strict": true,
6-
"lib": ["esnext"],
7-
"esModuleInterop": true
6+
"lib": [
7+
"esnext"
8+
],
9+
"esModuleInterop": true,
10+
"module": "ESNext",
11+
"moduleResolution": "node",
12+
"target": "ES2020"
813
}
9-
}
14+
}

0 commit comments

Comments
 (0)