Completed
Push — master ( 3650d6...6d4b31 )
by André
20:00
created

BaseTest::createCustomUserVersion1()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 3
dl 0
loc 10
rs 9.4285
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
    /**
44
     */
45
    protected function setUp()
46
    {
47
        parent::setUp();
48
49
        try {
50
            // Use setup factory instance here w/o clearing data in case test don't need to
51
            $repository = $this->getSetupFactory()->getRepository(false);
52
53
            // Set session if we are testing the REST backend to make it
54
            // possible to persist data in the memory backend during multiple
55
            // requests.
56
            if ($repository instanceof Sessionable) {
57
                $repository->setSession($id = md5(microtime()));
58
            }
59
        } catch (PDOException $e) {
60
            $this->fail(
61
                'The communication with the database cannot be established. ' .
62
                "This is required in order to perform the tests.\n\n" .
63
                'Exception: ' . $e
64
            );
65
        } catch (Exception $e) {
66
            $this->fail(
67
                'Cannot create a repository with predefined user. ' .
68
                'Check the UserService or RoleService implementation. ' .
69
                PHP_EOL . PHP_EOL .
70
                'Exception: ' . $e
71
            );
72
        }
73
    }
74
75
    /**
76
     * Resets the temporary used repository between each test run.
77
     */
78
    protected function tearDown()
79
    {
80
        $this->repository = null;
81
        parent::tearDown();
82
    }
83
84
    /**
85
     * Returns the ID generator, fitting to the repository implementation.
86
     *
87
     * @return \eZ\Publish\API\Repository\Tests\IdManager
88
     */
89
    protected function getIdManager()
90
    {
91
        return $this->getSetupFactory()->getIdManager();
92
    }
93
94
    /**
95
     * Generates a repository specific ID value.
96
     *
97
     * @param string $type
98
     * @param mixed $rawId
99
     *
100
     * @return mixed
101
     */
102
    protected function generateId($type, $rawId)
103
    {
104
        return $this->getIdManager()->generateId($type, $rawId);
105
    }
106
107
    /**
108
     * Parses a repository specific ID value.
109
     *
110
     * @param string $type
111
     * @param mixed $id
112
     *
113
     * @return mixed
114
     */
115
    protected function parseId($type, $id)
116
    {
117
        return $this->getIdManager()->parseId($type, $id);
118
    }
119
120
    /**
121
     * Returns a config setting provided by the setup factory.
122
     *
123
     * @param string $configKey
124
     *
125
     * @return mixed
126
     */
127
    protected function getConfigValue($configKey)
128
    {
129
        return $this->getSetupFactory()->getConfigValue($configKey);
130
    }
131
132
    /**
133
     * Tests if the currently tested api is based on a V4 implementation.
134
     *
135
     * @return bool
136
     */
137
    protected function isVersion4()
138
    {
139
        return isset($_ENV['backendVersion']) && '4' === $_ENV['backendVersion'];
140
    }
141
142
    /**
143
     * @param bool $initialInitializeFromScratch Only has an effect if set in first call within a test
144
     *
145
     * @return \eZ\Publish\API\Repository\Repository
146
     */
147
    protected function getRepository($initialInitializeFromScratch = true)
148
    {
149
        if (null === $this->repository) {
150
            $this->repository = $this->getSetupFactory()->getRepository($initialInitializeFromScratch);
151
        }
152
153
        return $this->repository;
154
    }
155
156
    /**
157
     * @return \eZ\Publish\API\Repository\Tests\SetupFactory
158
     */
159
    protected function getSetupFactory()
160
    {
161
        if (null === $this->setupFactory) {
162
            if (false === isset($_ENV['setupFactory'])) {
163
                throw new \ErrorException('Missing mandatory setting $_ENV["setupFactory"].');
164
            }
165
166
            $setupClass = $_ENV['setupFactory'];
167
            if (false === class_exists($setupClass)) {
168
                throw new \ErrorException('$_ENV["setupFactory"] does not reference an existing class.');
169
            }
170
171
            $this->setupFactory = new $setupClass();
172
        }
173
174
        return $this->setupFactory;
175
    }
176
177
    /**
178
     * Asserts that properties given in $expectedValues are correctly set in
179
     * $actualObject.
180
     *
181
     * @param mixed[] $expectedValues
182
     * @param \eZ\Publish\API\Repository\Values\ValueObject $actualObject
183
     */
184
    protected function assertPropertiesCorrect(array $expectedValues, ValueObject $actualObject)
185
    {
186
        foreach ($expectedValues as $propertyName => $propertyValue) {
187
            $this->assertPropertiesEqual($propertyName, $propertyValue, $actualObject->$propertyName);
188
        }
189
    }
