UserTest::testValidateCreatesOnlyOneValidator()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 14
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Service\Execute;
6
7
use AbterPhp\Admin\Domain\Entities\User as Entity;
8
use AbterPhp\Admin\Orm\UserRepo as GridRepo;
9
use AbterPhp\Admin\Validation\Factory\User as ValidatorFactory;
10
use AbterPhp\Framework\Crypto\Crypto;
11
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
12
use Opulence\Events\Dispatchers\IEventDispatcher;
13
use Opulence\Orm\IUnitOfWork;
14
use Opulence\Validation\IValidator;
15
use Opulence\Validation\Rules\Errors\ErrorCollection;
16
use PHPUnit\Framework\MockObject\MockObject;
17
use PHPUnit\Framework\TestCase;
18
19
class UserTest extends TestCase
20
{
21
    /** @var User - System Under Test */
22
    protected $sut;
23
24
    /** @var GridRepo|MockObject */
25
    protected $gridRepoMock;
26
27
    /** @var ValidatorFactory|MockObject */
28
    protected $validatorFactoryMock;
29
30
    /** @var IUnitOfWork|MockObject */
31
    protected $unitOfWorkMock;
32
33
    /** @var IEventDispatcher|MockObject */
34
    protected $eventDispatcherMock;
35
36
    /** @var Crypto|MockObject */
37
    protected $cryptoMock;
38
39
    public function setUp(): void
40
    {
41
        parent::setUp();
42
43
        $this->gridRepoMock                = $this->createMock(GridRepo::class);
44
        $this->validatorFactoryMock        = $this->createMock(ValidatorFactory::class);
45
        $this->unitOfWorkMock              = $this->createMock(IUnitOfWork::class);
46
        $this->eventDispatcherMock         = $this->createMock(IEventDispatcher::class);
47
        $this->cryptoMock                  = $this->createMock(Crypto::class);
48
49
        $this->sut = new User(
50
            $this->gridRepoMock,
51
            $this->validatorFactoryMock,
52
            $this->unitOfWorkMock,
53
            $this->eventDispatcherMock,
54
            $this->cryptoMock
55
        );
56
    }
57
58
    public function testCreateMinimal()
59
    {
60
        $postData = [
61
            'username' => '',
62
            'password' => '',
63
            'email'    => '',
64
        ];
65
66
        $this->gridRepoMock->expects($this->once())->method('add');
67
        $this->eventDispatcherMock->expects($this->atLeastOnce())->method('dispatch');
68
        $this->unitOfWorkMock->expects($this->once())->method('commit');
69
70
        /** @var IStringerEntity|Entity $actualResult */
71
        $actualResult = $this->sut->create($postData, []);
72
73
        $this->assertInstanceOf(Entity::class, $actualResult);
74
        $this->assertEmpty($actualResult->getId());
75
        $this->assertSame('', $actualResult->getPassword());
76
        $this->assertFalse($actualResult->canLogin());
77
        $this->assertFalse($actualResult->isGravatarAllowed());
78
        $this->assertSame('', $actualResult->getUserLanguage()->getId());
79
        $this->assertCount(0, $actualResult->getUserGroups());
80
    }
81
82
    public function testCreate()
83
    {
84
        $username       = 'Foo';
85
        $email          = '[email protected]';
86
        $userLanguageId = 'ul-1';
87
        $userGroupIds   = ['ug-1', 'ug-2'];
88
        $postData       = [
89
            'username'            => $username,
90
            'password'            => '',
91
            'email'               => $email,
92
            'is_gravatar_allowed' => true,
93
            'can_login'           => true,
94
            'user_language_id'    => $userLanguageId,
95
            'user_group_ids'      => $userGroupIds,
96
        ];
97
98
        $this->gridRepoMock->expects($this->once())->method('add');
99
        $this->eventDispatcherMock->expects($this->atLeastOnce())->method('dispatch');
100
        $this->unitOfWorkMock->expects($this->once())->method('commit');
101
102
        /** @var IStringerEntity|Entity $actualResult */
103
        $actualResult = $this->sut->create($postData, []);
104
105
        $this->assertInstanceOf(Entity::class, $actualResult);
106
        $this->assertEmpty($actualResult->getId());
107
        $this->assertTrue($actualResult->canLogin());
108
        $this->assertTrue($actualResult->isGravatarAllowed());
109
        $this->assertSame($userLanguageId, $actualResult->getUserLanguage()->getId());
110
        $this->assertCount(2, $actualResult->getUserGroups());
111
    }
112
113
    public function testCreateWithPassword()
114
    {
115
        $password       = 'foo';
116
        $hashedPassword = 'foo-hashed';
117
        $postData       = [
118
            'username'         => '',
119
            'password'         => $password,
120
            'email'            => '',
121
            'user_language_id' => '',
122
            'user_group_ids'   => '',
123
        ];
124
125
        $this->gridRepoMock->expects($this->once())->method('add');
126
        $this->eventDispatcherMock->expects($this->atLeastOnce())->method('dispatch');
127
        $this->unitOfWorkMock->expects($this->once())->method('commit');
128
        $this->cryptoMock->expects($this->once())->method('hashCrypt')->with($password)->willReturn($hashedPassword);
129
130
        /** @var IStringerEntity|Entity $actualResult */
131
        $actualResult = $this->sut->create($postData, []);
132
133
        $this->assertInstanceOf(Entity::class, $actualResult);
134
        $this->assertEmpty($actualResult->getId());
135
        $this->assertSame($hashedPassword, $actualResult->getPassword());
136
    }
137
138
    public function testUpdate()
139
    {
140
        $id     = 'foo';
141
        $entity = $this->sut->createEntity($id);
142
143
        $username       = 'Foo';
144
        $email          = '[email protected]';
145
        $userLanguageId = 'ul-1';
146
        $userGroupIds   = ['ug-1', 'ug-2'];
147
        $postData       = [
148
            'username'            => $username,
149
            'password'            => '',
150
            'email'               => $email,
151
            'is_gravatar_allowed' => '1',
152
            'can_login'           => '1',
153
            'user_language_id'    => $userLanguageId,
154
            'user_group_ids'      => $userGroupIds,
155
        ];
156
157
        $this->gridRepoMock->expects($this->never())->method('add');
158
        $this->gridRepoMock->expects($this->never())->method('delete');
159
        $this->eventDispatcherMock->expects($this->atLeastOnce())->method('dispatch');
160
        $this->unitOfWorkMock->expects($this->once())->method('commit');
161
162
        $actualResult = $this->sut->update($entity, $postData, []);
163
164
        $this->assertTrue($actualResult);
165
        $this->assertSame($id, $entity->getId());
166
        $this->assertTrue($entity->canLogin());
167
        $this->assertTrue($entity->isGravatarAllowed());
168
        $this->assertSame($userLanguageId, $entity->getUserLanguage()->getId());
169
        $this->assertCount(2, $entity->getUserGroups());
170
    }
171
172
    public function testDelete()
173
    {
174
        $id     = 'foo';
175
        $entity = $this->sut->createEntity($id);
176
177
        $this->gridRepoMock->expects($this->once())->method('delete');
178
        $this->eventDispatcherMock->expects($this->atLeastOnce())->method('dispatch');
179
        $this->unitOfWorkMock->expects($this->once())->method('commit');
180
181
        $actualResult = $this->sut->delete($entity);
182
183
        $this->assertTrue($actualResult);
184
    }
185
186
    public function testRetrieveEntity()
187
    {
188
        $id     = 'foo';
189
        $entity = $this->sut->createEntity($id);
190
191
        $this->gridRepoMock->expects($this->once())->method('getById')->willReturn($entity);
192
193
        $actualResult = $this->sut->retrieveEntity($id);
194
195
        $this->assertSame($entity, $actualResult);
196
    }
197
198
    public function testRetrieveList()
199
    {
200
        $offset     = 0;
201
        $limit      = 2;
202
        $orders     = [];
203
        $conditions = [];
204
        $params     = [];
205
206
        $id0            = 'foo';
207
        $entity0        = $this->sut->createEntity($id0);
208
        $id1            = 'bar';
209
        $entity1        = $this->sut->createEntity($id1);
210
        $expectedResult = [$entity0, $entity1];
211
212
        $this->gridRepoMock->expects($this->once())->method('getPage')->willReturn($expectedResult);
213
214
        $actualResult = $this->sut->retrieveList($offset, $limit, $orders, $conditions, $params);
215
216
        $this->assertSame($expectedResult, $actualResult);
217
    }
218
219
    public function testValidateFormSuccess()
220
    {
221
        $postData = ['foo' => 'bar'];
222
223
        $validatorMock = $this->createMock(IValidator::class);
224
        $validatorMock->expects($this->once())->method('isValid')->with($postData)->willReturn(true);
225
        $validatorMock->expects($this->never())->method('getErrors');
226
227
        $this->validatorFactoryMock->expects($this->once())->method('createValidator')->willReturn($validatorMock);
228
229
        $result = $this->sut->validateForm($postData);
230
231
        $this->assertSame([], $result);
232
    }
233
234
    public function testValidateFormFailure()
235
    {
236
        $postData = ['foo' => 'bar'];
237
238
        $errorsStub        = new ErrorCollection();
239
        $errorsStub['foo'] = ['foo error'];
240
241
        $validatorMock = $this->createMock(IValidator::class);
242
        $validatorMock->expects($this->once())->method('isValid')->with($postData)->willReturn(false);
243
        $validatorMock->expects($this->once())->method('getErrors')->willReturn($errorsStub);
244
245
        $this->validatorFactoryMock->expects($this->once())->method('createValidator')->willReturn($validatorMock);
246
247
        $result = $this->sut->validateForm($postData);
248
249
        $this->assertSame(['foo' => ['foo error']], $result);
250
    }
251
252
    public function testValidateCreatesOnlyOneValidator()
253
    {
254
        $postData = ['foo' => 'bar'];
255
256
        $validatorMock = $this->createMock(IValidator::class);
257
        $validatorMock->expects($this->any())->method('isValid')->with($postData)->willReturn(true);
258
        $validatorMock->expects($this->any())->method('getErrors');
259
260
        $this->validatorFactoryMock->expects($this->once())->method('createValidator')->willReturn($validatorMock);
261
262
        $firstRun  = $this->sut->validateForm($postData);
263
        $secondRun = $this->sut->validateForm($postData);
264
265
        $this->assertSame($firstRun, $secondRun);
266
    }
267
}
268