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