edtech / apps /api /test /critical-flows.test.ts
CognxSafeTrack
feat: backlog P0→P3 — toast system, payments, tenant isolation, feedback handler, i18n parity
6dd9bad
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { buildApp } from '../src/app';
import { prisma } from '../src/services/prisma';
describe('Critical Flows Integration', () => {
let app: any;
beforeAll(async () => {
app = await buildApp();
});
afterAll(async () => {
await app.close();
});
it('should create a new organization and then allow login', async () => {
const slug = `test-org-${Math.random().toString(36).slice(2, 7)}`;
const email = `admin@${slug}.com`;
// 1. Create Organization
const createRes = await app.inject({
method: 'POST',
url: '/v1/organizations',
payload: {
name: 'Test Org',
slug,
adminEmail: email,
adminName: 'Test Admin',
password: 'password123'
}
});
expect(createRes.statusCode).toBe(201);
const orgData = JSON.parse(createRes.payload);
expect(orgData.organization.slug).toBe(slug);
// 2. Login
const loginRes = await app.inject({
method: 'POST',
url: '/v1/auth/login',
payload: {
email,
password: 'password123'
}
});
expect(loginRes.statusCode).toBe(200);
const authData = JSON.parse(loginRes.payload);
expect(authData.token).toBeDefined();
expect(authData.user.organizationId).toBe(orgData.organization.id);
});
it('should return 404 for non-existent student', async () => {
const res = await app.inject({
method: 'GET',
url: '/v1/student/me?phone=999999999'
});
expect(res.statusCode).toBe(404);
});
it('should receive a WhatsApp message and return 200', async () => {
const res = await app.inject({
method: 'POST',
url: '/v1/whatsapp/webhook',
payload: {
object: 'whatsapp_business_account',
entry: [{
id: 'WABA_ID',
changes: [{
value: {
messaging_product: 'whatsapp',
metadata: { display_phone_number: '123456789', phone_number_id: 'PN_ID' },
contacts: [{ profile: { name: 'Test User' }, wa_id: '221770000000' }],
messages: [{
from: '221770000000',
id: 'MSG_ID',
timestamp: '1625097600',
text: { body: 'HELLO' },
type: 'text'
}]
},
field: 'messages'
}]
}]
}
});
// Note: Webhook returns 200 even if processing fails internally to avoid retries from Meta,
// unless it's a structural error.
expect(res.statusCode).toBe(200);
});
});