Completed
Push — master ( 3ba77f...cda509 )
by
unknown
15:36
created

UrlTest::configureUrlViewPermissionForHasAccess()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
namespace eZ\Publish\Core\Repository\Tests\Service\Mock;
8
9
use DateTime;
10
use eZ\Publish\API\Repository\Values\Content\Search\SearchHit;
11
use eZ\Publish\API\Repository\Values\URL\UsageSearchResult;
12
use eZ\Publish\Core\Base\Exceptions\UnauthorizedException;
13
use eZ\Publish\Core\Repository\Tests\Service\Mock\Base as BaseServiceMockTest;
14
use eZ\Publish\API\Repository\SearchService;
15
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
16
use eZ\Publish\API\Repository\Values\Content\Query\Criterion as ContentCriterion;
17
use eZ\Publish\API\Repository\Values\Content\Query as ContentQuery;
18
use eZ\Publish\API\Repository\Values\Content\Search\SearchResult as ContentSearchResults;
19
use eZ\Publish\API\Repository\Values\URL\SearchResult;
20
use eZ\Publish\API\Repository\Values\URL\URL;
21
use eZ\Publish\API\Repository\Values\URL\URLQuery;
22
use eZ\Publish\API\Repository\Values\URL\URLUpdateStruct;
23
use eZ\Publish\Core\Repository\URLService;
24
use eZ\Publish\SPI\Persistence\URL\URL as SpiUrl;
25
26
class UrlTest extends BaseServiceMockTest
27
{
28
    private const URL_ID = 12;
29
    private const URL_EZ_NO = 'http://ez.no';
30
    private const URL_EZ_COM = 'http://ez.com';
31
32
    /** @var \eZ\Publish\API\Repository\URLService|\PHPUnit\Framework\MockObject\MockObject */
33
    private $urlHandler;
34
35
    /** @var \eZ\Publish\API\Repository\PermissionResolver|\PHPUnit\Framework\MockObject\MockObject */
36
    private $permissionResolver;
37
38
    protected function setUp(): void
39
    {
40
        parent::setUp();
41
        $this->urlHandler = $this->getPersistenceMockHandler('URL\\Handler');
42
        $this->permissionResolver = $this->getPermissionResolverMock();
43
    }
44
45
    public function testFindUrlsUnauthorized()
46
    {
47
        $this->configureUrlViewPermissionForHasAccess(false);
48
49
        $this->expectException(UnauthorizedException::class);
50
        $this->createUrlService()->findUrls(new URLQuery());
51
    }
52
53
    public function testFindUrlsNonNumericOffset()
54
    {
55
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue::class);
56
57
        $query = new URLQuery();
58
        $query->offset = 'foo';
0 ignored issues
show
Documentation Bug introduced by
The property $offset was declared of type integer, but 'foo' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
59
60
        $this->createUrlService()->findUrls($query);
61
    }
62
63
    public function testFindUrlsNonNumericLimit()
64
    {
65
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue::class);
66
67
        $query = new URLQuery();
68
        $query->limit = 'foo';
0 ignored issues
show
Documentation Bug introduced by
The property $limit was declared of type integer, but 'foo' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
69
70
        $this->createUrlService()->findUrls($query);
71
    }
72
73
    public function testFindUrls()
74
    {
75
        $url = $this->getApiUrl();
76
77
        $this->configureUrlViewPermissionForHasAccess(true);
78
79
        $query = new URLQuery();
80
81
        $results = [
82
            'count' => 1,
83
            'items' => [
84
                new SpiUrl(),
85
            ],
86
        ];
87
88
        $expected = new SearchResult([
89
            'totalCount' => 1,
90
            'items' => [$url],
91
        ]);
92
93
        $this->urlHandler
94
            ->expects($this->once())
95
            ->method('find')
96
            ->with($query)
97
            ->willReturn($results);
98
99
        $this->assertEquals($expected, $this->createUrlService()->findUrls($query));
100
    }
101
102
    public function testUpdateUrlUnauthorized()
103
    {
104
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\UnauthorizedException::class);
105
106
        $url = $this->getApiUrl();
107
108
        $this->configureUrlUpdatePermission($url, false);
109
110
        $this->createUrlService()->updateUrl($url, new URLUpdateStruct());
111
    }
112
113
    public function testUpdateUrlNonUnique()