190
191
    /**
192
     * Asserts that properties given in $expectedValues are correctly set in
193
     * $actualObject.
194
     *
195
     * If the property type is array, it will be sorted before comparison.
196
     *
197
     * @TODO: introduced because of randomly failing tests, ref: https://jira.ez.no/browse/EZP-21734
198
     *
199
     * @param mixed[] $expectedValues
200
     * @param \eZ\Publish\API\Repository\Values\ValueObject $actualObject
201
     */
202
    protected function assertPropertiesCorrectUnsorted(array $expectedValues, ValueObject $actualObject)
203
    {
204
        foreach ($expectedValues as $propertyName => $propertyValue) {
205
            $this->assertPropertiesEqual($propertyName, $propertyValue, $actualObject->$propertyName, true);
206
        }
207
    }
208
209
    /**
210
     * Asserts all properties from $expectedValues are correctly set in
211
     * $actualObject. Additional (virtual) properties can be asserted using
212
     * $additionalProperties.
213
     *
214
     * @param \eZ\Publish\API\Repository\Values\ValueObject $expectedValues
215
     * @param \eZ\Publish\API\Repository\Values\ValueObject $actualObject
216
     * @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...
217
     */
218
    protected function assertStructPropertiesCorrect(ValueObject $expectedValues, ValueObject $actualObject, array $additionalProperties = array())
219
    {
220
        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...
221
            $this->assertPropertiesEqual($propertyName, $propertyValue, $actualObject->$propertyName);
222
        }
223
224
        foreach ($additionalProperties as $propertyName) {
225
            $this->assertPropertiesEqual($propertyName, $expectedValues->$propertyName, $actualObject->$propertyName);
226
        }
227
    }
228
229
    /**
230
     * @see \eZ\Publish\API\Repository\Tests\BaseTest::assertPropertiesCorrectUnsorted()
231
     *
232
     * @param array $items An array of scalar values
233
     */
234
    private function sortItems(array &$items)
235
    {
236
        $sorter = function ($a, $b) {
237
            if (!is_scalar($a) || !is_scalar($b)) {
238
                $this->fail('Wrong usage: method ' . __METHOD__ . ' accepts only an array of scalar values');
239
            }
240
241
            return strcmp($a, $b);
242
        };
243
        usort($items, $sorter);
244
    }
245
246
    private function assertPropertiesEqual($propertyName, $expectedValue, $actualValue, $sortArray = false)
247
    {
248
        if ($expectedValue instanceof ArrayObject) {
249
            $expectedValue = $expectedValue->getArrayCopy();
250
        } elseif ($expectedValue instanceof DateTime) {
251
            $expectedValue = $expectedValue->format(DateTime::RFC850);
252
        }
253
        if ($actualValue instanceof ArrayObject) {
254
            $actualValue = $actualValue->getArrayCopy();
255
        } elseif ($actualValue instanceof DateTime) {
256
            $actualValue = $actualValue->format(DateTime::RFC850);
257
        }
258
259
        if ($sortArray && is_array($actualValue) && is_array($expectedValue)) {
260
            $this->sortItems($actualValue);
261
            $this->sortItems($expectedValue);
262
        }
263
264
        $this->assertEquals(
265
            $expectedValue,
266
            $actualValue,
267
            sprintf('Object property "%s" incorrect.', $propertyName)
268
        );
269
    }
270
271
    /**
272
     * Create a user in editor user group.
273
     *
274
     * @return \eZ\Publish\API\Repository\Values\User\User
275
     */
276 View Code Duplication
    protected function createUserVersion1()
277
    {
278
        $repository = $this->getRepository();
279
280
        /* BEGIN: Inline */
281
        // ID of the "Editors" user group in an eZ Publish demo installation
282
        $editorsGroupId = 13;
283
284
        $userService = $repository->getUserService();
285
286
        // Instantiate a create struct with mandatory properties
287
        $userCreate = $userService->newUserCreateStruct(
288
            'user',
289
            '[email protected]',
290
            'secret',
291
            'eng-US'
292
        );
293
        $userCreate->enabled = true;
294
295
        // Set some fields required by the user ContentType
296
        $userCreate->setField('first_name', 'Example');
297
        $userCreate->setField('last_name', 'User');
298
299
        // Load parent group for the user
300
        $group = $userService->loadUserGroup($editorsGroupId);
301
302
        // Create a new user instance.
303
        $user = $userService->createUser($userCreate, array($group));
304
        /* END: Inline */
305
306
        return $user;
307
    }
308
309
    /**
310
     * Create a user in new user group with editor rights limited to Media Library (/1/48/).
311
     *
312
     * @uses createCustomUserVersion1()
313
     *
314
     * @return \eZ\Publish\API\Repository\Values\User\User
315
     */
316
    protected function createMediaUserVersion1()
317
    {
318
        return $this->createCustomUserVersion1(
319
            'Media Editor',
320
            'Editor',
321
            new SubtreeLimitation(array('limitationValues' => array('/1/43/')))
322
        );
323
    }
