Files
vikunja/frontend/tests/support/factory.ts
2025-11-28 16:48:08 +01:00

100 lines
2.4 KiB
TypeScript

import type {APIRequestContext} from '@playwright/test'
/**
* A factory makes it easy to seed the database with data.
*/
export class Factory {
static table: string | null = null
static request: APIRequestContext
static setRequestContext(request: APIRequestContext) {
this.request = request
}
static factory() {
return {}
}
/**
* Seeds a bunch of fake data into the database.
*
* Takes an override object as its single argument which will override the data from the factory.
* If the value of one of the override fields is `{increment}` that value will be replaced with an incrementing
* number through all created entities.
*
* @param override
* @returns {[]}
*/
static async create(count = 1, override = {}, truncate = true) {
const data = []
for (let i = 1; i <= count; i++) {
const entry = {
...this.factory(),
...override,
}
for (const e in entry) {
if (typeof entry[e] === 'function') {
entry[e] = entry[e](i)
continue
}
if (entry[e] === '{increment}') {
entry[e] = i
}
}
data.push(entry)
}
// Create a flattened copy of the data for seeding
// This removes nested objects/arrays that the backend can't handle
const flatData = data.map(item => {
const flatItem = {}
for (const key in item) {
const value = item[key]
// Only include primitive values (string, number, boolean, null, Date)
if (value === null || value === undefined ||
typeof value === 'string' ||
typeof value === 'number' ||
typeof value === 'boolean' ||
value instanceof Date) {
flatItem[key] = value
}
// Skip arrays, objects, and other complex types
}
return flatItem
})
await this.seed(this.table, flatData, truncate)
return Promise.resolve(data)
}
static async seed(table: string, data: any, truncate = true) {
if (data === null) {
data = []
}
const response = await this.request.patch(
`test/${table}?truncate=${truncate ? 'true' : 'false'}`,
{
data,
headers: {
'Content-Type': 'application/json',
'Authorization': process.env.VIKUNJA_SERVICE_TESTINGTOKEN || 'averyLongSecretToSe33dtheDB',
},
},
)
if (!response.ok()) {
const body = await response.json()
throw new Error(`Failed to seed data for table ${table} (${response.status()}): ${body.message}`)
}
return response.json()
}
static async truncate() {
await this.seed(this.table, null)
}
}