// Fictional contact data and mocked submissions only. No external requests. import assert from 'node:assert/strict'; import { parseHTML } from 'linkedom'; import { createServer } from 'vite'; const { window } = parseHTML('
'); Object.assign(globalThis, { window, document: window.document, HTMLElement: window.HTMLElement, IS_REACT_ACT_ENVIRONMENT: true }); window.location = new URL('https://test.invalid/sales/'); 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, 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 { LeadModalProvider } = await vite.ssrLoadModule('/src/context/LeadModalContext.jsx'); const { default: PromosPage } = await vite.ssrLoadModule('/src/pages/PromosPage.jsx'); const { default: CheckupPage } = await vite.ssrLoadModule('/src/pages/CheckupPage.jsx'); const program = { id: 1, slug: 'chek-ap-ya-v-sad', name: 'Я в сад', audience: 'kids', blocks: [], seo: {} }; api.promos = async () => ({ data: [ { id: 1, slug: 'ya-v-sad-sale', title: 'Я в сад' }, { id: 2, slug: 'unrelated-promo', title: 'Другая акция', checkup_slug: program.slug }, ] }); api.checkups = async () => ({ data: [program] }); api.checkup = async () => ({ data: program }); let bookingCalls = 0; api.doctors = api.bookingAvailability = api.doctorSlots = async () => { bookingCalls++; throw new Error('Checkup request must not load doctors or schedules'); }; const submissions = []; api.createLead = async (payload) => { submissions.push(payload); return { data: { message: 'Тестовая заявка принята' } }; }; api.createAppointment = () => { throw new Error('Checkup must not create an appointment in 1C'); }; const container = document.getElementById('root'); const root = createRoot(container); const click = async (node) => { assert.ok(node, 'Expected actionable element'); await act(async () => node.dispatchEvent(new window.Event('click', { bubbles: true }))); }; const mount = async (url, Page, route) => act(async () => root.render( React.createElement(MemoryRouter, { key: url, initialEntries: [url] }, React.createElement(LeadModalProvider, {}, React.createElement(Routes, {}, React.createElement(Route, { path: route, element: React.createElement(Page) })))))); function checkSimpleForm() { const modal = container.querySelector('[role="dialog"]'); assert.ok(modal); assert.match(modal.textContent, /Записаться на чек-ап/); assert.match(modal.textContent, /Программа: Я в сад/); assert.equal(modal.querySelectorAll('input').length, 3, 'Only name, phone and consent'); assert.equal(modal.querySelector('select, textarea, input[type="date"], .doctor-picker, .native-booking'), null); assert.equal(bookingCalls, 0); return modal; } try { await mount('/sales/', PromosPage, '/sales/'); for (const card of container.querySelectorAll('.promo-card')) { await click(card.querySelector('button')); checkSimpleForm(); await click(container.querySelector('[aria-label="Закрыть"]')); } await click(container.querySelector('.promo-card button')); let modal = checkSimpleForm(); await act(async () => Simulate.submit(modal.querySelector('form'))); assert.equal(submissions.length, 0, 'Empty form rejected'); await act(async () => Simulate.change(modal.querySelector('input[type="text"]'), { target: { value: 'Тестовая заявка' } })); await act(async () => Simulate.change(modal.querySelector('input[type="tel"]'), { target: { value: '79990000000' } })); await act(async () => Simulate.submit(modal.querySelector('form'))); assert.equal(submissions.length, 0, 'Consent required'); await act(async () => Simulate.change(modal.querySelector('input[type="checkbox"]'), { target: { type: 'checkbox', checked: true } })); await act(async () => Simulate.submit(modal.querySelector('form'))); assert.equal(submissions.length, 1); assert.equal(submissions[0].form, 'appointment', 'Use existing lead endpoint form'); assert.deepEqual(submissions[0].extra, { checkup_slug: program.slug, checkup_name: program.name }); assert.match(submissions[0].message, /Чек-ап: Я в сад/); assert.match(submissions[0].message, /Акция: Я в сад/); assert.equal(submissions[0].doctor_id, undefined); assert.equal(submissions[0].slot, undefined); assert.equal(submissions[0].consent, true); assert.match(container.querySelector('[role="dialog"]').textContent, /Тестовая заявка принята/); await mount(`/checkup/${program.slug}/`, CheckupPage, '/checkup/:slug/'); await click(container.querySelector('.checkup-hero__btn')); checkSimpleForm(); await click(container.querySelector('[aria-label="Закрыть"]')); const bottomCta = [...container.querySelectorAll('button')].find((node) => node.textContent === 'Оставить заявку'); await click(bottomCta); checkSimpleForm(); console.log('PASS: promotion links (slug fallback and explicit), checkup hero/bottom CTAs, contact validation and program metadata; no doctors, schedules or 1C appointment calls'); } finally { await act(async () => root.unmount()); await vite.close(); }