114
    {
115
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\InvalidArgumentException::class);
116
117
        $url = $this->getApiUrl(self::URL_ID, self::URL_EZ_NO);
118
119
        $this->configureUrlUpdatePermission($url, true);
120
121
        $struct = new URLUpdateStruct([
122
            'url' => self::URL_EZ_COM,
123
        ]);
124
125
        $urlService = $this->createUrlService(['isUnique']);
126
        $urlService
127
            ->expects($this->once())
128
            ->method('isUnique')
129
            ->with($url->id, $struct->url)
130
            ->willReturn(false);
131
132
        $urlService->updateUrl($url, $struct);
133
    }
134
135
    public function testUpdateUrl()
136
    {
137
        $apiUrl = $this->getApiUrl(self::URL_ID, self::URL_EZ_NO);
138
        $apiStruct = new URLUpdateStruct([
139
            'url' => self::URL_EZ_COM,
140
            'isValid' => false,
141
            'lastChecked' => new DateTime(),
142
        ]);
143
144
        $this->configurePermissions([
145
            ['url', 'update', $apiUrl, []],
146
            ['url', 'view', $apiUrl, []],
147
            ['url', 'view', new URL(['id' => self::URL_ID, 'url' => self::URL_EZ_COM, 'isValid' => true]), []],
148
        ]);
149
150
        $urlService = $this->createUrlService(['isUnique']);
151
        $urlService
152
            ->expects($this->once())
153
            ->method('isUnique')
154
            ->with($apiUrl->id, $apiStruct->url)
155
            ->willReturn(true);
156
157
        $this->urlHandler
158
            ->expects($this->once())
159
            ->method('updateUrl')
160
            ->willReturnCallback(function ($id, $struct) use ($apiUrl, $apiStruct) {
161
                $this->assertEquals($apiUrl->id, $id);
162
163
                $this->assertEquals($apiStruct->url, $struct->url);
164
                $this->assertEquals(0, $struct->lastChecked);
165
                $this->assertTrue($struct->isValid);
166
            });
167
168
        $this->urlHandler
169
            ->method('loadById')
170
            ->with($apiUrl->id)
171
            ->willReturnOnConsecutiveCalls(
172
                new SpiUrl([
173
                    'id' => $apiUrl->id,
174
                    'url' => $apiUrl->url,
175
                    'isValid' => $apiUrl->isValid,
176
                    'lastChecked' => $apiUrl->lastChecked,
177
                ]),
178
                new SpiUrl([
179
                    'id' => $apiUrl->id,
180
                    'url' => $apiStruct->url,
181
                    'isValid' => true,
182
                    'lastChecked' => 0,
183
                ])
184
            );
185
186
        $this->assertEquals(new URL([
187
            'id' => $apiUrl->id,
188
            'url' => $apiStruct->url,
189
            'isValid' => true,
190
            'lastChecked' => null,
191
        ]), $urlService->updateUrl($apiUrl, $apiStruct));
192
    }
193
194
    public function testUpdateUrlStatus()
195
    {
196
        $apiUrl = $this->getApiUrl(self::URL_ID, self::URL_EZ_NO);
197
        $apiStruct = new URLUpdateStruct([
198
            'isValid' => true,
199
            'lastChecked' => new DateTime('@' . time()),
200
        ]);
201
202
        $urlAfterUpdate = new URL([
203
            'id' => self::URL_ID,
204
            'url' => self::URL_EZ_NO,
205
            'isValid' => true,
206
            'lastChecked' => new DateTime('@' . time()),
207
        ]);
208
209
        $this->configurePermissions([
210
            ['url', 'update', $apiUrl, []],
211
            ['url', 'view', $apiUrl, []],
212
            ['url', 'view', $urlAfterUpdate, []],
213
        ]);
214
215
        $urlService = $this->createUrlService(['isUnique']);
216
        $urlService
217
            ->expects($this->once())
218
            ->method('isUnique')
219
            ->with($apiUrl->id, $apiStruct->url)
220
            ->willReturn(true);
221
222
        $this->urlHandler
223
            ->expects($this->once())
224
            ->method('updateUrl')
225
            ->willReturnCallback(function ($id, $struct) use ($apiUrl, $apiStruct) {
226
                $this->assertEquals($apiUrl->id, $id);
227
228
                $this->assertEquals($apiUrl->url, $struct->url);
229
                $this->assertEquals($apiStruct->lastChecked->getTimestamp(), $struct->lastChecked);
230
                $this->assertTrue($apiStruct->isValid, $struct->isValid);
231
            });
232
233
        $this->urlHandler
234
            ->method('loadById')
235
            ->with($apiUrl->id)
236
            ->willReturnOnConsecutiveCalls(
237
                new SpiUrl([
238
                    'id' => $apiUrl->id,
239
                    'url' => $apiUrl->url,
240
                    'isValid' => $apiUrl->isValid,
241
                    'lastChecked' => $apiUrl->lastChecked,
242
                ]),
243
                new SpiUrl([
244
                    'id' => $apiUrl->id,
245
                    'url' => $apiUrl->url,
246
                    'isValid' => $apiStruct->isValid,
247
                    'lastChecked' => $apiStruct->lastChecked->getTimestamp(),
248
                ])
249
            );
250
251
        $this->assertEquals(new URL([
252
            'id' => $apiUrl->id,
253
            'url' => $apiUrl->url,
254
            'isValid' => $apiStruct->isValid,
255
            'lastChecked' => $apiStruct->lastChecked,
256
        ]), $urlService->updateUrl($apiUrl, $apiStruct));
257
    }
