packages/ztd-query-core/tests/Unit/Shadow/Mutation/DataMutationTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation;
6
7use PHPUnit\Framework\Attributes\CoversNothing;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Schema\Key\ForeignKeyDefinition;
11use ZtdQuery\Schema\Key\ReferentialAction;
12use ZtdQuery\Schema\TableDefinition;
13use ZtdQuery\Schema\TableDefinitionRegistry;
14use ZtdQuery\Shadow\Mutation\Row\DeleteMutation;
15use ZtdQuery\Shadow\Mutation\Row\InsertMutation;
16use ZtdQuery\Shadow\Mutation\Row\MultiDeleteMutation;
17use ZtdQuery\Shadow\Mutation\Row\MultiUpdateMutation;
18use ZtdQuery\Shadow\Mutation\Row\ReplaceMutation;
19use ZtdQuery\Shadow\Mutation\Row\UpdateMutation;
20use ZtdQuery\Shadow\Mutation\ShadowMutation;
21use ZtdQuery\Shadow\Mutation\Table\CreateTableMutation;
22use ZtdQuery\Shadow\Mutation\Table\MultiTruncateMutation;
23use ZtdQuery\Shadow\Mutation\Table\SynchronizeMutation;
24use ZtdQuery\Shadow\Mutation\Table\TruncateMutation;
25use ZtdQuery\Shadow\Mutation\UpsertMutation;
26use ZtdQuery\Shadow\ReferentialIntegrityEnforcer;
27use ZtdQuery\Shadow\ShadowStore;
28
29#[CoversNothing]
30final class DataMutationTest extends TestCase
31{
32    #[DataProvider('providerRowChangingMutation')]
33    public function testAMutationThatChangesRowsCarriesItsConsequencesToTheChildren(
34        ShadowMutation $mutation,
35    ): void {
36        $registry = new TableDefinitionRegistry();
37        $registry->register('parents', new TableDefinition(['id'], [], ['id'], [], []));
38        $registry->register('children', new TableDefinition(['id', 'parent_id'], [], ['id'], [], [], foreignKeys: [
39            'fk' => new ForeignKeyDefinition(['parent_id'], 'parents', ['id'], ReferentialAction::Cascade),
40        ]));
41        $before = new ShadowStore();
42        $before->set('parents', [['id' => 1]]);
43        $before->set('children', [['id' => 10, 'parent_id' => 1]]);
44        $after = $before->snapshot();
45        $after->set('parents', []);
46
47        (new ReferentialIntegrityEnforcer($registry))->synchronize($before, $after, $mutation, [], 'SQL');
48
49        self::assertSame([], $after->get('children'));
50    }
51
52    /**
53     * @return iterable<string, array{ShadowMutation}>
54     */
55    public static function providerRowChangingMutation(): iterable
56    {
57        yield 'insert' => [new InsertMutation('parents')];
58        yield 'update' => [new UpdateMutation('parents', ['id'])];
59        yield 'delete' => [new DeleteMutation('parents', ['id'])];
60        yield 'replace' => [new ReplaceMutation('parents')];
61        yield 'upsert' => [new UpsertMutation('parents', ['id'])];
62        yield 'truncate' => [new TruncateMutation('parents')];
63        yield 'multi update' => [new MultiUpdateMutation([])];
64        yield 'multi delete' => [new MultiDeleteMutation([])];
65        yield 'multi truncate' => [new MultiTruncateMutation([])];
66        yield 'synchronize' => [new SynchronizeMutation('parents')];
67    }
68
69    public function testAMutationThatChangesNoRowsCarriesNothingToTheChildren(): void
70    {
71        $registry = new TableDefinitionRegistry();
72        $registry->register('parents', new TableDefinition(['id'], [], ['id'], [], []));
73        $registry->register('children', new TableDefinition(['id', 'parent_id'], [], ['id'], [], [], foreignKeys: [
74            'fk' => new ForeignKeyDefinition(['parent_id'], 'parents', ['id'], ReferentialAction::Cascade),
75        ]));
76        $before = new ShadowStore();
77        $before->set('parents', [['id' => 1]]);
78        $before->set('children', [['id' => 10, 'parent_id' => 1]]);
79        $after = $before->snapshot();
80        $after->set('parents', []);
81        $mutation = new CreateTableMutation(
82            'extra',
83            new TableDefinition(['id'], [], ['id'], [], []),
84            $registry,
85            'CREATE TABLE extra (id INT)',
86        );
87
88        (new ReferentialIntegrityEnforcer($registry))->synchronize($before, $after, $mutation, [], 'SQL');
89
90        self::assertSame([['id' => 10, 'parent_id' => 1]], $after->get('children'));
91    }
92}
93