Files
payloadcms/test/database/int.spec.ts
2024-02-16 15:09:51 -05:00

192 lines
4.6 KiB
TypeScript

import type { Payload } from '../../packages/payload/src'
import type { TypeWithID } from '../../packages/payload/src/collections/config/types'
import type { PayloadRequest } from '../../packages/payload/src/types'
import { getPayload } from '../../packages/payload/src'
import { commitTransaction } from '../../packages/payload/src/utilities/commitTransaction'
import { initTransaction } from '../../packages/payload/src/utilities/initTransaction'
import { devUser } from '../credentials'
import { startMemoryDB } from '../startMemoryDB'
import configPromise from './config'
let payload: Payload
let user: TypeWithID & Record<string, unknown>
let useTransactions = true
const collection = 'posts'
const title = 'title'
describe('database', () => {
beforeAll(async () => {
const config = await startMemoryDB(configPromise)
payload = await getPayload({ config })
if (payload.db.name === 'mongoose') {
useTransactions = false
}
const loginResult = await payload.login({
collection: 'users',
data: {
email: devUser.email,
password: devUser.password,
},
})
user = loginResult.user
})
describe('transactions', () => {
describe('local api', () => {
it('should commit multiple operations in isolation', async () => {
const req = {
payload,
user,
} as PayloadRequest
await initTransaction(req)
const first = await payload.create({
collection,
data: {
title,
},
req,
})
if (useTransactions) {
await expect(() =>
payload.findByID({
id: first.id,
collection,
// omitting req for isolation
}),
).rejects.toThrow('The requested resource was not found.')
}
const second = await payload.create({
collection,
data: {
title,
},
req,
})
await commitTransaction(req)
expect(req.transactionID).toBeUndefined()
const firstResult = await payload.findByID({
id: first.id,
collection,
req,
})
const secondResult = await payload.findByID({
id: second.id,
collection,
req,
})
expect(firstResult.id).toStrictEqual(first.id)
expect(secondResult.id).toStrictEqual(second.id)
})
it('should commit multiple operations async', async () => {
const req = {
payload,
user,
} as PayloadRequest
let first
let second
const firstReq = payload
.create({
collection,
data: {
title,
},
req,
})
.then((res) => {
first = res
})
const secondReq = payload
.create({
collection,
data: {
title,
},
req,
})
.then((res) => {
second = res
})
await Promise.all([firstReq, secondReq])
await commitTransaction(req)
expect(req.transactionID).toBeUndefined()
const firstResult = await payload.findByID({
id: first.id,
collection,
req,
})
const secondResult = await payload.findByID({
id: second.id,
collection,
req,
})
expect(firstResult.id).toStrictEqual(first.id)
expect(secondResult.id).toStrictEqual(second.id)
})
it('should rollback operations on failure', async () => {
const req = {
payload,
user,
} as PayloadRequest
await initTransaction(req)
const first = await payload.create({
collection,
data: {
title,
},
req,
})
try {
await payload.create({
collection,
data: {
throwAfterChange: true,
title,
},
req,
})
} catch (error: unknown) {
// catch error and carry on
}
expect(req.transactionID).toBeFalsy()
// this should not do anything but is needed to be certain about the next assertion
await commitTransaction(req)
if (useTransactions) {
await expect(() =>
payload.findByID({
id: first.id,
collection,
req,
}),
).rejects.toThrow('The requested resource was not found.')
}
})
})
})
})