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) } static async truncateAll() { const response = await this.request.delete('test/all', { headers: { 'Authorization': process.env.VIKUNJA_SERVICE_TESTINGTOKEN || 'averyLongSecretToSe33dtheDB', }, }) if (!response.ok()) { const body = await response.json() throw new Error(`Failed to truncate all tables (${response.status()}): ${body.message}`) } } }