324
325
    /**
326
     * Create a user with new user group and assign a existing role (optionally with RoleLimitation).
327
     *
328
     * @param string $userGroupName Name of the new user group to create
329
     * @param string $roleIdentifier Role identifier to assign to the new group
330
     * @param RoleLimitation|null $roleLimitation
331
     *
332
     * @return \eZ\Publish\API\Repository\Values\User\User
333
     */
334
    protected function createCustomUserVersion1($userGroupName, $roleIdentifier, RoleLimitation $roleLimitation = null)
335
    {
336
        return $this->createCustomUserWithLogin(
337
            'user',
338
            '[email protected]',
339
            $userGroupName,
340
            $roleIdentifier,
341
            $roleLimitation
342
        );
343
    }
344
345
    /**
346
     * Create a user with new user group and assign a existing role (optionally with RoleLimitation).
347
     *
348
     * @param string $login User login
349
     * @param string $email User e-mail
350
     * @param string $userGroupName Name of the new user group to create
351
     * @param string $roleIdentifier Role identifier to assign to the new group
352
     * @param RoleLimitation|null $roleLimitation
353
     * @return \eZ\Publish\API\Repository\Values\User\User
354
     */
355
    protected function createCustomUserWithLogin(
356
        $login,
357
        $email,
358
        $userGroupName,
359
        $roleIdentifier,
360
        RoleLimitation $roleLimitation = null
361
    ) {
362
        $repository = $this->getRepository();
363
364
        /* BEGIN: Inline */
365
        // ID of the "Users" user group in an eZ Publish demo installation
366
        $rootUsersGroupId = $this->generateId('location', 4);
367
368
        $roleService = $repository->getRoleService();
369
        $userService = $repository->getUserService();
370
371
        // Get a group create struct
372
        $userGroupCreate = $userService->newUserGroupCreateStruct('eng-US');
373
        $userGroupCreate->setField('name', $userGroupName);
374
375
        // Create new group with media editor rights
376
        $userGroup = $userService->createUserGroup(
377
            $userGroupCreate,
378
            $userService->loadUserGroup($rootUsersGroupId)
379
        );
380
        $roleService->assignRoleToUserGroup(
381
            $roleService->loadRoleByIdentifier($roleIdentifier),
382
            $userGroup,
383
            $roleLimitation
384
        );
385
386
        // Instantiate a create struct with mandatory properties
387
        $userCreate = $userService->newUserCreateStruct(
388
            $login,
389
            $email,
390
            'secret',
391
            'eng-US'
392
        );
393
        $userCreate->enabled = true;
394
395
        // Set some fields required by the user ContentType
396
        $userCreate->setField('first_name', 'Example');
397
        $userCreate->setField('last_name', ucfirst($login));
398
399
        // Create a new user instance.
400
        $user = $userService->createUser($userCreate, array($userGroup));
401
        /* END: Inline */
402
403
        return $user;
404
    }
405
406
    /**
407
     * Only for internal use.
408
     *
409
     * Creates a \DateTime object for $timestamp in the current time zone
410
     *
411
     * @param int $timestamp
412
     *
413
     * @return \DateTime
414
     */
415 View Code Duplication
    public function createDateTime($timestamp = null)
416
    {
417
        $dateTime = new \DateTime();
418
        if ($timestamp !== null) {
419
            $dateTime->setTimestamp($timestamp);
420
        }
421
422
        return $dateTime;
423
    }
424
425
    /**
426
     * Calls given Repository's aggregated SearchHandler::refresh().
427
     *
428
     * Currently implemented only in Solr search engine.
429
     *
430
     * @param \eZ\Publish\API\Repository\Repository $repository
431
     */
432
    protected function refreshSearch(Repository $repository)
433
    {
434
        $setupFactory = $this->getSetupFactory();
435
436
        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...
437
            return;
438
        }
439
440
        while (true) {
441
            $repositoryReflection = new \ReflectionObject($repository);
442
            // If the repository is decorated, we need to recurse in the "repository" property
443
            if (!$repositoryReflection->hasProperty('repository')) {
444
                break;
445
            }
446
447
            $repositoryProperty = $repositoryReflection->getProperty('repository');
448
            $repositoryProperty->setAccessible(true);
449
            $repository = $repositoryProperty->getValue($repository);
450
        }
451
452
        $searchHandlerProperty = new \ReflectionProperty($repository, 'searchHandler');
453
        $searchHandlerProperty->setAccessible(true);
454
455
        /** @var \EzSystems\EzPlatformSolrSearchEngine\Handler $searchHandler */
456
        $searchHandler = $searchHandlerProperty->getValue($repository);
457
458
        $searchHandler->commit();
459
    }
460
}
461