Setup : - .env.test étoffé : DRIVE_DISK=fs, MAIL_DRIVER=smtp local, OCR_PROVIDER=mock. Réutilise la DB rubis_dev avec global transactions par test (rollback auto, isolation parfaite). - Schedulers (relance + checkin) détectent NODE_ENV=test et skippent BullMQ.add. Les tasks DB sont quand même créées (utiles pour assertions) mais aucun job orphelin n'arrive en Redis après rollback de tx. - helpers/auth.ts : factory createTestUser() qui crée org + user + 4 plans pré-fournis dans une tx, retourne user/org/accessToken/bearer header. createTwoOrgs() pour les tests cross-org à venir. Tests fonctionnels auth (tests/functional/auth.spec.ts) : - Signup : crée user + org + 4 plans pré-fournis (vérifie les slugs), refuse email mal formé / password court / email déjà pris - Login : émet AuthSession avec credentials valides, rejette mauvais password / email inconnu - Bearer auth : 401 sans token, 401 avec token bidon, 200 avec token valide - Logout : révoque le token courant, requêtes suivantes en 401 - Onboarding : PATCH /organizations/me pose onboardingCompletedAt à la 1re mise du nom, idempotent ensuite Pour lancer : `pnpm -F api test`
58 lines
1.9 KiB
TypeScript
58 lines
1.9 KiB
TypeScript
import User from '#models/user'
|
|
import Organization from '#models/organization'
|
|
import { provisionDefaultPlans } from '#services/default_plans'
|
|
import db from '@adonisjs/lucid/services/db'
|
|
|
|
let counter = 0
|
|
|
|
/**
|
|
* Helper : crée une organisation + un user + provisionne les 4 plans
|
|
* pré-fournis, dans une transaction. Retourne le user, l'org et un
|
|
* access token Bearer prêt à être passé en header.
|
|
*
|
|
* `counter` rend les emails uniques entre les tests d'une même suite —
|
|
* sans ça, les tests qui ne tombent pas dans une global tx risquent un
|
|
* email_taken.
|
|
*/
|
|
export async function createTestUser(overrides: {
|
|
email?: string
|
|
password?: string
|
|
fullName?: string
|
|
orgName?: string
|
|
} = {}) {
|
|
counter += 1
|
|
const email = overrides.email ?? `test-${counter}-${Date.now()}@rubis.test`
|
|
const password = overrides.password ?? 'password123'
|
|
const fullName = overrides.fullName ?? `Test User ${counter}`
|
|
const orgName = overrides.orgName ?? ''
|
|
|
|
const { user, org } = await db.transaction(async (trx) => {
|
|
const o = await Organization.create({ name: orgName }, { client: trx })
|
|
await provisionDefaultPlans(o.id, trx)
|
|
const u = await User.create({ email, password, fullName, organizationId: o.id }, { client: trx })
|
|
return { user: u, org: o }
|
|
})
|
|
|
|
const token = await User.accessTokens.create(user)
|
|
// .release() consomme la valeur — on capture une seule fois.
|
|
const accessToken = token.value!.release()
|
|
|
|
return {
|
|
user,
|
|
org,
|
|
plainPassword: password,
|
|
accessToken,
|
|
bearer: { Authorization: `Bearer ${accessToken}` },
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Variante : crée juste 2 users dans 2 orgs distinctes (pour les tests
|
|
* cross-org : user A ne peut pas voir/modifier les ressources de B).
|
|
*/
|
|
export async function createTwoOrgs() {
|
|
const a = await createTestUser({ orgName: 'Org A' })
|
|
const b = await createTestUser({ orgName: 'Org B' })
|
|
return { a, b }
|
|
}
|