44a1b21421
- 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>
94 lines
3.4 KiB
PHP
94 lines
3.4 KiB
PHP
<?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}");
|
||
}
|
||
});
|