258
259
    public function testLoadByIdUnauthorized()
260
    {
261
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\UnauthorizedException::class);
262
263
        $this->configureUrlViewPermission(
264
            new URL([
265
                'id' => self::URL_ID,
266
            ]),
267
            false
268
        );
269
270
        $this->urlHandler
271
            ->expects($this->once())
272
            ->method('loadById')
273
            ->with(self::URL_ID)
274
            ->willReturn(new SpiUrl([
275
                'id' => self::URL_ID,
276
            ]));
277
278
        $this->createUrlService()->loadById(self::URL_ID);
279
    }
280
281
    public function testLoadById()
282
    {
283
        $url = new URL([
284
            'id' => self::URL_ID,
285
        ]);
286
287
        $this->configureUrlViewPermission($url, true);
288
289
        $this->urlHandler
290
            ->expects($this->once())
291
            ->method('loadById')
292
            ->with(self::URL_ID)
293
            ->willReturn(new SpiUrl([
294
                'id' => self::URL_ID,
295
            ]));
296
297
        $this->assertEquals($url, $this->createUrlService()->loadById(self::URL_ID));
298
    }
299
300
    public function testLoadByUrlUnauthorized()
301
    {
302
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\UnauthorizedException::class);
303
304
        $url = self::URL_EZ_NO;
305
306
        $this->configureUrlViewPermission(
307
            new URL([
308
                'id' => self::URL_ID,
309
            ]),
310
            false
311
        );
312
313
        $this->urlHandler
314
            ->expects($this->once())
315
            ->method('loadByUrl')
316
            ->with($url)
317
            ->willReturn(new SpiUrl([
318
                'id' => self::URL_ID,
319
            ]));
320
321
        $this->createUrlService()->loadByUrl(self::URL_EZ_NO);
322
    }
323
324
    public function testLoadByUrl()
325
    {
326
        $url = self::URL_EZ_NO;
327
328
        $apiUrl = new URL([
329
            'url' => $url,
330
        ]);
331
332
        $this->configureUrlViewPermission($apiUrl, true);
333
334
        $this->urlHandler
335
            ->expects($this->once())
336
            ->method('loadByUrl')
337
            ->with($url)
338
            ->willReturn(new SpiUrl([
339
                'url' => $url,
340
            ]));
341
342
        $this->assertEquals($apiUrl, $this->createUrlService()->loadByUrl($url));
343
    }
344
345
    /**
346
     * @dataProvider dateProviderForFindUsages
347
     */
348
    public function testFindUsages($offset, $limit, ContentQuery $expectedQuery, array $usages)
