test.ts•19.3 kB
import { expectTypeOf } from 'expect-type'
import { Providers } from '../_utils/providers'
import { NewPrismaClient } from '../_utils/types'
import testMatrix from './_matrix'
// @ts-ignore
import type { Prisma, PrismaClient } from './generated/prisma/client'
declare const newPrismaClient: NewPrismaClient<PrismaClient, typeof PrismaClient>
declare const prisma: PrismaClient
// TODO: Remove this test once we drop the prisma-client-js generator.
// This test was duplicated from `globOmit` to run only against the prisma-client-js generator.
// The `clientWithOmit` helper was too complicated to make it work with both generators at the same time.
// wrapper around newPrismaClient to correctly infer generic arguments.
// `newPrismaClient` by itself is not smart enough for that and I don't think
// we can make it smarter in a generic way, without having `PrismaClient` on hands.
function clientWithOmit<O extends Prisma.PrismaClientOptions>(options: O): PrismaClient<O> {
return newPrismaClient(options) as unknown as PrismaClient<O>
}
testMatrix.setupTestSuite(({ provider }) => {
beforeEach(async () => {
await prisma.userGroup.deleteMany()
await prisma.user.deleteMany()
await prisma.userGroup.create({
data: {
name: 'Admins',
users: {
create: {
email: 'user@example.com',
password: 'hunter2',
},
},
},
})
})
test('throws if omit is not an object', () => {
expect(() =>
clientWithOmit({
// @ts-expect-error
omit: 'yes',
}),
).toThrowErrorMatchingInlineSnapshot(`
""omit" option is expected to be an object.
Read more at https://pris.ly/d/client-constructor"
`)
})
test('throws if omit is null', () => {
expect(() =>
clientWithOmit({
// @ts-expect-error
omit: null,
}),
).toThrowErrorMatchingInlineSnapshot(`
""omit" option can not be \`null\`
Read more at https://pris.ly/d/client-constructor"
`)
})
test('throws if unknown model is mentioned in omit', () => {
expect(() =>
clientWithOmit({
omit: {
// @ts-expect-error
notAUser: {
field: true,
},
},
}),
).toThrowErrorMatchingInlineSnapshot(`
"Error validating "omit" option:
{
notAUser: {
~~~~~~~~
field: true
}
}
Unknown model name: notAUser.
Read more at https://pris.ly/d/client-constructor"
`)
})
test('throws if unknown field is mentioned in omit', () => {
expect(() =>
clientWithOmit({
omit: {
user: {
// @ts-expect-error
notAField: true,
},
},
}),
).toThrowErrorMatchingInlineSnapshot(`
"Error validating "omit" option:
{
user: {
notAField: true
~~~~~~~~~
}
}
Model "user" does not have a field named "notAField".
Read more at https://pris.ly/d/client-constructor"
`)
})
test('throws if non boolean field is used in omit', () => {
expect(() =>
clientWithOmit({
omit: {
user: {
// @ts-expect-error
password: 'yes, please',
},
},
}),
).toThrowErrorMatchingInlineSnapshot(`
"Error validating "omit" option:
{
user: {
password: "yes, please"
~~~~~~~~~~~~~
}
}
Omit field option value must be a boolean.
Read more at https://pris.ly/d/client-constructor"
`)
})
test('throws if relation field is used in omit', () => {
expect(() =>
clientWithOmit({
omit: {
user: {
// @ts-expect-error
group: true,
},
},
}),
).toThrowErrorMatchingInlineSnapshot(`
"Error validating "omit" option:
{
user: {
group: true
~~~~~
}
}
Relations are already excluded by default and can not be specified in "omit".
Read more at https://pris.ly/d/client-constructor"
`)
})
test('omitting every field', async () => {
const client = clientWithOmit({
omit: {
user: {
id: true,
email: true,
highScore: true,
groupId: true,
password: true,
},
},
})
await expect(() => client.user.findFirstOrThrow()).rejects.toMatchPrismaErrorInlineSnapshot(`
"
Invalid \`client.user.findFirstOrThrow()\` invocation in
/client/tests/functional/globalOmitJSGenerator/test.ts:0:0
XX },
XX },
XX })
→ XX await expect(() => client.user.findFirstOrThrow({
+ omit: {
+ id: false,
+ email: false,
+ password: false,
+ highScore: false,
+ groupId: false
+ }
})
The global omit configuration excludes every field of the model User. At least one field must be included in the result"
`)
})
test('findFirstOrThrow', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.findFirstOrThrow()
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).toHaveProperty('highScore')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).toHaveProperty('highScore')
expectTypeOf(user).not.toHaveProperty('password')
})
test('findUniqueOrThrow', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.findUniqueOrThrow({ where: { email: 'user@example.com' } })
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).toHaveProperty('highScore')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).toHaveProperty('highScore')
expectTypeOf(user).not.toHaveProperty('password')
})
test('findFirst', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.findFirst()
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).toHaveProperty('highScore')
expect(user).not.toHaveProperty('password')
expectTypeOf(user!).toHaveProperty('id')
expectTypeOf(user!).toHaveProperty('email')
expectTypeOf(user!).toHaveProperty('highScore')
expectTypeOf(user!).not.toHaveProperty('password')
})
test('findUnique', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.findUnique({ where: { email: 'user@example.com' } })
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).toHaveProperty('highScore')
expect(user).not.toHaveProperty('password')
expectTypeOf(user!).toHaveProperty('id')
expectTypeOf(user!).toHaveProperty('email')
expectTypeOf(user!).toHaveProperty('highScore')
expectTypeOf(user!).not.toHaveProperty('password')
})
test('findMany', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const users = await client.user.findMany()
expect(users[0]).toHaveProperty('id')
expect(users[0]).toHaveProperty('email')
expect(users[0]).toHaveProperty('highScore')
expect(users[0]).not.toHaveProperty('password')
expectTypeOf(users[0]).toHaveProperty('id')
expectTypeOf(users[0]).toHaveProperty('email')
expectTypeOf(users[0]).toHaveProperty('highScore')
expectTypeOf(users[0]).not.toHaveProperty('password')
})
test('create', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.create({
data: {
email: 'createUser@example.com',
password: 'hunter2',
},
})
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).toHaveProperty('highScore')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).toHaveProperty('highScore')
expectTypeOf(user).not.toHaveProperty('password')
})
test('delete', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.delete({ where: { email: 'user@example.com' } })
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).toHaveProperty('highScore')
expect(user).not.toHaveProperty('password')
expectTypeOf(user!).toHaveProperty('id')
expectTypeOf(user!).toHaveProperty('email')
expectTypeOf(user!).toHaveProperty('highScore')
expectTypeOf(user!).not.toHaveProperty('password')
})
test('createMany does not crash', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const result = await client.user.createMany({
data: [
{
email: 'user1@example.com',
password: 'hunter2',
},
{
email: 'user2@example.com',
password: 'hunter2',
},
],
})
expect(result.count).toBe(2)
})
test('deleteMany does not crash', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const result = await client.user.deleteMany({})
expect(result.count).toBe(1)
})
test('updateMany does not crash', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const result = await client.user.updateMany({
where: { email: 'user@example.com' },
data: {
password: '*******',
},
})
expect(result.count).toBe(1)
})
test('groupBy does not crash', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const result = await client.user.groupBy({
by: ['id'],
})
expect(result.length).toBe(1)
})
test('count does not crash', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const result = await client.user.count()
expect(result).toBe(1)
})
test('aggregate does not crash', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const result = await client.user.aggregate({
_sum: {
highScore: true,
},
})
expect(result._sum.highScore).toBe(0)
})
skipTestIf([Providers.SQLSERVER, Providers.MONGODB, Providers.MYSQL].includes(provider))(
'createManyAndReturn',
async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
// @ts-test-if: provider !== Providers.SQLSERVER && provider !== Providers.MONGODB && provider !== Providers.MYSQL
const users = await client.user.createManyAndReturn({
data: [
{
email: 'createmanyuser1@example.com',
password: 'hunter2',
},
],
})
expect(users[0]).toHaveProperty('id')
expect(users[0]).toHaveProperty('email')
expect(users[0]).toHaveProperty('highScore')
expect(users[0]).not.toHaveProperty('password')
expectTypeOf(users[0]).toHaveProperty('id')
expectTypeOf(users[0]).toHaveProperty('email')
expectTypeOf(users[0]).toHaveProperty('highScore')
// @ts-test-if: provider !== Providers.SQLSERVER && provider !== Providers.MONGODB && provider !== Providers.MYSQL
expectTypeOf(users[0]).not.toHaveProperty('password')
},
)
test('update', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.update({
where: {
email: 'user@example.com',
},
data: {
password: '*******',
},
})
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).toHaveProperty('highScore')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).toHaveProperty('highScore')
expectTypeOf(user).not.toHaveProperty('password')
})
test('upsert', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.upsert({
where: {
email: 'userUpsert@example.com',
},
create: {
email: 'userUpsert@example.com',
password: '*******',
},
update: {
password: '*******',
},
})
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).toHaveProperty('highScore')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).toHaveProperty('highScore')
expectTypeOf(user).not.toHaveProperty('password')
})
test('excluding more than one field at a time', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
highScore: true,
},
},
})
const user = await client.user.findFirstOrThrow()
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).not.toHaveProperty('highScore')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).not.toHaveProperty('highScore')
expectTypeOf(user).not.toHaveProperty('password')
})
test('allows to include globally omitted field with omit: false', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.findFirstOrThrow({
omit: { password: false },
})
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).toHaveProperty('password')
})
test('allows to include globally omitted field with select: true', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const user = await client.user.findFirstOrThrow({
select: { id: true, password: true },
})
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('password')
})
test('works for nested relations (include)', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const group = await client.userGroup.findFirstOrThrow({
include: {
users: true,
},
})
const user = group.users[0]
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).not.toHaveProperty('password')
})
test('works for nested relations (select)', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const group = await client.userGroup.findFirstOrThrow({
select: {
users: true,
},
})
const user = group.users[0]
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).not.toHaveProperty('password')
})
test('works for fluent api', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
})
const users = await client.userGroup.findFirst().users()
expect(users![0]).toHaveProperty('id')
expect(users![0]).toHaveProperty('email')
expect(users![0]).not.toHaveProperty('password')
expectTypeOf(users![0]).toHaveProperty('id')
expectTypeOf(users![0]).toHaveProperty('email')
expectTypeOf(users![0]).not.toHaveProperty('password')
})
test('works after extending the client', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
}).$extends({})
const user = await client.user.findFirstOrThrow()
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).toHaveProperty('id')
expectTypeOf(user).toHaveProperty('email')
expectTypeOf(user).not.toHaveProperty('password')
})
test('works with fluent api after extending the client', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
}).$extends({})
const users = await client.userGroup.findFirst().users()
expect(users![0]).toHaveProperty('id')
expect(users![0]).toHaveProperty('email')
expect(users![0]).not.toHaveProperty('password')
expectTypeOf(users![0]).toHaveProperty('id')
expectTypeOf(users![0]).toHaveProperty('email')
expectTypeOf(users![0]).not.toHaveProperty('password')
})
test('works with result extension, depending on explicitly omitted field', async () => {
const client = clientWithOmit({
omit: {
user: {
password: true,
},
},
}).$extends({
result: {
user: {
bigPassword: {
needs: { password: true },
compute(data) {
return data.password.toUpperCase()
},
},
},
},
})
const user = await client.user.findUniqueOrThrow({
where: {
email: 'user@example.com',
},
})
expect(user.bigPassword).toBe('HUNTER2')
expect(user).not.toHaveProperty('password')
expectTypeOf(user).not.toHaveProperty('password')
})
})