Completed
Push — master ( 57bfac...8ddd4e )
by Craig
13:34 queued 07:58
created

UserCreationApiTest::createEncoderFactory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 11
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\ZAuthModule\Tests\Api;
15
16
use Doctrine\Persistence\ManagerRegistry;
17
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
18
use Symfony\Component\Dotenv\Dotenv;
19
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
20
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
21
use Symfony\Component\Validator\ConstraintViolationList;
22
use Zikula\ExtensionsModule\Api\ApiInterface\VariableApiInterface;
23
use Zikula\GroupsModule\Constant as GroupsConstant;
24
use Zikula\GroupsModule\Entity\GroupEntity;
25
use Zikula\GroupsModule\Entity\RepositoryInterface\GroupRepositoryInterface;
26
use Zikula\UsersModule\Api\ApiInterface\CurrentUserApiInterface;
27
use Zikula\UsersModule\Constant as UsersConstant;
28
use Zikula\UsersModule\Entity\UserEntity;
29
use Zikula\ZAuthModule\Api\ApiInterface\UserCreationApiInterface;
30
use Zikula\ZAuthModule\Api\UserCreationApi;
31
use Zikula\ZAuthModule\Entity\AuthenticationMappingEntity;
32
use Zikula\ZAuthModule\ZAuthConstant;
33
34
class UserCreationApiTest extends KernelTestCase
35
{
36
    /**
37
     * @var UserCreationApiInterface
38
     */
39
    private $api;
40
41
    protected function setUp(): void
42
    {
43
        // load test env vars
44
        $dotenv = new Dotenv();
45
        $dotenv->load('.env.test');
46
47
        self::bootKernel();
48
        $container = self::$container;
49
        $validator = $container->get('validator');
50
51
        $currentUserApi = $this->createMock(CurrentUserApiInterface::class);
52
        $currentUserApi->method('get')->willReturn(UsersConstant::USER_ID_ADMIN);
53
        $encoder = $this->createPasswordEncoder();
54
        $encoderFactory = $this->createEncoderFactory($encoder);
55
        $managerRegistry = $this->createMock(ManagerRegistry::class);
56
        $variableApi = $this->createMock(VariableApiInterface::class);
57
        $variableApi->method('get')->willReturn(ZAuthConstant::DEFAULT_EMAIL_VERIFICATION_REQUIRED);
58
        $groupRepository = $this->createMock(GroupRepositoryInterface::class);
59
        $groupRepository->method('findAllAndIndexBy')->willReturn($this->createGroups());
60
        $this->api = new UserCreationApi(
61
            $validator,
0 ignored issues
show
Bug introduced by
It seems like $validator can also be of type null; however, parameter $validator of Zikula\ZAuthModule\Api\U...ationApi::__construct() does only seem to accept Symfony\Component\Valida...ator\ValidatorInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
            /** @scrutinizer ignore-type */ $validator,
Loading history...
62
            $currentUserApi,
63
            $encoderFactory,
64
            $managerRegistry,
65
            $variableApi,
66
            $groupRepository
67
        );
68
    }
69
70
    /**
71
     * @dataProvider isValidUserDataProvider
72
     */
73
    public function testIsValidUserData($expected, array $user): void
74
    {
75
        $this->assertEquals($expected, $this->api->isValidUserData($user));
76
    }
77
78
    public function testIsValidUserDataArray(): void
79
    {
80
        $users = $this->getValidUsersArray();
81
        $errors = $this->api->isValidUserDataArray($users);
82
        $this->assertTrue($errors);
83
84
        $users = $this->getInvalidUsersArray();
85
        $errors = $this->api->isValidUserDataArray($users);
86
        $this->assertNotTrue($errors);
87
        $this->assertInstanceOf(ConstraintViolationList::class, $errors);
88
        $this->assertEquals(4, $errors->count());
89
        $this->assertEquals('This value is not a valid email address.', $errors[0]->getMessage());
90
        $this->assertEquals('This value is too short. It should have 5 characters or more.', $errors[1]->getMessage());
91
        $this->assertEquals('The value you selected is not a valid choice.', $errors[2]->getMessage());
92
        $this->assertEquals('This value is not valid.', $errors[3]->getMessage());
93
    }
94
95
    public function testCreateUser(): void
96
    {
97
        $this->api->createUser([
98
            'uname' => 'foo',
99
            'email' => '[email protected]',
100
            'pass' => '12345678'
101
        ]);
102
103
        $users = $this->api->getCreatedUsers();
104
        $hash = array_key_first($users);
105
        /** @var UserEntity $newUser */
106
        $newUser = $users[$hash];
107
        $this->assertEquals('foo', $newUser->getUname());
108
        $this->assertEquals('[email protected]', $newUser->getEmail());
109
        $this->assertEquals(1, $newUser->getActivated());
110
        $this->assertEquals(1, $newUser->getGroups()->count());
111
        $this->assertEquals(null, $newUser->getUid());
112
113
        $mappings = $this->api->getCreatedMappings();
114
        $this->assertArrayHasKey($hash, $mappings);
115
        /** @var AuthenticationMappingEntity $newMapping */
116
        $newMapping = $mappings[$hash];
117
        $this->assertEquals('foo', $newMapping->getUname());
118
        $this->assertEquals('[email protected]', $newMapping->getEmail());
119
        $this->assertEquals('thisIsAnEncodedPassword!', $newMapping->getPass());
120
        $this->assertEquals(ZAuthConstant::AUTHENTICATION_METHOD_EITHER, $newMapping->getMethod());
121
        $this->assertNotEquals(ZAuthConstant::DEFAULT_EMAIL_VERIFICATION_REQUIRED, $newMapping->isVerifiedEmail());
122
    }
123
124
    public function testCreateUsers(): void
125
    {
126
        $users = $this->getValidUsersArray();
127
        $errors = $this->api->createUsers($users);
128
        $this->assertCount(0, $errors);
129
        $this->assertCount(10, $this->api->getCreatedUsers());
130
        $this->assertCount(10, $this->api->getCreatedMappings());
131
132
        $this->api->clearCreated();
133
        $users = $this->getInvalidUsersArray();
134
        $errors = $this->api->createUsers($users);
135
        $this->assertCount(4, $errors);
136
        $this->assertCount(6, $this->api->getCreatedUsers());
137
        $this->assertCount(6, $this->api->getCreatedMappings());
138
        $this->assertEquals('Row 0 with email `foo0@bar` and uname `foo0` is invalid and was rejected.', $errors[0]);
139
        $this->assertEquals('Row 2 with email `[email protected]` and uname `foo2` is invalid and was rejected.', $errors[1]);
140
        $this->assertEquals('Row 3 with email `[email protected]` and uname `foo3` is invalid and was rejected.', $errors[2]);
141
        $this->assertEquals('Row 9 with email `[email protected]` and uname `foo9` is invalid and was rejected.', $errors[3]);
142
    }
143
144
    public function isValidUserDataProvider()
145
    {
146
        return [
147
            ['This field is missing.', []],
148
            ['This field is missing.', ['uname' => 'foo', 'pass' => '12345678']],
149
            ['This field is missing.', ['uname' => 'foo', 'pass' => '12345678', 'bar' => 'foo']],
150
            ['This field is missing.', ['uname' => 'foo', 'email' => '[email protected]']],
151
            ['This value is not a valid email address.', ['uname' => 'foo', 'pass' => '12345678', 'email' => 'foo']],
152
            ['This value should not be blank.', ['uname' => '', 'pass' => '12345678', 'email' => '[email protected]']],
153
            ['This value is too short. It should have 5 characters or more.', ['uname' => 'foo', 'pass' => '123', 'email' => '[email protected]']],
154
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]']],
155
156
            ['The value you selected is not a valid choice.', ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 2]],
157
            ['The value you selected is not a valid choice.', ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => '2']],
