packages/ztd-query-core/tests/Unit/Shadow/Mutation/Row/MultiUpdateMutationTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation\Row;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Shadow\Mutation\Row\MultiTableMutationRow;
11use ZtdQuery\Shadow\Mutation\Row\MultiTableMutationTarget;
12use ZtdQuery\Shadow\Mutation\Row\MultiUpdateMutation;
13use ZtdQuery\Shadow\ShadowStore;
14
15#[UsesClass(ShadowStore::class)]
16#[UsesClass(MultiTableMutationRow::class)]
17#[UsesClass(MultiTableMutationTarget::class)]
18#[CoversClass(MultiUpdateMutation::class)]
19#[UsesClass(\ZtdQuery\Shadow\Row\RowMatch::class)]
20#[UsesClass(\ZtdQuery\Schema\RowSet::class)]
21final class MultiUpdateMutationTest extends TestCase
22{
23 public function testApplyUpdatesMultipleTables(): void
24 {
25 $store = new ShadowStore();
26 $store->set('users', [
27 ['id' => 1, 'name' => 'Alice', 'status' => 'active'],
28 ['id' => 2, 'name' => 'Bob', 'status' => 'active'],
29 ]);
30 $store->set('profiles', [
31 ['user_id' => 1, 'verified' => false],
32 ['user_id' => 2, 'verified' => false],
33 ]);
34
35 $mutation = new MultiUpdateMutation([
36 new MultiTableMutationTarget('users', ['id', 'name', 'status'], ['id']),
37 new MultiTableMutationTarget('profiles', ['user_id', 'verified'], ['user_id']),
38 ]);
39
40 $mutation->apply($store, [
41 [
42 '__ztd_multi_0_value_0' => 1,
43 '__ztd_multi_0_value_1' => 'Alice Updated',
44 '__ztd_multi_0_value_2' => 'inactive',
45 '__ztd_multi_0_identity_0' => 1,
46 '__ztd_multi_1_value_0' => 1,
47 '__ztd_multi_1_value_1' => true,
48 '__ztd_multi_1_identity_0' => 1,
49 ],
50 ]);
51
52 self::assertSame('Alice Updated', $store->get('users')[0]['name']);
53 self::assertSame('inactive', $store->get('users')[0]['status']);
54 self::assertTrue($store->get('profiles')[0]['verified']);
55 }
56
57 public function testTableNameReturnsPrimaryTable(): void
58 {
59 $mutation = new MultiUpdateMutation([
60 new MultiTableMutationTarget('users', ['id'], ['id']),
61 new MultiTableMutationTarget('profiles', ['user_id'], ['user_id']),
62 ]);
63
64 self::assertSame('users', $mutation->tableName());
65 }
66
67 public function testTableNamesReturnsAllTableNames(): void
68 {
69 $mutation = new MultiUpdateMutation([
70 new MultiTableMutationTarget('users', ['id'], ['id']),
71 new MultiTableMutationTarget('profiles', ['user_id'], ['user_id']),
72 new MultiTableMutationTarget('settings', ['user_id'], ['user_id']),
73 ]);
74
75 self::assertSame(['users', 'profiles', 'settings'], $mutation->tableNames());
76 }
77
78 public function testApplyWithEmptyTablesReturnsEmptyPrimaryTable(): void
79 {
80 $mutation = new MultiUpdateMutation([]);
81
82 self::assertSame('', $mutation->tableName());
83 }
84
85 public function testApplyUpdatesMultipleRows(): void
86 {
87 $store = new ShadowStore();
88 $store->set('users', [
89 ['id' => 1, 'name' => 'Alice'],
90 ['id' => 2, 'name' => 'Bob'],
91 ['id' => 3, 'name' => 'Carol'],
92 ]);
93
94 $mutation = new MultiUpdateMutation([
95 new MultiTableMutationTarget('users', ['id', 'name'], ['id']),
96 ]);
97
98 $mutation->apply($store, [
99 [
100 '__ztd_multi_0_value_0' => 1,
101 '__ztd_multi_0_value_1' => 'Alice Updated',
102 '__ztd_multi_0_identity_0' => 1,
103 ],
104 [
105 '__ztd_multi_0_value_0' => 3,
106 '__ztd_multi_0_value_1' => 'Carol Updated',
107 '__ztd_multi_0_identity_0' => 3,
108 ],
109 ]);
110
111 self::assertSame('Alice Updated', $store->get('users')[0]['name']);
112 self::assertSame('Bob', $store->get('users')[1]['name']);
113 self::assertSame('Carol Updated', $store->get('users')[2]['name']);
114 }
115
116 public function testApplySkipsRowsWithIncompleteValuesOrIdentity(): void
117 {
118 $store = new ShadowStore();
119 $store->set('users', [['id' => 1, 'name' => 'Alice']]);
120 $mutation = new MultiUpdateMutation([
121 new MultiTableMutationTarget('users', ['id', 'name'], ['id']),
122 ]);
123
124 $mutation->apply($store, [
125 [
126 '__ztd_multi_0_identity_0' => 1,
127 ],
128 [
129 '__ztd_multi_0_value_0' => 1,
130 '__ztd_multi_0_value_1' => 'Incomplete',
131 ],
132 ]);
133
134 self::assertSame([['id' => 1, 'name' => 'Alice']], $store->get('users'));
135 }
136}
137