Bicycle/tests/Unit/ValidationTest.php
Egor Isaev e6e8844f2b dev
2026-06-23 14:17:26 +03:00

212 lines
7.2 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
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use System\Classes\MyException;
use System\Classes\Validation;
class ValidationTest extends TestCase
{
public function testValidDataPasses(): void
{
$v = Validation::factory(['email' => 'a@b.com', 'age' => '20'])
->rule('email', 'email')
->rule('age', 'digit');
$this->assertTrue($v->check());
$this->assertSame([], $v->errors());
}
public function testRequiredFailsOnEmpty(): void
{
$v = Validation::factory(['name' => ''])->rule('name', 'required');
$this->assertFalse($v->check());
$this->assertArrayHasKey('name', $v->errors());
}
public function testRequiredFailsOnMissingKey(): void
{
$v = Validation::factory([])->rule('name', 'required');
$this->assertFalse($v->check());
$this->assertArrayHasKey('name', $v->errors());
}
public function testEmptyOptionalFieldSkipsOtherRules(): void
{
// Поле пустое, но required нет — email-правило не должно срабатывать.
$v = Validation::factory(['email' => ''])->rule('email', 'email');
$this->assertTrue($v->check());
$this->assertSame([], $v->errors());
}
public function testStopsAtFirstErrorPerField(): void
{
// required и email оба провалились бы, но сообщение должно быть от required.
$v = Validation::factory(['email' => ''])
->rule('email', 'required')
->rule('email', 'email');
$this->assertFalse($v->check());
$this->assertStringContainsString('обязательно', $v->error('email'));
}
public function testEmailRule(): void
{
$bad = Validation::factory(['email' => 'not-an-email'])->rule('email', 'email');
$this->assertFalse($bad->check());
$ok = Validation::factory(['email' => 'user@example.com'])->rule('email', 'email');
$this->assertTrue($ok->check());
}
public function testUrlRule(): void
{
$bad = Validation::factory(['site' => 'example'])->rule('site', 'url');
$this->assertFalse($bad->check());
$ok = Validation::factory(['site' => 'https://example.com'])->rule('site', 'url');
$this->assertTrue($ok->check());
}
public function testNumericRule(): void
{
$this->assertTrue(Validation::factory(['n' => '3.14'])->rule('n', 'numeric')->check());
$this->assertFalse(Validation::factory(['n' => '12abc'])->rule('n', 'numeric')->check());
}
public function testDigitRule(): void
{
$this->assertTrue(Validation::factory(['n' => '42'])->rule('n', 'digit')->check());
$this->assertFalse(Validation::factory(['n' => '3.14'])->rule('n', 'digit')->check());
}
public function testMinLengthRule(): void
{
$this->assertFalse(Validation::factory(['p' => '123'])->rule('p', 'min_length', [8])->check());
$this->assertTrue(Validation::factory(['p' => '12345678'])->rule('p', 'min_length', [8])->check());
}
public function testMaxLengthRule(): void
{
$this->assertFalse(Validation::factory(['p' => '123456'])->rule('p', 'max_length', [4])->check());
$this->assertTrue(Validation::factory(['p' => '1234'])->rule('p', 'max_length', [4])->check());
}
public function testExactLengthRule(): void
{
$this->assertTrue(Validation::factory(['code' => '1234'])->rule('code', 'exact_length', [4])->check());
$this->assertFalse(Validation::factory(['code' => '12345'])->rule('code', 'exact_length', [4])->check());
}
public function testMinLengthCountsMultibyte(): void
{
// 4 кириллических символа — должно проходить min_length(4).
$this->assertTrue(Validation::factory(['p' => 'тест'])->rule('p', 'min_length', [4])->check());
}
public function testMatchesRule(): void
{
$ok = Validation::factory(['pass' => 'secret', 'confirm' => 'secret'])
->rule('confirm', 'matches', ['pass']);
$this->assertTrue($ok->check());
$bad = Validation::factory(['pass' => 'secret', 'confirm' => 'other'])
->rule('confirm', 'matches', ['pass']);
$this->assertFalse($bad->check());
}
public function testInRule(): void
{
$ok = Validation::factory(['role' => 'admin'])
->rule('role', 'in', [['admin', 'user']]);
$this->assertTrue($ok->check());
$bad = Validation::factory(['role' => 'root'])
->rule('role', 'in', [['admin', 'user']]);
$this->assertFalse($bad->check());
}
public function testRegexRule(): void
{
$ok = Validation::factory(['slug' => 'hello-world'])
->rule('slug', 'regex', ['/^[a-z\-]+$/']);
$this->assertTrue($ok->check());
$bad = Validation::factory(['slug' => 'Hello World'])
->rule('slug', 'regex', ['/^[a-z\-]+$/']);
$this->assertFalse($bad->check());
}
public function testLabelAppearsInMessage(): void
{
$v = Validation::factory(['email' => 'bad'])
->label('email', 'E-mail')
->rule('email', 'email');
$v->check();
$this->assertStringContainsString('E-mail', $v->error('email'));
}
public function testMatchesMessageUsesParamLabel(): void
{
$v = Validation::factory(['pass' => 'a', 'confirm' => 'b'])
->label('pass', 'Пароль')
->rule('confirm', 'matches', ['pass']);
$v->check();
$this->assertStringContainsString('Пароль', $v->error('confirm'));
}
public function testParamPlaceholderInMessage(): void
{
$v = Validation::factory(['p' => '1'])->rule('p', 'min_length', [8]);
$v->check();
$this->assertStringContainsString('8', $v->error('p'));
}
public function testErrorReturnsNullForValidField(): void
{
$v = Validation::factory(['email' => 'a@b.com'])->rule('email', 'email');
$v->check();
$this->assertNull($v->error('email'));
}
public function testMultipleFieldsCollectErrors(): void
{
$v = Validation::factory(['email' => 'bad', 'age' => 'x'])
->rule('email', 'email')
->rule('age', 'digit');
$this->assertFalse($v->check());
$this->assertCount(2, $v->errors());
}
public function testFluentReturnsStatic(): void
{
$v = Validation::factory([]);
$this->assertSame($v, $v->rule('a', 'required'));
$this->assertSame($v, $v->label('a', 'A'));
}
public function testUnknownRuleThrows(): void
{
$this->expectException(MyException::class);
Validation::factory(['a' => 'x'])->rule('a', 'no_such_rule')->check();
}
public function testCheckIsRepeatableAndResetsErrors(): void
{
$v = Validation::factory(['email' => 'bad'])->rule('email', 'email');
$this->assertFalse($v->check());
$this->assertCount(1, $v->errors());
// Повторный вызов не накапливает ошибки.
$this->assertFalse($v->check());
$this->assertCount(1, $v->errors());
}
}