158
            ['This value should be of type numeric.', ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 'foo']],
159
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => '1']],
160
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 0]],
161
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 1]],
162
            ['The value you selected is not a valid choice.', ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => 2]],
163
            ['The value you selected is not a valid choice.', ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => '2']],
164
            ['This value should be of type numeric.', ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => 'foo']],
165
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => '1']],
166
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => 0]],
167
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => 1]],
168
            ['This value should be of type string.', ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'groups' => 1]],
169
            ['This value is not valid.', ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'groups' => 'users']],
170
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'groups' => '1']],
171
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'groups' => '1|2|3']],
172
173
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => '1', 'sendmail' => '1', 'groups' => '1']],
174
            [true, ['uname' => 'foo', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 1, 'sendmail' => 1, 'groups' => '1|2|12345']],
175
        ];
176
    }
177
178
    private function getValidUsersArray(): array
179
    {
180
        return [
181
            ['uname' => 'foo0', 'pass' => '12345678', 'email' => '[email protected]'],
182
            ['uname' => 'foo1', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => '1'],
183
            ['uname' => 'foo2', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 0],
184
            ['uname' => 'foo3', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 1],
185
            ['uname' => 'foo4', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => '1'],
186
            ['uname' => 'foo5', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => 1],
187
            ['uname' => 'foo6', 'pass' => '12345678', 'email' => '[email protected]', 'groups' => '1|57'],
188
            ['uname' => 'foo7', 'pass' => '12345678', 'email' => '[email protected]', 'groups' => '1|2'],
189
            ['uname' => 'foo8', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => '1', 'sendmail' => '1', 'groups' => '1'],
190
            ['uname' => 'foo9', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 1, 'sendmail' => 1, 'groups' => '1|2|3'],
191
        ];
192
    }
