Skip to content

Commit 2140e3d

Browse files
committed
test: add tests for modelName on error.meta when unique constraint is violated
1 parent 2c3bb56 commit 2140e3d

File tree

3 files changed

+213
-0
lines changed

3 files changed

+213
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { defineMatrix } from '../../_utils/defineMatrix'
2+
import { Providers } from '../../_utils/providers'
3+
4+
export default defineMatrix(() => [
5+
[
6+
{
7+
provider: Providers.SQLITE,
8+
testEmail: '[email protected]',
9+
},
10+
{
11+
provider: Providers.MYSQL,
12+
testEmail: '[email protected]',
13+
},
14+
{
15+
provider: Providers.SQLSERVER,
16+
testEmail: '[email protected]',
17+
},
18+
{
19+
provider: Providers.POSTGRESQL,
20+
testEmail: '[email protected]',
21+
},
22+
{
23+
provider: Providers.COCKROACHDB,
24+
testEmail: '[email protected]',
25+
},
26+
],
27+
])
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { idForProvider } from '../../../_utils/idForProvider'
2+
import testMatrix from '../_matrix'
3+
4+
export default testMatrix.setupSchema(({ provider }) => {
5+
return /* Prisma */ `
6+
generator client {
7+
provider = "prisma-client-js"
8+
}
9+
10+
datasource db {
11+
provider = "${provider}"
12+
url = env("DATABASE_URI_${provider}")
13+
}
14+
15+
model User {
16+
id ${idForProvider(provider)}
17+
email String @unique
18+
}
19+
`
20+
})
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import { Providers } from '../../_utils/providers'
2+
import testMatrix from './_matrix'
3+
// @ts-ignore
4+
import type { PrismaClient } from './node_modules/@prisma/client'
5+
6+
declare let prisma: PrismaClient
7+
8+
testMatrix.setupTestSuite(
9+
(suiteConfig) => {
10+
describe('unique constraint violation', () => {
11+
const user1_cuid = 'tz4a98xxat96iws9zmbrgj3a'
12+
const user2_cuid = 'tz4a98xxat96iws9zmbrgj3b'
13+
14+
// Create a user with the same email as the test email
15+
// This is to ensure that the test email is already in the database
16+
beforeAll(async () => {
17+
await prisma.user.create({
18+
data: {
19+
id: user1_cuid,
20+
email: suiteConfig.testEmail,
21+
},
22+
})
23+
})
24+
25+
describe('modelName is returned on error.meta', () => {
26+
it('should return modelName on error.meta when performing prisma.model.create', async () => {
27+
const createDuplicateUserWithEmail = async () => {
28+
await prisma.user.create({
29+
data: {
30+
email: suiteConfig.testEmail,
31+
},
32+
})
33+
}
34+
35+
try {
36+
await createDuplicateUserWithEmail()
37+
// If the above function doesn't throw an error, fail the test
38+
expect(true).toBe(false)
39+
} catch (e) {
40+
expect(e.name).toBeDefined()
41+
expect(e.code).toBeDefined()
42+
expect(e.meta).toBeDefined()
43+
expect(e.meta.modelName).toBeDefined()
44+
expect(e.name).toBe('PrismaClientKnownRequestError')
45+
expect(e.code).toBe('P2002')
46+
expect(e.meta.modelName).toBe('User')
47+
}
48+
})
49+
50+
it('should return modelName on error.meta when performing prisma$transaction with the client', async () => {
51+
const createDuplicateUserWithEmail = async () => {
52+
await prisma.$transaction([
53+
prisma.user.create({
54+
data: {
55+
email: suiteConfig.testEmail,
56+
},
57+
}),
58+
prisma.user.create({
59+
data: {
60+
email: suiteConfig.testEmail,
61+
},
62+
}),
63+
])
64+
}
65+
66+
try {
67+
await createDuplicateUserWithEmail()
68+
// If the above function doesn't throw an error, fail the test
69+
expect(true).toBe(false)
70+
} catch (e) {
71+
expect(e.name).toBeDefined()
72+
expect(e.code).toBeDefined()
73+
expect(e.meta).toBeDefined()
74+
expect(e.meta.modelName).toBeDefined()
75+
expect(e.name).toBe('PrismaClientKnownRequestError')
76+
expect(e.code).toBe('P2002')
77+
expect(e.meta.modelName).toBe('User')
78+
}
79+
})
80+
})
81+
82+
describe('modelName is not returned on error.meta', () => {
83+
it('should not return modelName when performing queryRaw', async () => {
84+
const createTwoUserWithSameEmail = async () => {
85+
if (suiteConfig.provider === Providers.MYSQL) {
86+
await prisma.$queryRaw`INSERT INTO \`User\` (\`id\`, \`email\`) VALUES (${user2_cuid}, ${suiteConfig.testEmail});`
87+
} else {
88+
await prisma.$queryRaw`INSERT INTO "User" (id, email) VALUES (${user2_cuid}, ${suiteConfig.testEmail});`
89+
}
90+
}
91+
92+
try {
93+
await createTwoUserWithSameEmail()
94+
// If the above function doesn't throw an error, fail the test
95+
expect(true).toBe(false)
96+
} catch (e) {
97+
expect(e.name).toBeDefined()
98+
expect(e.code).toBeDefined()
99+
expect(e.meta).toBeDefined()
100+
expect(e.name).toBe('PrismaClientKnownRequestError')
101+
expect(e.code).toBe('P2010')
102+
expect(Object.keys(e.meta).includes('modelName')).toBe(false)
103+
}
104+
})
105+
106+
it('should not return modelName when performing executeRaw', async () => {
107+
const createTwoUserWithSameEmail = async () => {
108+
if (suiteConfig.provider === Providers.MYSQL) {
109+
await prisma.$executeRaw`INSERT INTO \`User\` (\`id\`, \`email\`) VALUES (${user2_cuid}, ${suiteConfig.testEmail});`
110+
} else {
111+
await prisma.$executeRaw`INSERT INTO "User" (id, email) VALUES (${user2_cuid}, ${suiteConfig.testEmail});`
112+
}
113+
}
114+
115+
try {
116+
await createTwoUserWithSameEmail()
117+
// If the above function doesn't throw an error, fail the test
118+
expect(true).toBe(false)
119+
} catch (e) {
120+
expect(e.name).toBeDefined()
121+
expect(e.code).toBeDefined()
122+
expect(e.meta).toBeDefined()
123+
expect(e.name).toBe('PrismaClientKnownRequestError')
124+
expect(e.code).toBe('P2010')
125+
expect(Object.keys(e.meta).includes('modelName')).toBe(false)
126+
}
127+
})
128+
129+
it('should not return modelName when performing transactions with raw queries', async () => {
130+
const createTwoUserWithSameEmail = async () => {
131+
if (suiteConfig.provider === Providers.MYSQL) {
132+
await prisma.$transaction([
133+
prisma.$executeRaw`INSERT INTO \`User\` (\`id\`, \`email\`) VALUES (${user2_cuid}, ${suiteConfig.testEmail});`,
134+
prisma.$executeRaw`INSERT INTO \`User\` (\`id\`, \`email\`) VALUES (${user2_cuid}, ${suiteConfig.testEmail});`,
135+
])
136+
} else {
137+
await prisma.$transaction([
138+
prisma.$executeRaw`INSERT INTO "User" (id, email) VALUES (${user2_cuid}, ${suiteConfig.testEmail});`,
139+
prisma.$executeRaw`INSERT INTO "User" (id, email) VALUES (${user2_cuid}, ${suiteConfig.testEmail});`,
140+
])
141+
}
142+
}
143+
144+
try {
145+
await createTwoUserWithSameEmail()
146+
// If the above function doesn't throw an error, fail the test
147+
expect(true).toBe(false)
148+
} catch (e) {
149+
expect(e.name).toBeDefined()
150+
expect(e.code).toBeDefined()
151+
expect(e.meta).toBeDefined()
152+
expect(e.name).toBe('PrismaClientKnownRequestError')
153+
expect(e.code).toBe('P2010')
154+
expect(Object.keys(e.meta).includes('modelName')).toBe(false)
155+
}
156+
})
157+
})
158+
})
159+
},
160+
{
161+
optOut: {
162+
from: ['mongodb'],
163+
reason: "MongoDB doesn't support raw queries",
164+
},
165+
},
166+
)

0 commit comments

Comments
 (0)