import { test } from '@japa/runner' import testUtils from '@adonisjs/core/services/test_utils' import { createTestUser } from '../helpers/auth.js' import { body, type ApiOk } from '../helpers/response.js' type Kpis = { rubisCount: number rubisThisMonth: number encaisseCents: number factureToRelance: number factureInRelance: number miseEnDemeurePending: number monthlyGoalProgress: number } type ActivityEvent = { id: string; kind: string; label: string } type LatePayer = { clientId: string; name: string; lateInvoicesCount: number } test.group('Dashboard — GET /dashboard/kpis', (group) => { group.each.setup(() => testUtils.db().withGlobalTransaction()) test('zéros sur une org vierge', async ({ client, assert }) => { const { bearer } = await createTestUser() const r = await client.get('/api/v1/dashboard/kpis').headers(bearer) r.assertStatus(200) const k = body>(r).data assert.equal(k.rubisCount, 0) assert.equal(k.rubisThisMonth, 0) assert.equal(k.encaisseCents, 0) assert.equal(k.factureToRelance, 0) assert.equal(k.factureInRelance, 0) assert.equal(k.miseEnDemeurePending, 0) }) test('factureToRelance compte les pending', async ({ client, assert }) => { const { bearer } = await createTestUser() const c = await client .post('/api/v1/clients') .headers(bearer) .json({ name: 'Dash', email: 'dash@spec.test' }) const cid = body>(c).data.id await client.post('/api/v1/invoices').headers(bearer).json({ clientId: cid, clientName: 'Dash', numero: 'F-DASH-01', amountTtcCents: 10000, issueDate: '2026-04-01T09:00:00.000Z', dueDate: '2026-05-01T09:00:00.000Z', }) const r = await client.get('/api/v1/dashboard/kpis').headers(bearer) assert.equal(body>(r).data.factureToRelance, 1) }) test('encaisseCents et rubisCount bumpent après mark-paid', async ({ client, assert, }) => { const { bearer } = await createTestUser() const c = await client .post('/api/v1/clients') .headers(bearer) .json({ name: 'Paid Spec', email: 'paid@spec.test' }) const cid = body>(c).data.id const inv = await client.post('/api/v1/invoices').headers(bearer).json({ clientId: cid, clientName: 'Paid Spec', numero: 'F-PAID-01', amountTtcCents: 250000, // issueDate/dueDate dans le mois courant pour rentrer dans rubisThisMonth issueDate: new Date().toISOString(), dueDate: new Date(Date.now() + 86_400_000).toISOString(), }) const invId = body>(inv).data.id await client.post(`/api/v1/invoices/${invId}/mark-paid`).headers(bearer) const r = await client.get('/api/v1/dashboard/kpis').headers(bearer) const k = body>(r).data assert.equal(k.rubisCount, 1) assert.equal(k.encaisseCents, 250000) }) }) test.group('Dashboard — GET /dashboard/activity', (group) => { group.each.setup(() => testUtils.db().withGlobalTransaction()) test('vide sur une org sans actions', async ({ client, assert }) => { const { bearer } = await createTestUser() const r = await client.get('/api/v1/dashboard/activity').headers(bearer) r.assertStatus(200) assert.deepEqual(body>(r).data, []) }) test('mark-paid logge un event invoice_paid', async ({ client, assert }) => { const { bearer } = await createTestUser() const c = await client .post('/api/v1/clients') .headers(bearer) .json({ name: 'Activity', email: 'activity@spec.test' }) const cid = body>(c).data.id const inv = await client.post('/api/v1/invoices').headers(bearer).json({ clientId: cid, clientName: 'Activity', numero: 'F-ACT-01', amountTtcCents: 50000, issueDate: '2026-04-01T09:00:00.000Z', dueDate: '2026-05-01T09:00:00.000Z', }) const invId = body>(inv).data.id await client.post(`/api/v1/invoices/${invId}/mark-paid`).headers(bearer) const r = await client.get('/api/v1/dashboard/activity').headers(bearer) const events = body>(r).data assert.isAbove(events.length, 0) assert.equal(events[0].kind, 'invoice_paid') }) }) test.group('Dashboard — GET /dashboard/top-late', (group) => { group.each.setup(() => testUtils.db().withGlobalTransaction()) test('liste les clients avec factures actives en retard', async ({ client, assert, }) => { const { bearer } = await createTestUser() const c = await client .post('/api/v1/clients') .headers(bearer) .json({ name: 'En Retard', email: 'late@spec.test' }) const cid = body>(c).data.id // dueDate dans le passé → en retard await client.post('/api/v1/invoices').headers(bearer).json({ clientId: cid, clientName: 'En Retard', numero: 'F-LATE-01', amountTtcCents: 50000, issueDate: '2025-12-01T09:00:00.000Z', dueDate: '2025-12-31T09:00:00.000Z', }) const r = await client.get('/api/v1/dashboard/top-late').headers(bearer) r.assertStatus(200) const list = body>(r).data assert.lengthOf(list, 1) assert.equal(list[0].name, 'En Retard') assert.equal(list[0].lateInvoicesCount, 1) }) })