349
    {
350
        $url = $this->getApiUrl(self::URL_ID, self::URL_EZ_NO);
351
352
        if (!empty($usages)) {
353
            $searchService = $this->createMock(SearchService::class);
354
            $searchService
355
                ->expects($this->once())
356
                ->method('findContentInfo')
357
                ->willReturnCallback(function ($query) use ($expectedQuery, $usages) {
358
                    $this->assertEquals($expectedQuery, $query);
359
360
                    return new ContentSearchResults([
361
                        'searchHits' => array_map(function ($id) {
362
                            return new SearchHit([
363
                                'valueObject' => new ContentInfo([
364
                                    'id' => $id,
365
                                ]),
366
                            ]);
367
                        }, $usages),
368
                        'totalCount' => count($usages),
369
                    ]);
370
                });
371
372
            $this->getRepositoryMock()
373
                ->expects($this->once())
374
                ->method('getSearchService')
375
                ->willReturn($searchService);
376
        }
377
378
        $this->urlHandler
379
            ->expects($this->once())
380
            ->method('findUsages')
381
            ->with($url->id)
382
            ->willReturn($usages);
383
384
        $usageSearchResult = $this->createUrlService()->findUsages($url, $offset, $limit);
385
386
        $this->assertInstanceOf(UsageSearchResult::class, $usageSearchResult);
387
        $this->assertEquals(count($usages), $usageSearchResult->totalCount);
388
        foreach ($usageSearchResult as $contentInfo) {
389
            $this->assertContains($contentInfo->id, $usages);
390
        }
391
    }
392
393
    public function dateProviderForFindUsages()
394
    {
395
        return [
396
            [
397
                10, -1, new ContentQuery([
398
                    'filter' => new ContentCriterion\MatchNone(),
399
                    'offset' => 10,
400
                ]), [],
401
            ],
402
            [
403
                10, -1, new ContentQuery([
404
                    'filter' => new ContentCriterion\LogicalAnd([
405
                        new ContentCriterion\ContentId([1, 2, 3]),
406
                        new ContentCriterion\Visibility(ContentCriterion\Visibility::VISIBLE),
407
                    ]),
408
                    'offset' => 10,
409
                ]), [1, 2, 3],
410
            ],
411
            [
412
                10, 10, new ContentQuery([
413
                    'filter' => new ContentCriterion\LogicalAnd([
414
                        new ContentCriterion\ContentId([1, 2, 3]),
415
                        new ContentCriterion\Visibility(ContentCriterion\Visibility::VISIBLE),
416
                    ]),
417
                    'offset' => 10,
418
                    'limit' => 10,
419
                ]), [1, 2, 3],
420
            ],
421
        ];
422
    }
423
424
    public function testCreateUpdateStruct()
425
    {
426
        $this->assertEquals(new URLUpdateStruct(), $this->createUrlService()->createUpdateStruct());
427
    }
428
429
    protected function configureUrlViewPermissionForHasAccess($hasAccess = false)
430
    {
431
        $this->getRepositoryMock()
432
            ->expects($this->once())
433
            ->method('hasAccess')
434
            ->with('url', 'view')
435
            ->willReturn($hasAccess);
436
    }
437
438
    protected function configureUrlViewPermission($object, $hasAccess = false)
439
    {
440
        $this->permissionResolver
441
            ->expects($this->once())
442
            ->method('canUser')
443
            ->with(
444
                $this->equalTo('url'),
445
                $this->equalTo('view'),
446
                $this->equalTo($object)
447
            )
448
            ->will($this->returnValue($hasAccess));
449
    }
450
451
    protected function configureUrlUpdatePermission($object, $hasAccess = false)
452
    {
453
        $this->permissionResolver
454
            ->expects($this->once())
455
            ->method('canUser')
456
            ->with(
457
                $this->equalTo('url'),
458
                $this->equalTo('update'),
459
                $this->equalTo($object)
460
            )
461
            ->will($this->returnValue($hasAccess));
462
    }
463
464
    protected function configurePermissions(array $permissions)
465
    {
466
        $this->permissionResolver
467
            ->expects($this->exactly(count($permissions)))
468
            ->method('canUser')
469
            ->withConsecutive(...$permissions)
470
            ->willReturn(true);
471
    }
472
473
    /**
474
     * @return \eZ\Publish\API\Repository\URLService|\PHPUnit\Framework\MockObject\MockObject
475
     */
476
    private function createUrlService(array $methods = null)
477
    {
478
        return $this
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\MockOb...ckBuilder::setMethods() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/pull/3687

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
479
            ->getMockBuilder(URLService::class)
480
            ->setConstructorArgs([$this->getRepositoryMock(), $this->urlHandler, $this->permissionResolver])
481
            ->setMethods($methods)
482
            ->getMock();
483
    }
484
485
    private function getApiUrl($id = null, $url = null)
486
    {
487
        return new URL(['id' => $id, 'url' => $url]);
488
    }
489
}
490