Completed
Push — 6.7 ( 1ebb2e...08099f )
by André
15:31
created

BaseTest::createUser()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 14
nc 1
nop 3
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the BaseTest class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\API\Repository\Tests;
10
11
use EzSystems\EzPlatformSolrSearchEngine\Tests\SetupFactory\LegacySetupFactory as LegacySolrSetupFactory;
12
use PHPUnit_Framework_TestCase;
13
use eZ\Publish\API\Repository\Repository;
14
use eZ\Publish\API\Repository\Values\ValueObject;
15
use eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation;
16
use eZ\Publish\API\Repository\Values\User\Limitation\SubtreeLimitation;
17
use eZ\Publish\Core\REST\Client\Sessionable;
18
use DateTime;
19
use ArrayObject;
20
use Exception;
21
use PDOException;
22
23
/**
24
 * Base class for api specific tests.
25
 */
26
abstract class BaseTest extends PHPUnit_Framework_TestCase
27
{
28
    /**
29
     * Maximum integer number accepted by the different backends.
30
     */
31
    const DB_INT_MAX = 2147483647;
32
33
    /**
34
     * @var \eZ\Publish\API\Repository\Tests\SetupFactory
35
     */
36
    private $setupFactory;
37
38
    /**
39
     * @var \eZ\Publish\API\Repository\Repository
40
     */
41
    private $repository;
42
43
    protected function setUp()
44
    {
45
        parent::setUp();
46
47
        try {
48
            // Use setup factory instance here w/o clearing data in case test don't need to
49
            $repository = $this->getSetupFactory()->getRepository(false);
50
51
            // Set session if we are testing the REST backend to make it
52
            // possible to persist data in the memory backend during multiple
53
            // requests.
54
            if ($repository instanceof Sessionable) {
55
                $repository->setSession($id = md5(microtime()));
56
            }
57
        } catch (PDOException $e) {
58
            $this->fail(
59
                'The communication with the database cannot be established. ' .
60
                "This is required in order to perform the tests.\n\n" .
61
                'Exception: ' . $e
62
            );
63
        } catch (Exception $e) {
64
            $this->fail(
65
                'Cannot create a repository with predefined user. ' .
66
                'Check the UserService or RoleService implementation. ' .
67
                PHP_EOL . PHP_EOL .
68
                'Exception: ' . $e
69
            );
70
        }
71
    }
72
73
    /**
74
     * Resets the temporary used repository between each test run.
75
     */
76
    protected function tearDown()
77
    {
78
        $this->repository = null;
79
        parent::tearDown();
80
    }
81
82
    /**
83
     * Returns the ID generator, fitting to the repository implementation.
84
     *
85
     * @return \eZ\Publish\API\Repository\Tests\IdManager
86
     */
87
    protected function getIdManager()
88
    {
89
        return $this->getSetupFactory()->getIdManager();
90
    }
91
92
    /**
93
     * Generates a repository specific ID value.
94
     *
95
     * @param string $type
96
     * @param mixed $rawId
97
     *
98
     * @return mixed
99
     */
100
    protected function generateId($type, $rawId)
101
    {
102
        return $this->getIdManager()->generateId($type, $rawId);
103
    }
104
105
    /**
106
     * Parses a repository specific ID value.
107
     *
108
     * @param string $type
109
     * @param mixed $id
110
     *
111
     * @return mixed
112
     */
113
    protected function parseId($type, $id)
114
    {
115
        return $this->getIdManager()->parseId($type, $id);
116
    }
117
118
    /**
119
     * Returns a config setting provided by the setup factory.
120
     *
121
     * @param string $configKey
122
     *
123
     * @return mixed
124
     */
125
    protected function getConfigValue($configKey)
126
    {
127
        return $this->getSetupFactory()->getConfigValue($configKey);
128
    }
129
130
    /**
131
     * Tests if the currently tested api is based on a V4 implementation.
132
     *
133
     * @return bool
134
     */
135
    protected function isVersion4()
136
    {
137
        return isset($_ENV['backendVersion']) && '4' === $_ENV['backendVersion'];
138
    }
139
140
    /**
141
     * @param bool $initialInitializeFromScratch Only has an effect if set in first call within a test
142
     *
143
     * @return \eZ\Publish\API\Repository\Repository
144
     */
145
    protected function getRepository($initialInitializeFromScratch = true)
146
    {
147
        if (null === $this->repository) {
148
            $this->repository = $this->getSetupFactory()->getRepository($initialInitializeFromScratch);
149
        }
150
151
        return $this->repository;
152
    }
153
154
    /**
155
     * @return \eZ\Publish\API\Repository\Tests\SetupFactory
156
     */
157
    protected function getSetupFactory()
158
    {
159
        if (null === $this->setupFactory) {
160
            if (false === isset($_ENV['setupFactory'])) {
161
                throw new \ErrorException('Missing mandatory setting $_ENV["setupFactory"].');
162
            }
163
164
            $setupClass = $_ENV['setupFactory'];
165
            if (false === class_exists($setupClass)) {
166
                throw new \ErrorException('$_ENV["setupFactory"] does not reference an existing class.');
167
            }
168
169
            $this->setupFactory = new $setupClass();
170
        }
171
172
        return $this->setupFactory;
173
    }
174
175
    /**
176
     * Asserts that properties given in $expectedValues are correctly set in
177
     * $actualObject.
178
     *
179
     * @param mixed[] $expectedValues
180
     * @param \eZ\Publish\API\Repository\Values\ValueObject $actualObject
181
     */
182
    protected function assertPropertiesCorrect(array $expectedValues, ValueObject $actualObject)
183
    {
184
        foreach ($expectedValues as $propertyName => $propertyValue) {
185
            $this->assertPropertiesEqual($propertyName, $propertyValue, $actualObject->$propertyName);
186
        }
187
    }
188
189
    /**
190
     * Asserts that properties given in $expectedValues are correctly set in
191
     * $actualObject.
192
     *
193
     * If the property type is array, it will be sorted before comparison.
194
     *
195
     * @TODO: introduced because of randomly failing tests, ref: https://jira.ez.no/browse/EZP-21734
196
     *
197
     * @param mixed[] $expectedValues
198
     * @param \eZ\Publish\API\Repository\Values\ValueObject $actualObject
199
     */
200
    protected function assertPropertiesCorrectUnsorted(array $expectedValues, ValueObject $actualObject)
201
    {
202
        foreach ($expectedValues as $propertyName => $propertyValue) {
203
            $this->assertPropertiesEqual($propertyName, $propertyValue, $actualObject->$propertyName, true);
204
        }
205
    }
206
207
    /**
208
     * Asserts all properties from $expectedValues are correctly set in
209
     * $actualObject. Additional (virtual) properties can be asserted using
210
     * $additionalProperties.
211
     *
212
     * @param \eZ\Publish\API\Repository\Values\ValueObject $expectedValues
213
     * @param \eZ\Publish\API\Repository\Values\ValueObject $actualObject
214
     * @param array $propertyNames
0 ignored issues
show
Bug introduced by
There is no parameter named $propertyNames. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
215
     */
216
    protected function assertStructPropertiesCorrect(ValueObject $expectedValues, ValueObject $actualObject, array $additionalProperties = array())
217
    {
218
        foreach ($expectedValues as $propertyName => $propertyValue) {
0 ignored issues
show
Bug introduced by
The expression $expectedValues of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not traversable.
Loading history...
219
            $this->assertPropertiesEqual($propertyName, $propertyValue, $actualObject->$propertyName);
220
        }
221
222
        foreach ($additionalProperties as $propertyName) {
223
            $this->assertPropertiesEqual($propertyName, $expectedValues->$propertyName, $actualObject->$propertyName);
224
        }
225
    }
226
227
    /**
228
     * @see \eZ\Publish\API\Repository\Tests\BaseTest::assertPropertiesCorrectUnsorted()
229
     *
230
     * @param array $items An array of scalar values
231
     */
232
    private function sortItems(array &$items)
233
    {
234
        $sorter = function ($a, $b) {
235
            if (!is_scalar($a) || !is_scalar($b)) {
236
                $this->fail('Wrong usage: method ' . __METHOD__ . ' accepts only an array of scalar values');
237
            }
238
239
            return strcmp($a, $b);
240
        };
241
        usort($items, $sorter);
242
    }
243
244
    private function assertPropertiesEqual($propertyName, $expectedValue, $actualValue, $sortArray = false)
245
    {
246
        if ($expectedValue instanceof ArrayObject) {
247
            $expectedValue = $expectedValue->getArrayCopy();
248
        } elseif ($expectedValue instanceof DateTime) {
249
            $expectedValue = $expectedValue->format(DateTime::RFC850);
250
        }
251
        if ($actualValue instanceof ArrayObject) {
252
            $actualValue = $actualValue->getArrayCopy();
253
        } elseif ($actualValue instanceof DateTime) {
254
            $actualValue = $actualValue->format(DateTime::RFC850);
255
        }
256
257
        if ($sortArray && is_array($actualValue) && is_array($expectedValue)) {
258
            $this->sortItems($actualValue);
259
            $this->sortItems($expectedValue);
260
        }
261
262
        $this->assertEquals(
263
            $expectedValue,
264
            $actualValue,
265
            sprintf('Object property "%s" incorrect.', $propertyName)
266
        );
267
    }
268
269
    /**
270
     * Create a user in editor user group.
271
     *
272
     * @return \eZ\Publish\API\Repository\Values\User\User
273
     */
274 View Code Duplication
    protected function createUserVersion1()
275
    {
276
        $repository = $this->getRepository();
277
278
        /* BEGIN: Inline */
279
        // ID of the "Editors" user group in an eZ Publish demo installation
280
        $editorsGroupId = 13;
281
282
        $userService = $repository->getUserService();
283
284
        // Instantiate a create struct with mandatory properties
285
        $userCreate = $userService->newUserCreateStruct(
286
            'user',
287
            '[email protected]',
288
            'secret',
289
            'eng-US'
290
        );
291
        $userCreate->enabled = true;
292
293
        // Set some fields required by the user ContentType
294
        $userCreate->setField('first_name', 'Example');
295
        $userCreate->setField('last_name', 'User');
296
297
        // Load parent group for the user
298
        $group = $userService->loadUserGroup($editorsGroupId);
299
300
        // Create a new user instance.
301
        $user = $userService->createUser($userCreate, array($group));
302
        /* END: Inline */
303
304
        return $user;
305
    }
306
307
    /**
308
     * Create a user in new user group with editor rights limited to Media Library (/1/48/).
309
     *
310
     * @uses ::createCustomUserVersion1()
311
     *
312
     * @return \eZ\Publish\API\Repository\Values\User\User
313
     */
314
    protected function createMediaUserVersion1()
315
    {
316
        return $this->createCustomUserVersion1(
317
            'Media Editor',
318
            'Editor',
319
            new SubtreeLimitation(array('limitationValues' => array('/1/43/')))
320
        );
321
    }
322
323
    /**
324
     * Create a user with new user group and assign a existing role (optionally with RoleLimitation).
325
     *
326
     * @param string $userGroupName Name of the new user group to create
327
     * @param string $roleIdentifier Role identifier to assign to the new group
328
     * @param RoleLimitation|null $roleLimitation
329
     *
330
     * @return \eZ\Publish\API\Repository\Values\User\User
331
     */
332
    protected function createCustomUserVersion1($userGroupName, $roleIdentifier, RoleLimitation $roleLimitation = null)
333
    {
334
        $repository = $this->getRepository();
335
336
        /* BEGIN: Inline */
337
        // ID of the "Users" user group in an eZ Publish demo installation
338
        $rootUsersGroupId = $this->generateId('location', 4);
339
340
        $roleService = $repository->getRoleService();
341
        $userService = $repository->getUserService();
342
343
        // Get a group create struct
344
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
345
        $userGroupCreate->setField('name', $userGroupName);
346
347
        // Create new group with media editor rights
348
        $userGroup = $userService->createUserGroup(
349
            $userGroupCreate,
350
            $userService->loadUserGroup($rootUsersGroupId)
351
        );
352
        $roleService->assignRoleToUserGroup(
353
            $roleService->loadRoleByIdentifier($roleIdentifier),
354
            $userGroup,
355
            $roleLimitation
356
        );
357
358
        // Instantiate a create struct with mandatory properties
359
        $userCreate = $userService->newUserCreateStruct(
360
            'user',
361
            '[email protected]',
362
            'secret',
363
            'eng-US'
364
        );
365
        $userCreate->enabled = true;
366
367
        // Set some fields required by the user ContentType
368
        $userCreate->setField('first_name', 'Example');
369
        $userCreate->setField('last_name', 'User');
370
371
        // Create a new user instance.
372
        $user = $userService->createUser($userCreate, array($userGroup));
373
        /* END: Inline */
374
375
        return $user;
376
    }
377
378
    /**
379
     * Create a user using given data.
380
     *
381
     * @param string $login
382
     * @param string $firstName
383
     * @param string $lastName
384
     * @return \eZ\Publish\API\Repository\Values\User\User
385
     */
386
    protected function createUser($login, $firstName, $lastName)
387
    {
388
        $repository = $this->getRepository();
389
390
        $userService = $repository->getUserService();
391
        $userGroup = $userService->loadUserGroup(13);
392
393
        // Instantiate a create struct with mandatory properties
394
        $userCreate = $userService->newUserCreateStruct(
395
            $login,
396
            "{$login}@example.com",
397
            'secret',
398
            'eng-US'
399
        );
400
        $userCreate->enabled = true;
401
402
        // Set some fields required by the user ContentType
403
        $userCreate->setField('first_name', $firstName);
404
        $userCreate->setField('last_name', $lastName);
405
406
        // Create a new user instance.
407
        $user = $userService->createUser($userCreate, array($userGroup));
408
409
        return $user;
410
    }
411
412
    /**
413
     * Only for internal use.
414
     *
415
     * Creates a \DateTime object for $timestamp in the current time zone
416
     *
417
     * @param int $timestamp
418
     *
419
     * @return \DateTime
420
     */
421 View Code Duplication
    public function createDateTime($timestamp = null)
422
    {
423
        $dateTime = new \DateTime();
424
        if ($timestamp !== null) {
425
            $dateTime->setTimestamp($timestamp);
426
        }
427
428
        return $dateTime;
429
    }
430
431
    /**
432
     * Calls given Repository's aggregated SearchHandler::refresh().
433
     *
434
     * Currently implemented only in Solr search engine.
435
     *
436
     * @param \eZ\Publish\API\Repository\Repository $repository
437
     */
438
    protected function refreshSearch(Repository $repository)
439
    {
440
        $setupFactory = $this->getSetupFactory();
441
442
        if (!$setupFactory instanceof LegacySolrSetupFactory) {
0 ignored issues
show
Bug introduced by
The class EzSystems\EzPlatformSolr...tory\LegacySetupFactory does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
443
            return;
444
        }
445
446
        while (true) {
447
            $repositoryReflection = new \ReflectionObject($repository);
448
            // If the repository is decorated, we need to recurse in the "repository" property
449
            if (!$repositoryReflection->hasProperty('repository')) {
450
                break;
451
            }
452
453
            $repositoryProperty = $repositoryReflection->getProperty('repository');
454
            $repositoryProperty->setAccessible(true);
455
            $repository = $repositoryProperty->getValue($repository);
456
        }
457
458
        $searchHandlerProperty = new \ReflectionProperty($repository, 'searchHandler');
459
        $searchHandlerProperty->setAccessible(true);
460
461
        /** @var \EzSystems\EzPlatformSolrSearchEngine\Handler $searchHandler */
462
        $searchHandler = $searchHandlerProperty->getValue($repository);
463
464
        $searchHandler->commit();
465
    }
466
}
467