Files
portal/app/tests/Unit/Support/SupplierProjectNameTest.php
T
Дмитрий 612bf71928 fix(privacy): срезаем канальный префикс поставщика B<N>_ из клиентских выдач
Клиент не должен видеть внутреннюю схему каналов поставщика (B1_/B2_/B6_…).
Фронт срезал префикс только на экране, но API сделок, публичный API тенанта и
экспорт CSV/XLSX отдавали сырое имя проекта — префикс утекал клиенту.

- new App\Support\SupplierProjectName::strip() (regex ^B\d+_) — серверный срез
- применён в DealController (SPA), V1\DealsController (публичный API), DealExportController (экспорт)
- фронтовый stripChannelPrefix расширен ^B[123]_ -> ^B\d+_ (закрывает B6/B8)
- убрано имя поставщика из комментариев клиентского фронта; admin-строки -> crm.lead.store
- phpstan-baseline перегенерён (сдвиг счётчиков Pest-ложняков + убран устаревший ignore)
- тесты: unit 6 + feature x3 (RED->GREEN), Pest 68/68, Vitest 9/9, Pint clean, stan 0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 10:47:49 +03:00

46 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
use App\Support\SupplierProjectName;
/**
* Серверный аналог фронтового stripChannelPrefix (resources/js/composables/projectName.ts).
* Поставщик префиксует имена проектов кодом канала-провайдера (B1_/B2_/B3_/B6_/B8_/B<N>_).
* Клиенту этот префикс показывать нельзя — он раскрывает нашу схему каналов/перекупа.
* Срезаем ЛЮБОЙ B<цифры>_ в начале строки (не только B1/B2/B3), но не букву (BX_) и не середину.
*/
test('срезает B1_/B2_/B3_ префикс', function () {
expect(SupplierProjectName::strip('B1_73912557675 [35]'))->toBe('73912557675 [35]');
expect(SupplierProjectName::strip('B2_krk-finance.ru/cabinet/auth [24]'))->toBe('krk-finance.ru/cabinet/auth [24]');
expect(SupplierProjectName::strip('B3_kras.vashinvestor.ru [23]'))->toBe('kras.vashinvestor.ru [23]');
});
test('срезает B6_/B8_ и любой B<цифры>_ (главный фикс — не только B1-3)', function () {
expect(SupplierProjectName::strip('B6_78002000010'))->toBe('78002000010');
expect(SupplierProjectName::strip('B8_segment-list'))->toBe('segment-list');
expect(SupplierProjectName::strip('B4_other'))->toBe('other');
expect(SupplierProjectName::strip('B0_zero'))->toBe('zero');
expect(SupplierProjectName::strip('B10_multi'))->toBe('multi');
});
test('case-insensitive: b1_/b6_ тоже срезает', function () {
expect(SupplierProjectName::strip('b1_test'))->toBe('test');
expect(SupplierProjectName::strip('b6_demo'))->toBe('demo');
});
test('не трогает букву BX_ (только цифры) и имя без префикса', function () {
expect(SupplierProjectName::strip('BX_unknown'))->toBe('BX_unknown');
expect(SupplierProjectName::strip('Натяжные потолки'))->toBe('Натяжные потолки');
expect(SupplierProjectName::strip('okna.ru'))->toBe('okna.ru');
});
test('не трогает префикс внутри строки — только в начале', function () {
expect(SupplierProjectName::strip('foo B1_bar'))->toBe('foo B1_bar');
});
test('null сохраняет null, пустая строка — пустая (контракт API не ломаем)', function () {
expect(SupplierProjectName::strip(null))->toBeNull();
expect(SupplierProjectName::strip(''))->toBe('');
});