Completed
Push — EZP-30821 ( 252180 )
by
unknown
150:25 queued 129:39
created

UrlTest::testFindUrls()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

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