Passed
Push — master ( 74d060...d17a79 )
by Kirill
05:31 queued 10s
created

EntityCheckerTest::testCaseInsensitiveUnique()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Tests\Framework\Validation;
6
7
use Cycle\ORM\TransactionInterface;
8
use Spiral\Database\Database;
9
use Spiral\Database\DatabaseInterface;
10
use Spiral\App\TestApp;
11
use Spiral\App\User\User;
12
use Spiral\Tests\Framework\BaseTest;
13
use Spiral\Validation\ValidationInterface;
14
use Throwable;
15
16
class EntityCheckerTest extends BaseTest
17
{
18
    /** @var TestApp */
19
    private $app;
20
21
    public function setUp(): void
22
    {
23
        $this->app = $this->makeApp();
24
25
        /** @var Database $database */
26
        $database = $this->app->get(DatabaseInterface::class);
27
28
        $table = $database->table('users')->getSchema();
29
        $table->primary('id');
30
        $table->string('name');
31
        $table->save();
32
    }
33
34
    /**
35
     * @throws Throwable
36
     */
37
    public function testExistsByPK(): void
38
    {
39
        /** @var TransactionInterface $transaction */
40
        $transaction = $this->app->get(TransactionInterface::class);
41
        $transaction->persist(new User('Valentin'));
42
        $transaction->run();
43
44
        $this->assertFalse($this->exists(2));
45
        $this->assertTrue($this->exists(1));
46
    }
47
48
    public function testCaseInsensitiveExists(): void
49
    {
50
        $transaction = $this->app->get(TransactionInterface::class);
51
        $transaction->persist(new User('Valentin'));
52
        $transaction->run();
53
54
        $this->assertTrue($this->exists('vALenTIn', 'name', true));
55
        $this->assertFalse($this->exists('valentin', 'name', false));
56
    }
57
58
    /**
59
     * @throws Throwable
60
     */
61
    public function testExistsByField(): void
62
    {
63
        /** @var TransactionInterface $transaction */
64
        $transaction = $this->app->get(TransactionInterface::class);
65
        $transaction->persist(new User('Valentin'));
66
        $transaction->run();
67
68
        $this->assertFalse($this->exists('John', 'name'));
69
        $this->assertTrue($this->exists('Valentin', 'name'));
70
    }
71
72
    /**
73
     * @throws Throwable
74
     */
75
    public function testSimpleUnique(): void
76
    {
77
        /** @var TransactionInterface $transaction */
78
        $transaction = $this->app->get(TransactionInterface::class);
79
        $transaction->persist(new User('Valentin'));
80
        $transaction->persist(new User('Anton'));
81
        $transaction->run();
82
83
        $this->assertTrue($this->isUnique('John', 'name'));
84
        $this->assertFalse($this->isUnique('Valentin', 'name'));
85
    }
86
87
    public function testCaseInsensitiveUnique(): void
88
    {
89
        $transaction = $this->app->get(TransactionInterface::class);
90
        $transaction->persist(new User('Valentin'));
91
        $transaction->run();
92
93
        $this->assertFalse($this->isUnique('vaLeNtIN', 'name', [], null, [], true));
94
        $this->assertTrue($this->isUnique('vaLeNtIN', 'name'));
95
    }
96
97
    /**
98
     * @throws Throwable
99
     */
100
    public function testContextualUnique(): void
101
    {
102
        $user1 = new User('Valentin');
103
        $user2 = new User('Anton');
104
        $user3 = new User('John');
105
106
        /** @var TransactionInterface $transaction */
107
        $transaction = $this->app->get(TransactionInterface::class);
108
        $transaction->persist($user1);
109
        $transaction->persist($user2);
110
        $transaction->persist($user3);
111
        $transaction->run();
112
113
        //context match
114
        $this->assertTrue($this->isUnique('Valentin', 'name', [], $user1));
115
        $this->assertTrue($this->isUnique('Valentin', 'name', [], $user1, ['id']));
116
        $this->assertTrue($this->isUnique('Valentin', 'name', ['id' => 1], $user1, ['id']));
117
118
        //context mismatch, unique in db
119
        $this->assertTrue($this->isUnique('Valentin', 'name', ['id' => 2], $user1, ['id']));
120
        $this->assertTrue($this->isUnique('Valentin', 'name', ['id' => 2], $user3, ['id']));
121
122
        //context mismatch, not unique in db
123
        $this->assertFalse($this->isUnique('Valentin', 'name', [], $user2));
124
        $this->assertFalse($this->isUnique('Valentin', 'name', [], $user2, ['id']));
125
    }
126
127
    /**
128
     * @param mixed       $value
129
     * @param string|null $field
130
     * @param bool        $ignoreCase
131
     * @return bool
132
     */
133
    private function exists($value, ?string $field = null, bool $ignoreCase = false): bool
134
    {
135
        /** @var ValidationInterface $validator */
136
        $validator = $this->app->get(ValidationInterface::class);
137
        $validator = $validator->validate(
138
            ['value' => $value],
139
            ['value' => [['entity::exists', User::class, $field, $ignoreCase]]]
140
        );
141
142
        return $validator->isValid();
143
    }
144
145
    /**
146
     * @param string      $value
147
     * @param string      $field
148
     * @param array       $data
149
     * @param object|null $context
150
     * @param string[]    $fields
151
     * @param bool        $ignoreCase
152
     * @return bool
153
     */
154
    private function isUnique(
155
        string $value,
156
        string $field,
157
        array $data = [],
158
        ?object $context = null,
159
        array $fields = [],
160
        bool $ignoreCase = false
161
    ): bool {
162
        /** @var ValidationInterface $validator */
163
        $validator = $this->app->get(ValidationInterface::class);
164
        $validator = $validator->validate(
165
            ['value' => $value] + $data,
166
            ['value' => [['entity::unique', User::class, $field, $fields, $ignoreCase]]]
167
        );
168
        if ($context !== null) {
169
            $validator = $validator->withContext($context);
170
        }
171
172
        return $validator->isValid();
173
    }
174
}
175