import type { FastifyInstance } from 'fastify' import { buildApp } from '../main.js' import { sql, eq } from 'drizzle-orm' import { companies, locations } from '../db/schema/stores.js' import { UnitStatusService, ItemConditionService } from '../services/lookup.service.js' import { RbacService } from '../services/rbac.service.js' import { roles } from '../db/schema/rbac.js' import { users } from '../db/schema/users.js' export const TEST_COMPANY_ID = '00000000-0000-0000-0000-000000000099' export const TEST_LOCATION_ID = '00000000-0000-0000-0000-000000000099' export async function createTestApp(): Promise { const app = await buildApp() await app.ready() return app } export async function cleanDb(app: FastifyInstance): Promise { await app.db.execute(sql` DO $$ DECLARE r RECORD; BEGIN SET client_min_messages TO WARNING; FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = 'public') LOOP EXECUTE 'TRUNCATE TABLE ' || quote_ident(r.tablename) || ' CASCADE'; END LOOP; RESET client_min_messages; END $$ `) } export async function seedTestCompany(app: FastifyInstance): Promise { await app.db.insert(companies).values({ id: TEST_COMPANY_ID, name: 'Test Music Co.', timezone: 'America/Chicago', }) await app.db.insert(locations).values({ id: TEST_LOCATION_ID, name: 'Test Location', }) await UnitStatusService.seedDefaults(app.db) await ItemConditionService.seedDefaults(app.db) // Seed RBAC permissions and default roles await RbacService.seedPermissions(app.db) await RbacService.seedDefaultRoles(app.db) } export async function registerAndLogin( app: FastifyInstance, overrides: { email?: string password?: string firstName?: string lastName?: string role?: string } = {}, ): Promise<{ token: string; user: Record }> { const response = await app.inject({ method: 'POST', url: '/v1/auth/register', headers: { 'x-company-id': TEST_COMPANY_ID }, payload: { email: overrides.email ?? 'test@forte.dev', password: overrides.password ?? 'testpassword1234', firstName: overrides.firstName ?? 'Test', lastName: overrides.lastName ?? 'User', role: overrides.role ?? 'admin', }, }) const body = response.json() // Assign the admin role to the test user so they have all permissions if (body.user?.id) { const [adminRole] = await app.db .select() .from(roles) .where(eq(roles.slug, 'admin')) .limit(1) if (adminRole) { await RbacService.assignRole(app.db, body.user.id, adminRole.id) } // Re-login to get a fresh token (permissions are loaded on authenticate) const loginRes = await app.inject({ method: 'POST', url: '/v1/auth/login', payload: { email: overrides.email ?? 'test@forte.dev', password: overrides.password ?? 'testpassword1234', }, }) const loginBody = loginRes.json() return { token: loginBody.token, user: loginBody.user } } return { token: body.token, user: body.user } }