63 lines
5.0 KiB
JavaScript
63 lines
5.0 KiB
JavaScript
// Fictional doctors only; no external network or appointment submissions.
|
|
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://test.invalid/services/detskaya-klinika/priem-detskogo-oftalmologa/');
|
|
document.oninput = null;
|
|
const { default: React, act } = await import('react');
|
|
const { createRoot } = await import('react-dom/client');
|
|
const { MemoryRouter, Routes, Route } = await import('react-router-dom');
|
|
const vite = await createServer({ server: { middlewareMode: true, hmr: false }, appType: 'custom' });
|
|
const { api } = await vite.ssrLoadModule('/src/api.js');
|
|
const { default: ServicePage } = await vite.ssrLoadModule('/src/pages/ServicePage.jsx');
|
|
const { LeadModalProvider } = await vite.ssrLoadModule('/src/context/LeadModalContext.jsx');
|
|
const { serviceSpecialty } = await vite.ssrLoadModule('/src/lib/media.js');
|
|
const { renderService, renderPage } = await vite.ssrLoadModule('/src/entry-server.jsx');
|
|
const path = 'detskaya-klinika/priem-detskogo-oftalmologa';
|
|
const service = { id: 17, path, slug: 'priem-detskogo-oftalmologa', name: 'Тестовый детский офтальмолог', doctors: [], blocks: [], seo: {} };
|
|
const parent = { id: 1, path: 'detskaya-klinika', name: 'Детская клиника', children: [service], blocks: [], seo: {} };
|
|
const doctors = [
|
|
{ id: 1, slug: 'eye-test', full_name: 'Тестовый офтальмолог', last_name: 'Тестовый', first_name: 'Офтальмолог', position: 'Офтальмолог', specialties: [{ slug: 'oftalmologi', name: 'Офтальмологи', name_plural: 'Офтальмологи' }], booking: { provider: 'none' } },
|
|
{ id: 2, slug: 'uzi-test', full_name: 'Посторонний врач УЗИ', last_name: 'Посторонний', first_name: 'Врач', position: 'Врач УЗИ', specialties: [{ slug: 'detskie-vrachi', name: 'Детские врачи' }], booking: { provider: 'none' } },
|
|
];
|
|
const requested = [];
|
|
api.service = async (requestedPath) => ({ data: requestedPath === path ? service : parent });
|
|
api.prices = async () => ({ data: [] });
|
|
api.specialties = async () => ({ data: [{ slug: 'oftalmologi', name: 'Офтальмологи' }] });
|
|
api.doctors = async (params = {}) => {
|
|
requested.push(params.specialty);
|
|
return { data: doctors.filter((doctor) => !params.specialty || doctor.specialties.some((s) => s.slug === params.specialty)) };
|
|
};
|
|
api.bookingAvailability = async () => ({ data: { enabled: true, days: [] } });
|
|
api.createLead = api.createAppointment = () => { throw new Error('Submissions forbidden'); };
|
|
const container = document.getElementById('root');
|
|
const root = createRoot(container);
|
|
const click = async (node) => act(async () => node.dispatchEvent(new window.Event('click', { bubbles: true })));
|
|
try {
|
|
assert.equal(serviceSpecialty(path), 'oftalmologi');
|
|
assert.equal(serviceSpecialty('detskaya-klinika'), 'detskie-vrachi');
|
|
assert.equal(serviceSpecialty('oko'), 'oftalmologi');
|
|
assert.equal(serviceSpecialty('ginekologiya/test'), 'ginekologi');
|
|
assert.equal(serviceSpecialty('unknown/test'), undefined);
|
|
await act(async () => root.render(React.createElement(MemoryRouter, { initialEntries: [`/services/${path}/`] },
|
|
React.createElement(LeadModalProvider, {}, React.createElement(Routes, {}, React.createElement(Route, { path: '/services/*', element: React.createElement(ServicePage) }))))));
|
|
assert.match(container.querySelector('.service-doctors').textContent, /Тестовый офтальмолог/);
|
|
assert.doesNotMatch(container.querySelector('.service-doctors').textContent, /Посторонний/);
|
|
await click(container.querySelector('button.service-hero__btn'));
|
|
await click(container.querySelector('.doctor-picker__trigger'));
|
|
assert.deepEqual([...container.querySelectorAll('[data-doctor-id]')].map((node) => node.dataset.doctorId), ['1']);
|
|
assert.ok(requested.length >= 2);
|
|
assert.ok(requested.every((specialty) => specialty === 'oftalmologi'), 'Both service cards and booking must request ophthalmologists');
|
|
const common = { doctors, specialties: [], prices: [], site: { branches: [], addresses: [], phone: '', hours: '' } };
|
|
const server = renderService(service, parent, common, 'https://test.invalid');
|
|
assert.deepEqual(JSON.parse(server.initial)['doctors:oftalmologi'].data.map((d) => d.id), [1]);
|
|
const runtime = renderPage(`/services/${path}/`, { [`service:${path}`]: { data: service }, doctors: { data: doctors } }, 'https://test.invalid');
|
|
assert.deepEqual(JSON.parse(runtime.initial)['doctors:oftalmologi'].data.map((d) => d.id), [1]);
|
|
console.log('PASS: service doctor cards, booking picker, runtime SSR and prerender use the specific ophthalmology specialty');
|
|
} finally {
|
|
await act(async () => root.unmount());
|
|
await vite.close();
|
|
}
|