PPPAIMT-Crest/backend/test/surveyExport.test.js

102 lines
3.5 KiB
JavaScript

import { randomUUID } from 'node:crypto';
import argon2 from 'argon2';
import ExcelJS from 'exceljs';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { createServer } from '../src/app.js';
import { db } from '../src/db/knex.js';
import { seedSurveyDefinition } from '../src/survey/seed.js';
import { truncateTables } from './truncate.js';
const email = 'export-admin@example.com';
const password = 'correct-password';
/**
* @param {import('@hapi/hapi').ServerInjectResponse} response
*/
function sessionCookie(response) {
const raw = response.headers['set-cookie'];
const header = Array.isArray(raw) ? raw[0] : raw;
return header.split(';')[0];
}
describe('survey export', () => {
/** @type {import('@hapi/hapi').Server | undefined} */
let server;
beforeEach(async () => {
await seedSurveyDefinition();
});
afterEach(async () => {
await server?.stop();
await truncateTables();
});
it('writes response headers, question ids, and choice counts', async () => {
server = await createServer();
await db('admin_users').insert({
name: 'Administrator',
email,
password_hash: await argon2.hash(password, { type: argon2.argon2id }),
is_active: true,
});
const login = await server.inject({
method: 'POST',
url: '/api/admin/auth/login',
payload: { email, password },
});
const definitionId = await seedSurveyDefinition();
const [applicationId] = await db('applications').insert({
public_id: randomUUID(),
email: 'physician@example.com',
status: 'APPROVED',
full_name: 'Asha Rao',
registration_no: 'MMC-100',
version: 1,
});
await db('survey_responses').insert({
application_id: applicationId,
survey_definition_id: definitionId,
answers: JSON.stringify({
adherence_comparison: { choice: 'much_better' },
pack_split: {
regular_pmdi: { asthma: 25, copd: 25 },
regular_rotacap: { asthma: 25, copd: 25 },
extended_pmdi: { asthma: 25, copd: 25 },
extended_rotacap: { asthma: 25, copd: 25 },
},
}),
status: 'COMPLETED',
started_at: new Date(),
completed_at: new Date(),
});
const response = await server.inject({
method: 'GET',
url: '/api/admin/survey/export?status=COMPLETED',
headers: { cookie: sessionCookie(login) },
});
expect(response.statusCode).toBe(200);
expect(response.headers['content-disposition']).toContain('survey-responses.xlsx');
const workbook = new ExcelJS.Workbook();
await workbook.xlsx.load(response.rawPayload);
const responses = workbook.getWorksheet('Responses');
const headers = responses.getRow(1).values.slice(1);
expect(headers).toContain(
'Prescribing % - Extended-Dose Pack — Rotacap (pack of 60) - COPD',
);
const column =
headers.indexOf('Prescribing % - Extended-Dose Pack — Rotacap (pack of 60) - COPD') + 1;
expect(responses.getRow(2).getCell(column).value).toBe(25);
const questions = workbook.getWorksheet('Questions');
const questionIds = questions.getColumn(1).values;
expect(questionIds).toContain('pack_split');
const summary = workbook.getWorksheet('Summary');
const summaryText = summary.getSheetValues().flat().join(' ');
expect(summaryText).toContain('Much better');
expect(summaryText).toContain('1');
expect(await db('audit_log').where({ action: 'SURVEY_EXPORTED' }).first()).toBeTruthy();
});
});