Completed
Push — master ( 336c64...8fa798 )
by Łukasz
25:31
created

BookmarkTest::testCreateBookmark()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
c 0
b 0
f 0
cc 1
eloc 17
nc 1
nop 0
rs 8.8571
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
declare(strict_types=1);
8
9
namespace eZ\Publish\Core\Repository\Tests\Service\Mock;
10
11
use Exception;
12
use eZ\Publish\API\Repository\LocationService;
13
use eZ\Publish\API\Repository\PermissionResolver;
14
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
15
use eZ\Publish\Core\Repository\BookmarkService;
16
use eZ\Publish\Core\Repository\Tests\Service\Mock\Base as BaseServiceMockTest;
17
use eZ\Publish\Core\Repository\Values\Content\Location;
18
use eZ\Publish\Core\Repository\Values\User\UserReference;
19
use eZ\Publish\SPI\Persistence\Bookmark\Bookmark;
20
use eZ\Publish\SPI\Persistence\Bookmark\CreateStruct;
21
use PHPUnit\Framework\MockObject\MockObject;
22
23
class BookmarkTest extends BaseServiceMockTest
24
{
25
    const BOOKMARK_ID = 2;
26
    const CURRENT_USER_ID = 7;
27
    const LOCATION_ID = 1;
28
29
    /** @var \eZ\Publish\SPI\Persistence\Bookmark\Handler|\PHPUnit\Framework\MockObject\MockObject */
30
    private $bookmarkHandler;
31
32
    protected function setUp()
33
    {
34
        parent::setUp();
35
36
        $this->bookmarkHandler = $this->getPersistenceMockHandler('Bookmark\\Handler');
37
38
        $permissionResolverMock = $this->createMock(PermissionResolver::class);
39
        $permissionResolverMock
40
            ->expects($this->atLeastOnce())
41
            ->method('getCurrentUserReference')
42
            ->willReturn(new UserReference(self::CURRENT_USER_ID));
43
44
        $repository = $this->getRepositoryMock();
45
        $repository
46
            ->expects($this->atLeastOnce())
47
            ->method('getPermissionResolver')
48
            ->willReturn($permissionResolverMock);
49
    }
50
51
    /**
52
     * @covers \eZ\Publish\Core\Repository\BookmarkService::createBookmark
53
     */
54
    public function testCreateBookmark()
55
    {
56
        $location = $this->createLocation(self::LOCATION_ID);
57
58
        $this->assertLocationIsLoaded($location);
59
60
        $this->bookmarkHandler
61
            ->expects($this->once())
62
            ->method('loadByUserIdAndLocationId')
63
            ->with(self::CURRENT_USER_ID, [self::LOCATION_ID])
64
            ->willReturn([]);
65
66
        $this->assertTransactionIsCommitted(function () {
67
            $this->bookmarkHandler
68
                ->expects($this->once())
69
                ->method('create')
70
                ->willReturnCallback(function (CreateStruct $createStruct) {
71
                    $this->assertEquals(self::LOCATION_ID, $createStruct->locationId);
72
                    $this->assertEquals(self::CURRENT_USER_ID, $createStruct->userId);
73
74
                    return new Bookmark();
75
                });
76
        });
77
78
        $this->createBookmarkService()->createBookmark($location);
79
    }
80
81
    /**
82
     * @covers \eZ\Publish\Core\Repository\BookmarkService::createBookmark
83
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
84
     */
85 View Code Duplication
    public function testCreateBookmarkThrowsInvalidArgumentException()
86
    {
87
        $location = $this->createLocation(self::LOCATION_ID);
88
89
        $this->assertLocationIsLoaded($location);
90
91
        $this->bookmarkHandler
92
            ->expects($this->once())
93
            ->method('loadByUserIdAndLocationId')
94
            ->with(self::CURRENT_USER_ID, [self::LOCATION_ID])
95
            ->willReturn([self::LOCATION_ID => new Bookmark()]);
96
97
        $this->assertTransactionIsNotStarted(function () {
98
            $this->bookmarkHandler->expects($this->never())->method('create');
99
        });
100
101
        $this->createBookmarkService()->createBookmark($location);
102
    }
103
104
    /**
105
     * @covers \eZ\Publish\Core\Repository\BookmarkService::createBookmark
106
     * @expectedException \Exception
107
     */
108 View Code Duplication
    public function testCreateBookmarkWithRollback()
109
    {
110
        $location = $this->createLocation(self::LOCATION_ID);
111
112
        $this->assertLocationIsLoaded($location);
113
114
        $this->bookmarkHandler
115
            ->expects($this->once())
116
            ->method('loadByUserIdAndLocationId')
117
            ->with(self::CURRENT_USER_ID, [self::LOCATION_ID])
118
            ->willReturn([]);
119
120
        $this->assertTransactionIsRollback(function () {
121
            $this->bookmarkHandler
122
                ->expects($this->once())
123
                ->method('create')
124
                ->willThrowException($this->createMock(Exception::class));
125
        });
126
127
        $this->createBookmarkService()->createBookmark($location);
128
    }
129
130
    /**
131
     * @covers \eZ\Publish\Core\Repository\BookmarkService::deleteBookmark
132
     */
133
    public function testDeleteBookmarkExisting()
134
    {
135
        $location = $this->createLocation(self::LOCATION_ID);
136
137
        $this->assertLocationIsLoaded($location);
138
139
        $bookmark = new Bookmark(['id' => self::BOOKMARK_ID]);
140
141
        $this->bookmarkHandler
142
            ->expects($this->once())
143
            ->method('loadByUserIdAndLocationId')
144
            ->with(self::CURRENT_USER_ID, [self::LOCATION_ID])
145
            ->willReturn([self::LOCATION_ID => $bookmark]);
146
147
        $this->assertTransactionIsCommitted(function () use ($bookmark) {
148
            $this->bookmarkHandler
149
                ->expects($this->once())
150
                ->method('delete')
151
                ->with($bookmark->id);
152
        });
153
154
        $this->createBookmarkService()->deleteBookmark($location);
155
    }
156
157
    /**
158
     * @covers \eZ\Publish\Core\Repository\BookmarkService::deleteBookmark
159
     * @expectedException \Exception
160
     */
161
    public function testDeleteBookmarkWithRollback()
162
    {
163
        $location = $this->createLocation(self::LOCATION_ID);
164
165
        $this->assertLocationIsLoaded($location);
166
167
        $this->bookmarkHandler
168
            ->expects($this->once())
169
            ->method('loadByUserIdAndLocationId')
170
            ->with(self::CURRENT_USER_ID, [self::LOCATION_ID])
171
            ->willReturn([self::LOCATION_ID => new Bookmark(['id' => self::BOOKMARK_ID])]);
172
173
        $this->assertTransactionIsRollback(function () {
174
            $this->bookmarkHandler
175
                ->expects($this->once())
176
                ->method('delete')
177
                ->willThrowException($this->createMock(Exception::class));
178
        });
179
180
        $this->createBookmarkService()->deleteBookmark($location);
181
    }
182
183
    /**
184
     * @covers \eZ\Publish\Core\Repository\BookmarkService::deleteBookmark
185
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
186
     */
187 View Code Duplication
    public function testDeleteBookmarkNonExisting()
188
    {
189
        $location = $this->createLocation(self::LOCATION_ID);
190
191
        $this->assertLocationIsLoaded($location);
192
193
        $this->bookmarkHandler
194
            ->expects($this->once())
195
            ->method('loadByUserIdAndLocationId')
196
            ->with(self::CURRENT_USER_ID, [self::LOCATION_ID])
197
            ->willReturn([]);
198
199
        $this->assertTransactionIsNotStarted(function () {
200
            $this->bookmarkHandler->expects($this->never())->method('delete');
201
        });
202
203
        $this->createBookmarkService()->deleteBookmark($location);
204
    }
205
206
    /**
207
     * @covers \eZ\Publish\Core\Repository\BookmarkService::loadBookmarks
208
     */
209
    public function testLoadBookmarks()
210
    {
211
        $offset = 0;
212
        $limit = 25;
213
214
        $expectedTotalCount = 10;
215
        $expectedItems = array_map(function ($locationId) {
216
            return $this->createLocation($locationId);
217
        }, range(1, $expectedTotalCount));
218
219
        $this->bookmarkHandler
220
            ->expects($this->once())
221
            ->method('countUserBookmarks')
222
            ->with(self::CURRENT_USER_ID)
223
            ->willReturn($expectedTotalCount);
224
225
        $this->bookmarkHandler
226
            ->expects($this->once())
227
            ->method('loadUserBookmarks')
228
            ->with(self::CURRENT_USER_ID, $offset, $limit)
229
            ->willReturn(array_map(function ($locationId) {
230
                return new Bookmark(['locationId' => $locationId]);
231
            }, range(1, $expectedTotalCount)));
232
233
        $locationServiceMock = $this->createMock(LocationService::class);
234
        $locationServiceMock
235
            ->expects($this->exactly($expectedTotalCount))
236
            ->method('loadLocation')
237
            ->willReturnCallback(function ($locationId) {
238
                return $this->createLocation($locationId);
239
            });
240
241
        $repository = $this->getRepositoryMock();
242
        $repository
243
            ->expects($this->any())
244
            ->method('getLocationService')
245
            ->willReturn($locationServiceMock);
246
247
        $bookmarks = $this->createBookmarkService()->loadBookmarks($offset, $limit);
248
249
        $this->assertEquals($expectedTotalCount, $bookmarks->totalCount);
250
        $this->assertEquals($expectedItems, $bookmarks->items);
251
    }
252
253
    /**
254
     * @covers \eZ\Publish\Core\Repository\BookmarkService::loadBookmarks
255
     */
256
    public function testLoadBookmarksEmptyList()
257
    {
258
        $this->bookmarkHandler
259
            ->expects($this->once())
260
            ->method('countUserBookmarks')
261
            ->with(self::CURRENT_USER_ID)
262
            ->willReturn(0);
263
264
        $this->bookmarkHandler
265
            ->expects($this->never())
266
            ->method('loadUserBookmarks');
267
268
        $bookmarks = $this->createBookmarkService()->loadBookmarks(0, 10);
269
270
        $this->assertEquals(0, $bookmarks->totalCount);
271
        $this->assertEmpty($bookmarks->items);
272
    }
273
274
    /**
275
     * @covers \eZ\Publish\Core\Repository\BookmarkService::isBookmarked
276
     */
277 View Code Duplication
    public function testLocationShouldNotBeBookmarked()
278
    {
279
        $this->bookmarkHandler
280
            ->expects($this->once())
281
            ->method('loadByUserIdAndLocationId')
282
            ->with(self::CURRENT_USER_ID, [self::LOCATION_ID])
283
            ->willReturn([]);
284
285
        $this->assertFalse($this->createBookmarkService()->isBookmarked($this->createLocation(self::LOCATION_ID)));
286
    }
287
288
    /**
289
     * @covers \eZ\Publish\Core\Repository\BookmarkService::isBookmarked
290
     */
291 View Code Duplication
    public function testLocationShouldBeBookmarked()
292
    {
293
        $this->bookmarkHandler
294
            ->expects($this->once())
295
            ->method('loadByUserIdAndLocationId')
296
            ->with(self::CURRENT_USER_ID, [self::LOCATION_ID])
297
            ->willReturn([self::LOCATION_ID => new Bookmark()]);
298
299
        $this->assertTrue($this->createBookmarkService()->isBookmarked($this->createLocation(self::LOCATION_ID)));
300
    }
301
302
    private function assertLocationIsLoaded(Location $location): MockObject
303
    {
304
        $locationServiceMock = $this->createMock(LocationService::class);
305
        $locationServiceMock
306
            ->expects($this->once())
307
            ->method('loadLocation')
308
            ->willReturn($location);
309
310
        $repository = $this->getRepositoryMock();
311
        $repository
312
            ->expects($this->once())
313
            ->method('getLocationService')
314
            ->willReturn($locationServiceMock);
315
316
        return $locationServiceMock;
317
    }
318
319 View Code Duplication
    private function assertTransactionIsNotStarted(callable $operation): void
320
    {
321
        $repository = $this->getRepositoryMock();
322
        $repository->expects($this->never())->method('beginTransaction');
323
        $operation();
324
        $repository->expects($this->never())->method('commit');
325
        $repository->expects($this->never())->method('rollback');
326
    }
327
328 View Code Duplication
    private function assertTransactionIsCommitted(callable $operation): void
329
    {
330
        $repository = $this->getRepositoryMock();
331
        $repository->expects($this->once())->method('beginTransaction');
332
        $operation();
333
        $repository->expects($this->once())->method('commit');
334
        $repository->expects($this->never())->method('rollback');
335
    }
336
337 View Code Duplication
    private function assertTransactionIsRollback(callable $operation): void
338
    {
339
        $repository = $this->getRepositoryMock();
340
        $repository->expects($this->once())->method('beginTransaction');
341
        $operation();
342
        $repository->expects($this->never())->method('commit');
343
        $repository->expects($this->once())->method('rollback');
344
    }
345
346
    private function createLocation(int $id = self::CURRENT_USER_ID, string $name = 'Lorem ipsum...'): Location
347
    {
348
        return new Location([
349
            'id' => $id,
350
            'contentInfo' => new ContentInfo([
351
                'name' => $name,
352
            ]),
353
        ]);
354
    }
355
356
    /**
357
     * @return \eZ\Publish\API\Repository\BookmarkService|\PHPUnit\Framework\MockObject\MockObject
358
     */
359
    private function createBookmarkService(array $methods = null)
360
    {
361
        return $this
362
            ->getMockBuilder(BookmarkService::class)
363
            ->setConstructorArgs([$this->getRepositoryMock(), $this->bookmarkHandler])
364
            ->setMethods($methods)
365
            ->getMock();
366
    }
367
}
368