caterium-app/tests/support-form.spec.mjs
pavlov346346-source 5e72b23161
Correct support mailbox to support@caterium.ru (#42)
Apply the user's explicit address correction to the PHP recipient, Help links, contact form and tests. Refresh the form URL and PWA cache. Exact-recipient PHP tests and support/Help browser tests passed in isolated run 35575721587. No real mail sent, delivery not claimed. Keep standard main QA and production publication gates unchanged; no auth, database or unrelated feature changes.
2026-09-21 11:04:06 +03:00

55 lines
5.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {test,expect} from '@playwright/test';
import fs from 'node:fs';
import {spawnSync} from 'node:child_process';
const EMAIL='support@caterium.ru';
async function fixture(page){
await page.route('**/index.html',r=>r.fulfill({contentType:'text/html',body:'<!doctype html><html><head><meta name="viewport" content="width=device-width,initial-scale=1"></head><body><header><nav></nav></header></body></html>'}));
await page.goto('/index.html');await page.addStyleTag({url:'/core/help-center.css'});await page.addScriptTag({url:'/core/help-center.js'});
await page.getByRole('button',{name:'Помощь',exact:true}).click();await expect(page.locator('#ctContactTab')).toBeVisible();
}
async function fill(page){
await page.locator('#ctContactTab').click();await page.locator('#ctContactName').fill('Анна');await page.locator('#ctContactEmail').fill('anna@example.invalid');
await page.locator('#ctContactSubject').fill('Не получается открыть PDF');await page.locator('#ctContactMessage').fill('Как посмотреть предложение с телефона?');
}
function mock(page,answer={ok:true,status:'accepted',id:'SUP-20260921-123456ABCDEF'},http=202){
const requests=[];
return page.route('**/api/support.php',r=>{requests.push({method:r.request().method(),body:r.request().postDataJSON()});return r.fulfill({status:r.request().method()==='GET'?200:http,contentType:'application/json',body:JSON.stringify(r.request().method()==='GET'?{csrf:'token',recipient:EMAIL}:answer)});}).then(()=>requests);
}
test('PHP support delivery validates inputs and never sends a real test email',async()=>{
const result=spawnSync('php',['tests/support-mail.php'],{encoding:'utf8'});expect(result.status,result.stderr+result.stdout).toBe(0);
});
test('help exposes contact form after an unanswered search, without background mail or personal data requests',async({page})=>{
const requests=await mock(page);await fixture(page);
await page.locator('#ctHelpSearch').fill('zznomatch99381zz');await expect(page.locator('#ctHelpStatus')).toContainText('Ничего не найдено');
await page.locator('#ctHelpGuide [data-human-support]').click();await expect(page.locator('#ctContactForm')).toBeVisible();
expect(requests).toHaveLength(0);await expect(page.locator('#ctContactSection')).toContainText(EMAIL);
await page.locator('#ctHelpGuideTab').click();await expect(page.locator('#ctContactForm')).toBeHidden();await expect(page.locator('#ctHelpSearch')).toBeVisible();
});
test('explicit form submission sends the fixed-recipient contract and whitelisted diagnostics only',async({page},info)=>{
const requests=await mock(page);await fixture(page);
await page.evaluate(()=>{localStorage.sunOrders='PRIVATE_ORDER_CANARY';const sdk={token:'SECRET_TOKEN_CANARY'};sdk.self=sdk;window.SunCloudV2={getClient:()=>sdk};});
await fill(page);await page.locator('#ctContactDiagnostics').check();await page.screenshot({path:info.outputPath('support-form.png')});
expect(await page.locator('#ctContactForm').evaluate(el=>el.scrollWidth<=el.clientWidth)).toBe(true);
await page.locator('#ctContactSend').click();await expect(page.locator('#ctContactStatus')).toContainText('принято почтовым сервером');
const post=requests.find(r=>r.method==='POST').body;expect(post.email).toBe('anna@example.invalid');expect(post.message).toContain('предложение');
expect(post.device).toContain('экран');expect(post).not.toHaveProperty('to');expect(post).not.toHaveProperty('token');expect(JSON.stringify(post)).not.toMatch(/PRIVATE_ORDER_CANARY|SECRET_TOKEN_CANARY/);
await expect(page.locator('#ctContactMessage')).toHaveValue('');expect(await page.evaluate(()=>localStorage.sunOrders)).toBe('PRIVATE_ORDER_CANARY');
});
test('failed submission preserves the form and request ID; no silent mail-client fallback or false success',async({page})=>{
const requests=await mock(page,{ok:false,message:'Почтовый сервер не принял сообщение'},503);await fixture(page);await fill(page);
await page.locator('#ctContactSend').click();await expect(page.locator('#ctContactStatus')).toHaveAttribute('role','alert');await expect(page.locator('#ctContactMessage')).toHaveValue('Как посмотреть предложение с телефона?');
await page.locator('#ctContactSend').click();await expect.poll(()=>requests.filter(r=>r.method==='POST').length).toBe(2);
const posts=requests.filter(r=>r.method==='POST').map(r=>r.body);expect(posts[0].request_id).toBe(posts[1].request_id);expect(posts[0]).not.toHaveProperty('device');
await page.locator('#ctHelpClose').click();await page.getByRole('button',{name:'Помощь',exact:true}).click();await page.locator('#ctContactTab').click();await expect(page.locator('#ctContactMessage')).toHaveValue('Как посмотреть предложение с телефона?');
});
test('invalid fields never send and another account never sees the previous support draft',async({page})=>{
const requests=await mock(page);await fixture(page);await fill(page);await page.locator('#ctContactEmail').fill('invalid');await page.locator('#ctContactSend').click();expect(requests).toHaveLength(0);
await page.evaluate(()=>{window.SunCloudV2={getSession:()=>({user:{id:'another',email:'other@example.invalid'}})};window.dispatchEvent(new Event('sun:cloud-permissions-changed'));});
await page.getByRole('button',{name:'Помощь',exact:true}).click();await page.locator('#ctContactTab').click();await expect(page.locator('#ctContactMessage')).toHaveValue('');await expect(page.locator('#ctContactEmail')).toHaveValue('other@example.invalid');
});