dana-medical-site/web/scripts/test-booking-service-safety.mjs

50 lines
3.3 KiB
JavaScript

// Only fictional data and a mocked API. No live requests or appointments.
import assert from 'node:assert/strict';
import { parseHTML } from 'linkedom';
import { createServer } from 'vite';
const { window } = parseHTML('<html><body><div id="root"></div></body></html>');
Object.assign(globalThis, { window, document: window.document, HTMLElement: window.HTMLElement, IS_REACT_ACT_ENVIRONMENT: true });
window.location = new URL('https://booking-test.invalid/');
document.oninput = null;
const { default: React, act } = await import('react');
const { createRoot } = await import('react-dom/client');
const { Simulate } = await import('react-dom/test-utils');
const { MemoryRouter } = await import('react-router-dom');
const vite = await createServer({ server: { middlewareMode: true, hmr: false }, appType: 'custom' });
const { default: NativeBooking } = await vite.ssrLoadModule('/src/components/NativeBooking.jsx');
const { api } = await vite.ssrLoadModule('/src/api.js');
const slot = { start: '2070-10-23T12:00:00+03:00', end: '2070-10-23T12:30:00+03:00', status: 'free', branch_id: 'test', branch: 'Тестовый филиал' };
api.doctorSlots = async () => ({ data: { enabled: true, slots: [slot], services: [
{ id: 'unverified-lab', name: 'Непроверенный анализ из общего справочника' },
{ id: 'unverified-procedure', name: 'Непроверенная процедура другого направления' },
] } });
let submitted;
api.createAppointment = async (payload) => { submitted = payload; return { data: { message: 'Тестовая заявка принята' } }; };
const container = document.getElementById('root');
const root = createRoot(container);
try {
await act(async () => root.render(React.createElement(MemoryRouter, {}, React.createElement(NativeBooking, {
doctor: { slug: 'fictional-dentist' }, initialSlot: slot,
onClose() {}, onUnavailable() { throw new Error('Actual free slot must stay bookable'); },
}))));
assert.ok(!container.querySelector('select'), 'Unverified imported services must not appear in the booking form');
assert.doesNotMatch(container.textContent, /Непроверенный анализ|Непроверенная процедура/);
assert.match(container.textContent, /23 октября/);
await act(async () => {
Simulate.change(container.querySelector('input[type="text"]'), { target: { type: 'text', value: 'Вымышленный пациент' } });
Simulate.change(container.querySelector('input[type="tel"]'), { target: { type: 'tel', value: '+79990000000' } });
Simulate.change(container.querySelector('input[type="checkbox"]'), { target: { type: 'checkbox', checked: true } });
});
await act(async () => Simulate.submit(container.querySelector('form')));
assert.equal(submitted.doctor_slug, 'fictional-dentist');
assert.equal(submitted.start, slot.start);
assert.equal(submitted.branch_id, 'test');
assert.equal(Object.hasOwn(submitted, 'service_id'), false, 'No unverified service identifier may be sent');
assert.match(container.textContent, /Тестовая заявка принята/);
console.log('PASS: unrelated imported services hidden, real chosen slot retained, booking submitted without service_id; fictional data only');
} finally {
await act(async () => root.unmount());
await vite.close();
}