193
194
    private function getInvalidUsersArray(): array
195
    {
196
        return [
197
            ['uname' => 'foo0', 'pass' => '12345678', 'email' => 'foo0@bar'], // invalid
198
            ['uname' => 'foo1', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => '1'],
199
            ['uname' => 'foo2', 'pass' => '123', 'email' => '[email protected]', 'activated' => 0], // invalid
200
            ['uname' => 'foo3', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 9], // invalid
201
            ['uname' => 'foo4', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => '1'],
202
            ['uname' => 'foo5', 'pass' => '12345678', 'email' => '[email protected]', 'sendmail' => 1],
203
            ['uname' => 'foo6', 'pass' => '12345678', 'email' => '[email protected]', 'groups' => '1|57'],
204
            ['uname' => 'foo7', 'pass' => '12345678', 'email' => '[email protected]', 'groups' => '1|2'],
205
            ['uname' => 'foo8', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => '1', 'sendmail' => '1', 'groups' => '1'],
206
            ['uname' => 'foo9', 'pass' => '12345678', 'email' => '[email protected]', 'activated' => 1, 'sendmail' => 1, 'groups' => 'users'], // invalid
207
        ];
208
    }
209
210
    protected function createPasswordEncoder($isPasswordValid = true)
211
    {
212
        $mock = $this->getMockBuilder(PasswordEncoderInterface::class)->getMock();
213
        $mock->method('encodePassword')->willReturn('thisIsAnEncodedPassword!');
214
215
        return $mock;
216
    }
217
218
    protected function createEncoderFactory($encoder = null)
219
    {
220
        $mock = $this->getMockBuilder(EncoderFactoryInterface::class)->getMock();
221
222
        $mock
223
            ->expects($this->any())
224
            ->method('getEncoder')
225
            ->willReturn($encoder)
226
        ;
227
228
        return $mock;
229
    }
230
231
    protected function createGroups(): array
232
    {
233
        $records = [
234
            [
235
                'gid' => GroupsConstant::GROUP_ID_USERS,
236
                'name' => 'Users',
237
                'description' => 'By default, all users are made members of this group.'
238
            ],
239
            [
240
                'gid' => GroupsConstant::GROUP_ID_ADMIN,
241
                'name' => 'Administrators',
242
                'description' => 'Group of administrators of this site.',
243
            ]
244
        ];
245
246
        $groups = [];
247
        foreach ($records as $record) {
248
            $group = new GroupEntity();
249
            $group->setGid($record['gid']);
250
            $group->setName($record['name']);
251
            $group->setDescription($record['description']);
252
            $groups[$record['gid']] = $group;
253
        }
254
255
        return $groups;
256
    }
257
}
258