Files
portal/app/tests/Feature/Rules/SignalValidatorsTest.php
T
Дмитрий 44a1b21421 feat(rules): add Signal validators (Domain, Phone, SmsSender) with comprehensive datasets
- app/Rules/SignalIdentifier/DomainIdentifier.php — regex
  ^[a-z0-9-]+(\.[a-z0-9-]+)+$ (нижний регистр, без протокола/пути).
- app/Rules/SignalIdentifier/PhoneIdentifier.php — regex ^7\d{10}$
  (11 цифр, начинается с 7).
- app/Rules/SignalIdentifier/SmsSenderRule.php — 1-30 символов
  [A-Za-z0-9_-]; отвергает 11-значные номера (поставщик блокирует
  физический телефон в роли отправителя — alert "Важно!" в форме
  создания SMS-проекта).
- tests/Feature/Rules/SignalValidatorsTest.php — 24 теста с datasets:
  • Domain: 4 valid + 6 invalid (case, no-TLD, spaces, protocol, path, double-dot)
  • Phone: 3 valid + 6 invalid (8-prefix, length, plus, spaces, letters)
  • SmsSender: alpha+numeric short, 11-digit blocked, length>30 blocked,
    empty (с required), special chars blocked

Quirk: Laravel skips non-implicit rules для пустых строк. Тест empty
использует связку 'required' + правило (как в реальном FormRequest).

Pest: 499 / 497 passed / 2 skipped (473 + 24 новых = 497).
Larastan: 0 errors. Pint passed.

Spec: §3.1
Plan: Task 12

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 17:05:19 +03:00

94 lines
3.4 KiB
PHP
Raw 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.
<?php
declare(strict_types=1);
use App\Rules\SignalIdentifier\DomainIdentifier;
use App\Rules\SignalIdentifier\PhoneIdentifier;
use App\Rules\SignalIdentifier\SmsSenderRule;
use Illuminate\Support\Facades\Validator;
dataset('domains_valid', [
['example.com'],
['vashinvestor.ru'],
['sub.example.co.uk'],
['site-with-dash.ru'],
]);
dataset('domains_invalid', [
['EXAMPLE.COM'], // верхний регистр
['no-tld'], // без точки
['has spaces.com'],
['http://example.com'], // с протоколом
['example.com/path'], // с путём
['example..com'], // двойная точка
]);
test('DomainIdentifier accepts valid', function (string $value) {
$v = Validator::make(['x' => $value], ['x' => [new DomainIdentifier]]);
expect($v->fails())->toBeFalse("rejected valid {$value}");
})->with('domains_valid');
test('DomainIdentifier rejects invalid', function (string $value) {
$v = Validator::make(['x' => $value], ['x' => [new DomainIdentifier]]);
expect($v->fails())->toBeTrue("accepted invalid {$value}");
})->with('domains_invalid');
dataset('phones_valid', [
['79991234567'],
['74955551212'],
['78001234567'],
]);
dataset('phones_invalid', [
['89991234567'], // не 7 в начале
['7999123456'], // 10 цифр
['799912345678'], // 12 цифр
['+79991234567'], // плюс
['7 999 123 45 67'], // пробелы
['79991234abc'], // буквы
]);
test('PhoneIdentifier accepts valid', function (string $v) {
$val = Validator::make(['x' => $v], ['x' => [new PhoneIdentifier]]);
expect($val->fails())->toBeFalse();
})->with('phones_valid');
test('PhoneIdentifier rejects invalid', function (string $v) {
$val = Validator::make(['x' => $v], ['x' => [new PhoneIdentifier]]);
expect($val->fails())->toBeTrue();
})->with('phones_invalid');
test('SmsSenderRule accepts alpha and short numeric', function () {
foreach (['TINKOFF', 'SBER', '900', '1234', 'BANK-1', 'alfa_bank'] as $v) {
$r = Validator::make(['x' => $v], ['x' => [new SmsSenderRule]]);
expect($r->fails())->toBeFalse("rejected valid {$v}");
}
});
test('SmsSenderRule rejects 11-digit phone (supplier blocks it)', function () {
foreach (['79991234567', '12345678901'] as $v) {
$r = Validator::make(['x' => $v], ['x' => [new SmsSenderRule]]);
expect($r->fails())->toBeTrue("accepted invalid {$v}");
}
});
test('SmsSenderRule rejects too long', function () {
$longString = str_repeat('A', 31);
$r = Validator::make(['x' => $longString], ['x' => [new SmsSenderRule]]);
expect($r->fails())->toBeTrue();
});
test('SmsSenderRule combined with required rejects empty string', function () {
// Laravel skips non-implicit rules для пустых строк; в реальном FormRequest
// signal-поля будут обязательными — проверяем связку 'required' + наша rule.
$r = Validator::make(['x' => ''], ['x' => ['required', new SmsSenderRule]]);
expect($r->fails())->toBeTrue();
});
test('SmsSenderRule rejects special chars', function () {
foreach (['SBER!', 'a@b', 'with space', 'punto.ru'] as $v) {
$r = Validator::make(['x' => $v], ['x' => [new SmsSenderRule]]);
expect($r->fails())->toBeTrue("accepted invalid {$v}");
}
});