import { describe, it, expect } from 'vitest'; import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; /** * Экраны входа и регистрации собирают персональные данные: почту, пароль, * код из СМС, резервный код. С 20.07.2026 на них грузится Вебвизор, поэтому * контейнер формы обязан нести ym-hide-content — иначе введённое уедет * в записи Метрики открытым текстом (152-ФЗ). * * Проверяем разметку файлом, а не смонтированным компонентом: класс должен * стоять в исходнике всегда, независимо от состояния формы. */ const EKRANY = [ 'LoginView.vue', 'RegisterView.vue', 'ForgotPasswordView.vue', 'ResetPasswordView.vue', 'TwoFactorView.vue', 'UseRecoveryCodeView.vue', 'ConfirmEmailView.vue', ]; /** * Экраны, где почта выводится в ЗАГОЛОВКЕ — то есть вне контейнера формы. * Класс на форме их не накрывает: обнаружено при исполнении 20.07.2026, * до находки план считал, что все ПДн лежат внутри формы. * Здесь маскировка обязана стоять на самом теге с почтой. */ const EKRANY_S_POCHTOY_V_ZAGOLOVKE: Array<[string, string]> = [ ['TwoFactorView.vue', 'userEmail'], ['ConfirmEmailView.vue', 'email'], ]; describe('маскировка ПДн на экранах входа', () => { it.each(EKRANY)('%s закрывает форму от записи Вебвизором', (fayl) => { const put = resolve(__dirname, '../../resources/js/views/auth', fayl); const ishodnik = readFileSync(put, 'utf-8'); expect(ishodnik).toContain('ym-hide-content'); }); it.each(EKRANY_S_POCHTOY_V_ZAGOLOVKE)( '%s маскирует почту в заголовке — она вне формы, класс на форме её не закрывает', (fayl, peremennaya) => { const put = resolve(__dirname, '../../resources/js/views/auth', fayl); const ishodnik = readFileSync(put, 'utf-8'); // Тег, который выводит почту, обязан сам нести класс маскировки. // Проверяем строку целиком, а не наличие класса где-то в файле: // иначе тест зеленеет за счёт класса на форме и дыру пропускает. const stroka = ishodnik .split('\n') .find((s) => s.includes(`{{ ${peremennaya} }}`)); expect(stroka, `не нашёл вывод {{ ${peremennaya} }} в ${fayl}`).toBeDefined(); expect(stroka).toContain('ym-hide-content'); } ); });