Skip to content

Commit

Permalink
chore: 🎨 small improvments run tests in band
Browse files Browse the repository at this point in the history
  • Loading branch information
dennemark committed Nov 8, 2024
1 parent 32c0730 commit 38c3532
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 25 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"scripts": {
"build": "prisma generate && tsup src/index.ts --format=cjs,esm --dts",
"watch": "prisma generate && tsup src/index.ts --format=cjs,esm --dts --watch",
"test": "jest --watch",
"test": "jest --watch --runInBand",
"release": "release-it"
},
"keywords": [
Expand Down
2 changes: 1 addition & 1 deletion src/applyCaslToQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function applyCaslToQuery(operation: PrismaCaslOperation, args: any, abil
if (operationAbility.whereQuery && !args.where) {
args.where = {}
}
const { args: dataArgs, creationTree: dataCreationTree } = applyDataQuery(abilities, args, operationAbility.action, model)
const { args: dataArgs, creationTree: dataCreationTree } = applyDataQuery(abilities, args, operation, operationAbility.action, model)
creationTree = dataCreationTree
args = dataArgs
if (operation === 'updateMany') {
Expand Down
8 changes: 5 additions & 3 deletions src/applyDataQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Prisma } from '@prisma/client'
import { applyAccessibleQuery } from './applyAccessibleQuery'
import { applyWhereQuery } from './applyWhereQuery'
import { CreationTree } from './convertCreationTreeToSelect'
import { caslNestedOperationDict, getPermittedFields, propertyFieldsByModel, relationFieldsByModel } from './helpers'
import { caslNestedOperationDict, getPermittedFields, PrismaCaslOperation, propertyFieldsByModel, relationFieldsByModel } from './helpers'
import './polyfills'

/**
Expand All @@ -26,6 +26,7 @@ import './polyfills'
export function applyDataQuery(
abilities: PureAbility<AbilityTuple, PrismaQuery>,
args: any,
operation: PrismaCaslOperation,
action: string,
model: string,
creationTree?: CreationTree
Expand Down Expand Up @@ -91,11 +92,12 @@ export function applyDataQuery(
mutationArgs.map((mutation: any) => {

// get all mutation arg fields and if they are short code connect (userId instead of user: { connect: id }), we convert it
// except if it is a createMany or updateMany operation
const queriedFields = (mutation ? Object.keys(mutation) : []).map((field) => {
const relationModelId = propertyFieldsByModel[model][field]
if (relationModelId && mutation[field] !== null) {
const fieldId = relationFieldsByModel[model][relationModelId].relationToFields?.[0]
if (fieldId) {
if (fieldId && operation !== 'createMany' && operation !== 'createManyAndReturn') {
mutation[relationModelId] = { connect: { [fieldId]: mutation[field] } }
delete mutation[field]
}
Expand All @@ -120,7 +122,7 @@ export function applyDataQuery(

tree.children[field] = { action: mutationAction, model: relationModel.type as Prisma.ModelName, children: {}, mutation: [] }
if (nestedAction !== 'disconnect' && nestedArgs !== true) {
const dataQuery = applyDataQuery(abilities, nestedArgs, mutationAction, relationModel.type, tree.children[field])
const dataQuery = applyDataQuery(abilities, nestedArgs, operation, mutationAction, relationModel.type, tree.children[field])
mutation[field][nestedAction] = dataQuery.args
// connection works like a where query, so we apply it
if (isConnection) {
Expand Down
81 changes: 61 additions & 20 deletions test/applyDataQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ describe('apply data query', () => {
const { can, build } = abilityBuilder()
can('update', 'Post')
can('update', 'User')
const result = applyDataQuery(build(), { data: { authorId: 0 }, where: { id: 0 } }, 'update', 'Post')
const result = applyDataQuery(build(), { data: { authorId: 0 }, where: { id: 0 } }, 'update', 'update', 'Post')
expect(result.args).toEqual({ data: { author: { connect: { id: 0, } } }, where: { id: 0, } })
expect(result.creationTree).toEqual({ children: { author: { mutation: [], children: {}, model: 'User', action: "update" } }, model: 'Post', action: "update", mutation: [{ fields: ['authorId'], where: { id: 0 } }], })
})
it('throws error if update on connection is not allowed', () => {
const { can, cannot, build } = abilityBuilder()
can('update', 'Post')
cannot('update', 'User')
expect(() => applyDataQuery(build(), { data: { authorId: 0 }, where: { id: 0 } }, 'update', 'Post')).toThrow(`It's not allowed to "update" "id" on "User"`)
expect(() => applyDataQuery(build(), { data: { authorId: 0 }, where: { id: 0 } }, 'update', 'update', 'Post')).toThrow(`It's not allowed to "update" "id" on "User"`)
})
;['update', 'create'].map((mutation) => {
; (['update', 'create'] as const).map((mutation) => {
describe(mutation, () => {

it('adds where clause to query', () => {
const { can, build } = abilityBuilder()
can(mutation, 'User', {
id: 0
})
const result = applyDataQuery(build(), { data: { id: 0 }, where: { id: 1 } }, mutation, 'User')
const result = applyDataQuery(build(), { data: { id: 0 }, where: { id: 1 } }, mutation, mutation, 'User')
expect(result.args).toEqual({
data: { id: 0 },
where: { id: 1, AND: [{ OR: [{ id: 0 }] }] }
Expand All @@ -43,7 +43,7 @@ describe('apply data query', () => {
data: { email: '-1' }, where: {
id: 0
}
}, mutation, 'User')).toThrow(`It's not allowed to "${mutation}" "email" on "User"`)
}, mutation, mutation, 'User')).toThrow(`It's not allowed to "${mutation}" "email" on "User"`)
})

it('throws error if mutation of property is not permitted', () => {
Expand All @@ -53,7 +53,7 @@ describe('apply data query', () => {
data: { email: '-1' }, where: {
id: 0
}
}, mutation, 'User')).toThrow(`It's not allowed to run "${mutation}" on "User"`)
}, mutation, mutation, 'User')).toThrow(`It's not allowed to run "${mutation}" on "User"`)
})
})
})
Expand All @@ -63,7 +63,7 @@ describe('apply data query', () => {
can('update', 'Thread')
can('update', 'User', { id: 0 })
can('create', 'User')
const result = applyDataQuery(build(), { data: { creator: { upsert: { create: { email: '-1' }, update: { email: '-1' }, where: { id: 1 } } } }, where: { id: 0 } }, 'update', 'Thread')
const result = applyDataQuery(build(), { data: { creator: { upsert: { create: { email: '-1' }, update: { email: '-1' }, where: { id: 1 } } } }, where: { id: 0 } }, 'update', 'update', 'Thread')
expect(result.args).toEqual({ data: { creator: { upsert: { create: { email: '-1' }, update: { email: '-1' }, where: { id: 1, AND: [{ OR: [{ id: 0 }] }] } } } }, where: { id: 0, } })
expect(result.creationTree).toEqual({
action: 'update',
Expand All @@ -86,7 +86,7 @@ describe('apply data query', () => {
can('create', 'User')
cannot('create', 'User', 'email')

expect(() => applyDataQuery(build(), { data: { creator: { upsert: { create: { email: '-1' }, update: { email: '-1' }, where: { id: 1 } } } }, where: { id: 0 } }, 'update', 'Thread'))
expect(() => applyDataQuery(build(), { data: { creator: { upsert: { create: { email: '-1' }, update: { email: '-1' }, where: { id: 1 } } } }, where: { id: 0 } }, 'update', 'update', 'Thread'))
.toThrow(`It's not allowed to "create" "email" on "User"`)
})
})
Expand All @@ -100,7 +100,7 @@ describe('apply data query', () => {
can('update', 'Post', {
id: 1
})
const result = applyDataQuery(build(), { data: { id: 1, posts: { connect: { id: 0 } } }, where: { id: 0 } }, 'update', 'User')
const result = applyDataQuery(build(), { data: { id: 1, posts: { connect: { id: 0 } } }, where: { id: 0 } }, 'update', 'update', 'User')
expect(result.args).toEqual({ data: { id: 1, posts: { connect: { id: 0, AND: [{ OR: [{ id: 1 }] }] } } }, where: { id: 0, AND: [{ OR: [{ id: 0 }] }] } })
expect(result.creationTree).toEqual({ children: { posts: { children: {}, action: 'update', model: 'Post', mutation: [] } }, model: 'User', action: "update", mutation: [{ fields: ['id'], where: { id: 0 } }], })
})
Expand All @@ -113,7 +113,7 @@ describe('apply data query', () => {
id: 1
})

const result = applyDataQuery(build(), { data: { id: 1, posts: { connect: [{ id: 0 }] } }, where: { id: 0 } }, 'update', 'User')
const result = applyDataQuery(build(), { data: { id: 1, posts: { connect: [{ id: 0 }] } }, where: { id: 0 } }, 'update', 'update', 'User')
expect(result.args).toEqual({ data: { id: 1, posts: { connect: [{ id: 0, AND: [{ OR: [{ id: 1 }] }] }] } }, where: { id: 0, AND: [{ OR: [{ id: 0 }] }] } })
expect(result.creationTree).toEqual({ children: { posts: { children: {}, model: 'Post', action: "update", mutation: [] } }, model: 'User', action: "update", mutation: [{ fields: ['id'], where: { id: 0 } }] })
})
Expand All @@ -122,7 +122,7 @@ describe('apply data query', () => {
can('update', 'User')

cannot('update', 'Post')
expect(() => applyDataQuery(build(), { data: { id: 1, posts: { connect: { id: 0 } } }, where: { id: 0 } }, 'update', 'User'))
expect(() => applyDataQuery(build(), { data: { id: 1, posts: { connect: { id: 0 } } }, where: { id: 0 } }, 'update', 'update', 'User'))
.toThrow(`It's not allowed to "update" "id" on "Post"`)
})

Expand All @@ -136,7 +136,7 @@ describe('apply data query', () => {
can('update', 'Post', {
id: 1
})
const result = applyDataQuery(build(), { data: { id: 1, posts: { disconnect: true } }, where: { id: 0 } }, 'update', 'User')
const result = applyDataQuery(build(), { data: { id: 1, posts: { disconnect: true } }, where: { id: 0 } }, 'update', 'update', 'User')
expect(result.args).toEqual({ data: { id: 1, posts: { disconnect: true } }, where: { id: 0, AND: [{ OR: [{ id: 0 }] }] } })
expect(result.creationTree).toEqual({ children: { posts: { children: {}, action: 'update', model: 'Post', mutation: [] } }, model: 'User', action: "update", mutation: [{ fields: ['id'], where: { id: 0 } }] })
})
Expand Down Expand Up @@ -168,7 +168,7 @@ describe('apply data query', () => {
where: {
id: 0
}
}, 'update', 'User')
}, 'update', 'update', 'User')

expect(result.args).toEqual({ data: { id: 1, posts: { connectOrCreate: { create: { text: '' }, where: { id: 1, AND: [{ OR: [{ id: 2 }] }] } } } }, where: { id: 0, AND: [{ OR: [{ id: 0 }] }] } })
expect(result.creationTree).toEqual({ action: 'update', model: 'User', children: { posts: { model: 'Post', action: 'create', children: {}, mutation: [{ fields: ['text'], where: { id: 1 } }], } }, mutation: [{ fields: ['id'], where: { id: 0 } }], })
Expand Down Expand Up @@ -197,7 +197,7 @@ describe('apply data query', () => {
where: {
id: 0
}
}, 'update', 'User')
}, 'update', 'update', 'User')
expect(result.args).toEqual({ data: { id: 1, posts: { connectOrCreate: [{ create: { text: '' }, where: { id: 0, AND: [{ OR: [{ id: 2 }] }] } }] } }, where: { id: 0, AND: [{ OR: [{ id: 0 }] }] } })
expect(result.creationTree).toEqual({ action: 'update', model: 'User', children: { posts: { model: 'Post', action: 'create', children: {}, mutation: [{ fields: ['text'], where: { id: 0 } }] } }, mutation: [{ fields: ['id'], where: { id: 0 } }] })
})
Expand Down Expand Up @@ -228,7 +228,7 @@ describe('apply data query', () => {
where: {
id: 0
}
}, 'update', 'User'))
}, 'update', 'update', 'User'))
.toThrow(`It's not allowed to "create" "text" on "Post"`)
})
it('throws error if data in nested create property in connection is not allowed', () => {
Expand Down Expand Up @@ -258,7 +258,7 @@ describe('apply data query', () => {
where: {
id: 0
}
}, 'update', 'User'))
}, 'update', 'update', 'User'))
.toThrow(`It's not allowed to "create" "text" on "Post"`)
})
})
Expand All @@ -269,7 +269,7 @@ describe('apply data query', () => {
can('update', 'Post')
can('update', 'Thread')

const result = applyDataQuery(build(), { data: { id: 1, posts: { update: { data: { thread: { update: { id: 0 } } }, where: { id: 0 } } } }, where: { id: 0 } }, 'update', 'User')
const result = applyDataQuery(build(), { data: { id: 1, posts: { update: { data: { thread: { update: { id: 0 } } }, where: { id: 0 } } } }, where: { id: 0 } }, 'update', 'update', 'User')
expect(result.args).toEqual({ data: { id: 1, posts: { update: { data: { thread: { update: { id: 0 } } }, where: { id: 0, } } } }, where: { id: 0, } })
expect(result.creationTree).toEqual({ children: { posts: { children: { thread: { children: {}, model: 'Thread', action: "update", mutation: [] } }, model: 'Post', action: "update", mutation: [{ fields: [], where: { id: 0 } }] } }, model: 'User', action: "update", mutation: [{ fields: ['id'], where: { id: 0 } }] })
})
Expand All @@ -279,10 +279,51 @@ describe('apply data query', () => {
can('update', 'Post')
cannot('update', 'Thread')

expect(() => applyDataQuery(build(), { data: { id: 1, posts: { update: { data: { thread: { update: { id: 0 } } }, where: { id: 0 } } } }, where: { id: 0 } }, 'update', 'User'))
expect(() => applyDataQuery(build(), { data: { id: 1, posts: { update: { data: { thread: { update: { id: 0 } } }, where: { id: 0 } } } }, where: { id: 0 } }, 'update', 'update', 'User'))
.toThrow(`It's not allowed to "update" "id" on "Thread"`)
})
})
describe('nested delete', () => {
it('can update nested nested delete', () => {
const { can, build } = abilityBuilder()
can('update', 'User')
can('delete', 'Post')

const result = applyDataQuery(build(), { data: { id: 1, posts: { delete: { id: 0 } } }, where: { id: 0 } }, 'update', 'update', 'User')
expect(result.args).toEqual({ data: { id: 1, posts: { delete: { id: 0 } } }, where: { id: 0, } })
expect(result.creationTree).toEqual({
action: "update",
children: {
posts: {
action: "delete",
children: {},
model: "Post",
mutation: [],
},
},
model: "User",
mutation: [
{
fields: [
"id",
],
where: {
id: 0,
},
},
],
})
})
// it('throws error if data in nested nested update is not allowed', () => {
// const { can, cannot, build } = abilityBuilder()
// can('update', 'User')
// can('update', 'Post')
// cannot('update', 'Thread')

// expect(() => applyDataQuery(build(), { data: { id: 1, posts: { update: { data: { thread: { update: { id: 0 } } }, where: { id: 0 } } } }, where: { id: 0 } }, 'update', 'User'))
// .toThrow(`It's not allowed to "update" "id" on "Thread"`)
// })
})
describe('createMany', () => {
it('adds where and connection clause in nested connection update', () => {
const { can, build } = abilityBuilder()
Expand All @@ -299,7 +340,7 @@ describe('apply data query', () => {
}
}
}
}, 'create', 'User')
}, 'create', 'create', 'User')
expect(result.args)
.toEqual({ data: { id: 0, posts: { createMany: { data: { text: '' } } } } })
expect(result.creationTree).toEqual({ action: 'create', model: 'User', children: { posts: { model: 'Post', action: 'create', children: {}, mutation: [] } }, mutation: [] })
Expand All @@ -326,7 +367,7 @@ describe('apply data query', () => {
}
}
}
}, 'create', 'User'))
}, 'create', 'create', 'User'))
.toThrow(`It's not allowed to "create" "text" on "Post"`)
})

Expand Down
13 changes: 13 additions & 0 deletions test/subset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,17 @@ describe('subset', () => {
}
)).toBeFalsy()
})
it('is no subset', () => {
expect(isSubset({
a: [{ c: [{ d: 1 }] }],
e: 0,
f: 2
},
{
a: [{ b: 0 }, { c: [{ d: 0 }, { d: 1 }] }],
// e: 1,
f: 2
}
)).toBeFalsy()
})
})

0 comments on commit 38c3532

Please sign in to comment.