| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- <?php
- namespace Test\PhpDevCommunity\RequestKit;
- use DateTime;
- use PhpDevCommunity\RequestKit\Exceptions\InvalidDataException;
- use PhpDevCommunity\RequestKit\Schema\Schema;
- use PhpDevCommunity\RequestKit\Type;
- use PhpDevCommunity\UniTester\TestCase;
- class SchemaTest extends TestCase
- {
- private ?Schema $schema = null;
- protected function setUp(): void
- {
- $this->schema = Schema::create([
- 'name' => Type::string()->length(3, 100)->required(),
- 'age' => Type::int()->min(18)->max(99),
- 'email' => Type::email()->lowercase(),
- 'date_of_birth' => Type::date()->format('Y-m-d'),
- 'created_at' => Type::datetime()->format('Y-m-d H:i:s')->default(date('2025-01-01 12:00:00')),
- 'active' => Type::bool()->strict(),
- ]);
- }
- protected function tearDown(): void
- {
- // TODO: Implement tearDown() method.
- }
- protected function execute(): void
- {
- $this->testValidData();
- $this->testInvalidEmail();
- $this->testEdgeCaseAge();
- $this->testStrictBool();
- $this->testMissingOptionalField();
- $this->testMissingRequiredField();
- $this->testMultipleValidationErrors();
- $this->testNestedData();
- $this->testCollection();
- $this->testExtend();
- $this->testExampleData();
- }
- public function testValidData(): void
- {
- $data = [
- 'name' => 'John Doe',
- 'age' => 25,
- 'email' => 'JOHN@EXAMPLE.COM',
- 'date_of_birth' => '1990-01-01',
- 'created_at' => '2023-01-01 12:00:00',
- 'active' => true,
- ];
- $result = $this->schema->process($data);
- $result = $result->toArray();
- $this->assertStrictEquals($result['name'], 'John Doe');
- $this->assertStrictEquals($result['age'], 25);
- $this->assertStrictEquals($result['email'], 'john@example.com');
- $this->assertStrictEquals($result['date_of_birth']->format('Y-m-d'), '1990-01-01');
- $this->assertStrictEquals($result['created_at']->format('Y-m-d H:i:s'), '2023-01-01 12:00:00');
- $this->assertStrictEquals($result['active'], true);
- }
- public function testInvalidEmail(): void
- {
- $data = [
- 'name' => 'John Doe',
- 'age' => 25,
- 'email' => 'invalid-email', // Email invalide
- 'date_of_birth' => '1990-01-01',
- 'created_at' => '2023-01-01 12:00:00',
- 'active' => true,
- ];
- $this->expectException(InvalidDataException::class, function () use ($data) {
- try {
- $result = $this->schema->process($data);
- } catch (InvalidDataException $e) {
- $this->assertNotEmpty($e->getErrors());
- $this->assertEquals(1, count($e->getErrors()));
- $this->assertNotEmpty($e->getError('email'));
- throw $e;
- }
- });
- }
- public function testEdgeCaseAge(): void
- {
- $data = [
- 'name' => 'John Doe',
- 'age' => '18', // Âge limite
- 'email' => 'john@example.com',
- 'date_of_birth' => '1990-01-01',
- 'created_at' => '2023-01-01 12:00:00',
- 'active' => true,
- ];
- $result = $this->schema->process($data);
- $result = $result->toArray();
- $this->assertEquals(18, $result['age']);
- }
- public function testStrictBool(): void
- {
- $data = [
- 'name' => 'John Doe',
- 'age' => 25,
- 'email' => 'john@example.com',
- 'date_of_birth' => '1990-01-01',
- 'created_at' => '2023-01-01 12:00:00',
- 'active' => 1, //
- ];
- $this->expectException(InvalidDataException::class, function () use ($data) {
- try {
- $result = $this->schema->process($data);
- } catch (InvalidDataException $e) {
- $this->assertNotEmpty($e->getErrors());
- $this->assertEquals(1, count($e->getErrors()));
- $this->assertNotEmpty($e->getError('active'));
- throw $e;
- }
- });
- }
- public function testMissingOptionalField(): void
- {
- $data = [
- 'name' => 'John Doe',
- 'age' => 25,
- 'email' => 'john@example.com',
- 'date_of_birth' => '1990-01-01',
- // 'created_at'
- 'active' => true,
- ];
- $result = $this->schema->process($data);
- $result = $result->toArray();
- $this->assertInstanceOf(DateTime::class, $result['created_at']);
- }
- public function testMissingRequiredField(): void
- {
- $data = [
- // 'name' manquant
- 'age' => 25,
- 'email' => 'john@example.com',
- 'date_of_birth' => '1990-01-01',
- 'created_at' => '2023-01-01 12:00:00',
- 'active' => true,
- ];
- $this->expectException(InvalidDataException::class, function () use ($data) {
- try {
- $result = $this->schema->process($data);
- } catch (InvalidDataException $e) {
- $this->assertNotEmpty($e->getErrors());
- $this->assertEquals(1, count($e->getErrors()));
- $this->assertNotEmpty($e->getError('name'));
- throw $e;
- }
- });
- }
- public function testMultipleValidationErrors(): void
- {
- $data = [
- 'name' => 'John Doe',
- 'age' => 17, // Âge invalide
- 'email' => 'invalid-email', // Email invalide
- 'date_of_birth' => '1990-01-01',
- 'created_at' => '2023-01-01 12:00:00',
- 'active' => true,
- ];
- $this->expectException(InvalidDataException::class, function () use ($data) {
- try {
- $result = $this->schema->process($data);
- } catch (InvalidDataException $e) {
- $this->assertNotEmpty($e->getErrors());
- $this->assertEquals(2, count($e->getErrors()));
- $this->assertNotEmpty($e->getError('age'));
- $this->assertNotEmpty($e->getError('email'));
- throw $e;
- }
- });
- }
- public function testNestedData(): void
- {
- $schema = Schema::create([
- 'user' => Type::item([
- 'name' => Type::string()->length(20, 50)->required(),
- 'age' => Type::int()->strict()->alias('my_age'),
- 'roles' => Type::arrayOf(Type::string()->strict())->required(),
- 'address' => Type::item([
- 'street' => Type::string()->length(15, 100),
- 'city' => Type::string()->allowed('Paris', 'London'),
- ]),
- ]),
- ]);
- $data = [
- 'user' => [
- // 'name' => 'John Doe',
- 'my_age' => '25',
- // 'roles' => [
- // 1,
- // 2,
- // ],
- 'address' => [
- 'street' => 'Main Street',
- 'city' => 'New York',
- ]
- ],
- ];
- $this->expectException(InvalidDataException::class, function () use ($schema, $data) {
- try {
- $schema->process($data);
- } catch (InvalidDataException $e) {
- $this->assertNotEmpty($e->getErrors());
- $this->assertEquals(5, count($e->getErrors()));
- $this->assertNotEmpty($e->getError('user.name'));
- $this->assertNotEmpty($e->getError('user.age'));
- $this->assertNotEmpty($e->getError('user.address.street'));
- $this->assertNotEmpty($e->getError('user.address.city'));
- $this->assertNotEmpty($e->getError('user.roles'));
- throw $e;
- }
- });
- }
- public function testCollection(): void
- {
- $schema = Schema::create([
- 'users' => Type::arrayOf(Type::item([
- 'name' => Type::string()->length(3, 50)->required(),
- 'age' => Type::int(),
- 'roles' => Type::arrayOf(Type::string())->required(),
- 'address' => Type::item([
- 'street' => Type::string()->length(5, 100),
- 'city' => Type::string()->allowed('Paris', 'London'),
- ]),
- ])),
- ]);
- $data = [
- 'users' => [
- [
- 'name' => 'John Doe',
- 'age' => '25',
- 'roles' => [
- 1,
- 2,
- ],
- 'address' => [
- 'street' => 'Main Street',
- 'city' => 'London',
- ]
- ],
- [
- 'name' => 'Jane Doe',
- 'age' => '30',
- 'roles' => [
- 3,
- 4,
- ],
- 'address' => [
- 'street' => 'Main Street',
- 'city' => 'Paris',
- ]
- ],
- ]
- ];
- $result = $schema->process($data);
- $this->assertStrictEquals(2, count($result->get('users')));
- $this->assertStrictEquals('John Doe', $result->get('users.0.name'));
- $this->assertStrictEquals(25, $result->get('users.0.age'));
- $this->assertStrictEquals(2, count($result->get('users.0.roles')));
- $this->assertStrictEquals('Main Street', $result->get('users.0.address.street'));
- $this->assertStrictEquals('London', $result->get('users.0.address.city'));
- $this->assertStrictEquals('Jane Doe', $result->get('users.1.name'));
- $this->assertStrictEquals(30, $result->get('users.1.age'));
- $this->assertStrictEquals(2, count($result->get('users.1.roles')));
- $this->assertStrictEquals('Main Street', $result->get('users.1.address.street'));
- $this->assertStrictEquals('Paris', $result->get('users.1.address.city'));
- }
- private function testExtend()
- {
- $schema1 = Schema::create([
- 'name' => Type::string()->length(20, 50)->required(),
- 'age' => Type::int()->strict()->alias('my_age'),
- 'roles' => Type::arrayOf(Type::string()->strict())->required(),
- 'address' => Type::item([
- 'street' => Type::string()->length(15, 100),
- 'city' => Type::string()->allowed('Paris', 'London'),
- ]),
- ]);
- $schema2 = $schema1->extend([
- 'password' => Type::string()->length(10, 100),
- 'address' => Type::item([
- 'zip' => Type::string()->length(5, 10),
- ]),
- ]);
- $this->assertStrictEquals(5, count($schema2->copyDefinitions()));
- /**
- * @var Type\ItemType $address
- */
- $address = $schema2->copyDefinitions()['address'];
- $this->assertStrictEquals(1, count($address->copyDefinitions()));
- }
- private function testExampleData()
- {
- $schema1 = Schema::create([
- 'name' => Type::string()->length(20, 50)->required()->example('John Doe'),
- 'age' => Type::int()->strict()->alias('my_age')->example(20),
- 'roles' => Type::arrayOf(Type::string()->strict())->required()->example('admin'),
- 'address' => Type::item([
- 'street' => Type::string()->length(15, 100),
- 'city' => Type::string()->allowed('Paris', 'London'),
- ])->example([
- 'street' => 'Main Street',
- 'city' => 'London',
- ]
- ),
- ]);
- $this->assertEquals($schema1->generateExampleData(), [
- 'name' => 'John Doe',
- 'age' => 20,
- 'roles' => ['admin'],
- 'address' => [
- 'street' => 'Main Street',
- 'city' => 'London',
- ]
- ]);
- $schema2 = Schema::create([
- 'name' => Type::string()->length(20, 50)->required()->example('John Doe'),
- 'age' => Type::int()->strict()->alias('my_age')->example(20),
- 'roles' => Type::arrayOf(Type::string()->strict())->required()->example('admin'),
- 'address' => Type::item([
- 'street' => Type::string()->length(15, 100)->example('Main Street'),
- 'city' => Type::string()->allowed('Paris', 'London')->example('London'),
- ]),
- ]);
- $this->assertEquals($schema2->generateExampleData(), [
- 'name' => 'John Doe',
- 'age' => 20,
- 'roles' => ['admin'],
- 'address' => [
- 'street' => 'Main Street',
- 'city' => 'London',
- ]
- ]);
- }
- }
|