diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/container/ShaarliTestContainer.php | 4 | ||||
-rw-r--r-- | tests/front/controller/admin/PostBookmarkControllerTest.php | 652 |
2 files changed, 656 insertions, 0 deletions
diff --git a/tests/container/ShaarliTestContainer.php b/tests/container/ShaarliTestContainer.php index 53197ae6..7dbe914c 100644 --- a/tests/container/ShaarliTestContainer.php +++ b/tests/container/ShaarliTestContainer.php | |||
@@ -10,11 +10,13 @@ use Shaarli\Config\ConfigManager; | |||
10 | use Shaarli\Feed\FeedBuilder; | 10 | use Shaarli\Feed\FeedBuilder; |
11 | use Shaarli\Formatter\FormatterFactory; | 11 | use Shaarli\Formatter\FormatterFactory; |
12 | use Shaarli\History; | 12 | use Shaarli\History; |
13 | use Shaarli\Http\HttpAccess; | ||
13 | use Shaarli\Plugin\PluginManager; | 14 | use Shaarli\Plugin\PluginManager; |
14 | use Shaarli\Render\PageBuilder; | 15 | use Shaarli\Render\PageBuilder; |
15 | use Shaarli\Render\PageCacheManager; | 16 | use Shaarli\Render\PageCacheManager; |
16 | use Shaarli\Security\LoginManager; | 17 | use Shaarli\Security\LoginManager; |
17 | use Shaarli\Security\SessionManager; | 18 | use Shaarli\Security\SessionManager; |
19 | use Shaarli\Thumbnailer; | ||
18 | 20 | ||
19 | /** | 21 | /** |
20 | * Test helper allowing auto-completion for MockObjects. | 22 | * Test helper allowing auto-completion for MockObjects. |
@@ -31,6 +33,8 @@ use Shaarli\Security\SessionManager; | |||
31 | * @property MockObject|FormatterFactory $formatterFactory | 33 | * @property MockObject|FormatterFactory $formatterFactory |
32 | * @property MockObject|PageCacheManager $pageCacheManager | 34 | * @property MockObject|PageCacheManager $pageCacheManager |
33 | * @property MockObject|FeedBuilder $feedBuilder | 35 | * @property MockObject|FeedBuilder $feedBuilder |
36 | * @property MockObject|Thumbnailer $thumbnailer | ||
37 | * @property MockObject|HttpAccess $httpAccess | ||
34 | */ | 38 | */ |
35 | class ShaarliTestContainer extends ShaarliContainer | 39 | class ShaarliTestContainer extends ShaarliContainer |
36 | { | 40 | { |
diff --git a/tests/front/controller/admin/PostBookmarkControllerTest.php b/tests/front/controller/admin/PostBookmarkControllerTest.php new file mode 100644 index 00000000..f00a15c9 --- /dev/null +++ b/tests/front/controller/admin/PostBookmarkControllerTest.php | |||
@@ -0,0 +1,652 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Front\Controller\Admin; | ||
6 | |||
7 | use PHPUnit\Framework\TestCase; | ||
8 | use Shaarli\Bookmark\Bookmark; | ||
9 | use Shaarli\Config\ConfigManager; | ||
10 | use Shaarli\Front\Exception\WrongTokenException; | ||
11 | use Shaarli\Http\HttpAccess; | ||
12 | use Shaarli\Security\SessionManager; | ||
13 | use Shaarli\Thumbnailer; | ||
14 | use Slim\Http\Request; | ||
15 | use Slim\Http\Response; | ||
16 | use Slim\Http\Uri; | ||
17 | |||
18 | class PostBookmarkControllerTest extends TestCase | ||
19 | { | ||
20 | use FrontAdminControllerMockHelper; | ||
21 | |||
22 | /** @var PostBookmarkController */ | ||
23 | protected $controller; | ||
24 | |||
25 | public function setUp(): void | ||
26 | { | ||
27 | $this->createContainer(); | ||
28 | |||
29 | $this->container->httpAccess = $this->createMock(HttpAccess::class); | ||
30 | $this->controller = new PostBookmarkController($this->container); | ||
31 | } | ||
32 | |||
33 | /** | ||
34 | * Test displaying add link page | ||
35 | */ | ||
36 | public function testAddShaare(): void | ||
37 | { | ||
38 | $assignedVariables = []; | ||
39 | $this->assignTemplateVars($assignedVariables); | ||
40 | |||
41 | $request = $this->createMock(Request::class); | ||
42 | $response = new Response(); | ||
43 | |||
44 | $result = $this->controller->addShaare($request, $response); | ||
45 | |||
46 | static::assertSame(200, $result->getStatusCode()); | ||
47 | static::assertSame('addlink', (string) $result->getBody()); | ||
48 | |||
49 | static::assertSame('Shaare a new link - Shaarli', $assignedVariables['pagetitle']); | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * Test displaying bookmark create form | ||
54 | * Ensure that every step of the standard workflow works properly. | ||
55 | */ | ||
56 | public function testDisplayCreateFormWithUrl(): void | ||
57 | { | ||
58 | $this->container->environment = [ | ||
59 | 'HTTP_REFERER' => $referer = 'http://shaarli/subfolder/controller/?searchtag=abc' | ||
60 | ]; | ||
61 | |||
62 | $assignedVariables = []; | ||
63 | $this->assignTemplateVars($assignedVariables); | ||
64 | |||
65 | $url = 'http://url.tld/other?part=3&utm_ad=pay#hash'; | ||
66 | $expectedUrl = str_replace('&utm_ad=pay', '', $url); | ||
67 | $remoteTitle = 'Remote Title'; | ||
68 | $remoteDesc = 'Sometimes the meta description is relevant.'; | ||
69 | $remoteTags = 'abc def'; | ||
70 | |||
71 | $request = $this->createMock(Request::class); | ||
72 | $request->method('getParam')->willReturnCallback(function (string $key) use ($url): ?string { | ||
73 | return $key === 'post' ? $url : null; | ||
74 | }); | ||
75 | $response = new Response(); | ||
76 | |||
77 | $this->container->httpAccess | ||
78 | ->expects(static::once()) | ||
79 | ->method('getCurlDownloadCallback') | ||
80 | ->willReturnCallback( | ||
81 | function (&$charset, &$title, &$description, &$tags) use ( | ||
82 | $remoteTitle, | ||
83 | $remoteDesc, | ||
84 | $remoteTags | ||
85 | ): callable { | ||
86 | return function () use ( | ||
87 | &$charset, | ||
88 | &$title, | ||
89 | &$description, | ||
90 | &$tags, | ||
91 | $remoteTitle, | ||
92 | $remoteDesc, | ||
93 | $remoteTags | ||
94 | ): void { | ||
95 | $charset = 'ISO-8859-1'; | ||
96 | $title = $remoteTitle; | ||
97 | $description = $remoteDesc; | ||
98 | $tags = $remoteTags; | ||
99 | }; | ||
100 | } | ||
101 | ) | ||
102 | ; | ||
103 | $this->container->httpAccess | ||
104 | ->expects(static::once()) | ||
105 | ->method('getHttpResponse') | ||
106 | ->with($expectedUrl, 30, 4194304) | ||
107 | ->willReturnCallback(function($url, $timeout, $maxBytes, $callback): void { | ||
108 | $callback(); | ||
109 | }) | ||
110 | ; | ||
111 | |||
112 | $this->container->bookmarkService | ||
113 | ->expects(static::once()) | ||
114 | ->method('bookmarksCountPerTag') | ||
115 | ->willReturn($tags = ['tag1' => 2, 'tag2' => 1]) | ||
116 | ; | ||
117 | |||
118 | // Make sure that PluginManager hook is triggered | ||
119 | $this->container->pluginManager | ||
120 | ->expects(static::at(0)) | ||
121 | ->method('executeHooks') | ||
122 | ->willReturnCallback(function (string $hook, array $data) use ($remoteTitle, $remoteDesc): array { | ||
123 | static::assertSame('render_editlink', $hook); | ||
124 | static::assertSame($remoteTitle, $data['link']['title']); | ||
125 | static::assertSame($remoteDesc, $data['link']['description']); | ||
126 | |||
127 | return $data; | ||
128 | }) | ||
129 | ; | ||
130 | |||
131 | $result = $this->controller->displayCreateForm($request, $response); | ||
132 | |||
133 | static::assertSame(200, $result->getStatusCode()); | ||
134 | static::assertSame('editlink', (string) $result->getBody()); | ||
135 | |||
136 | static::assertSame('Shaare - Shaarli', $assignedVariables['pagetitle']); | ||
137 | |||
138 | static::assertSame($expectedUrl, $assignedVariables['link']['url']); | ||
139 | static::assertSame($remoteTitle, $assignedVariables['link']['title']); | ||
140 | static::assertSame($remoteDesc, $assignedVariables['link']['description']); | ||
141 | static::assertSame($remoteTags, $assignedVariables['link']['tags']); | ||
142 | static::assertFalse($assignedVariables['link']['private']); | ||
143 | |||
144 | static::assertTrue($assignedVariables['link_is_new']); | ||
145 | static::assertSame($referer, $assignedVariables['http_referer']); | ||
146 | static::assertSame($tags, $assignedVariables['tags']); | ||
147 | static::assertArrayHasKey('source', $assignedVariables); | ||
148 | static::assertArrayHasKey('default_private_links', $assignedVariables); | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * Test displaying bookmark create form | ||
153 | * Ensure all available query parameters are handled properly. | ||
154 | */ | ||
155 | public function testDisplayCreateFormWithFullParameters(): void | ||
156 | { | ||
157 | $assignedVariables = []; | ||
158 | $this->assignTemplateVars($assignedVariables); | ||
159 | |||
160 | $parameters = [ | ||
161 | 'post' => 'http://url.tld/other?part=3&utm_ad=pay#hash', | ||
162 | 'title' => 'Provided Title', | ||
163 | 'description' => 'Provided description.', | ||
164 | 'tags' => 'abc def', | ||
165 | 'private' => '1', | ||
166 | 'source' => 'apps', | ||
167 | ]; | ||
168 | $expectedUrl = str_replace('&utm_ad=pay', '', $parameters['post']); | ||
169 | |||
170 | $request = $this->createMock(Request::class); | ||
171 | $request | ||
172 | ->method('getParam') | ||
173 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
174 | return $parameters[$key] ?? null; | ||
175 | }); | ||
176 | $response = new Response(); | ||
177 | |||
178 | $result = $this->controller->displayCreateForm($request, $response); | ||
179 | |||
180 | static::assertSame(200, $result->getStatusCode()); | ||
181 | static::assertSame('editlink', (string) $result->getBody()); | ||
182 | |||
183 | static::assertSame('Shaare - Shaarli', $assignedVariables['pagetitle']); | ||
184 | |||
185 | static::assertSame($expectedUrl, $assignedVariables['link']['url']); | ||
186 | static::assertSame($parameters['title'], $assignedVariables['link']['title']); | ||
187 | static::assertSame($parameters['description'], $assignedVariables['link']['description']); | ||
188 | static::assertSame($parameters['tags'], $assignedVariables['link']['tags']); | ||
189 | static::assertTrue($assignedVariables['link']['private']); | ||
190 | static::assertTrue($assignedVariables['link_is_new']); | ||
191 | static::assertSame($parameters['source'], $assignedVariables['source']); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * Test displaying bookmark create form | ||
196 | * Without any parameter. | ||
197 | */ | ||
198 | public function testDisplayCreateFormEmpty(): void | ||
199 | { | ||
200 | $assignedVariables = []; | ||
201 | $this->assignTemplateVars($assignedVariables); | ||
202 | |||
203 | $request = $this->createMock(Request::class); | ||
204 | $response = new Response(); | ||
205 | |||
206 | $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); | ||
207 | $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); | ||
208 | |||
209 | $result = $this->controller->displayCreateForm($request, $response); | ||
210 | |||
211 | static::assertSame(200, $result->getStatusCode()); | ||
212 | static::assertSame('editlink', (string) $result->getBody()); | ||
213 | static::assertSame('', $assignedVariables['link']['url']); | ||
214 | static::assertSame('Note: ', $assignedVariables['link']['title']); | ||
215 | static::assertSame('', $assignedVariables['link']['description']); | ||
216 | static::assertSame('', $assignedVariables['link']['tags']); | ||
217 | static::assertFalse($assignedVariables['link']['private']); | ||
218 | static::assertTrue($assignedVariables['link_is_new']); | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * Test displaying bookmark create form | ||
223 | * URL not using HTTP protocol: do not try to retrieve the title | ||
224 | */ | ||
225 | public function testDisplayCreateFormNotHttp(): void | ||
226 | { | ||
227 | $assignedVariables = []; | ||
228 | $this->assignTemplateVars($assignedVariables); | ||
229 | |||
230 | $url = 'magnet://kubuntu.torrent'; | ||
231 | $request = $this->createMock(Request::class); | ||
232 | $request | ||
233 | ->method('getParam') | ||
234 | ->willReturnCallback(function (string $key) use ($url): ?string { | ||
235 | return $key === 'post' ? $url : null; | ||
236 | }); | ||
237 | $response = new Response(); | ||
238 | |||
239 | $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); | ||
240 | $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); | ||
241 | |||
242 | $result = $this->controller->displayCreateForm($request, $response); | ||
243 | |||
244 | static::assertSame(200, $result->getStatusCode()); | ||
245 | static::assertSame('editlink', (string) $result->getBody()); | ||
246 | static::assertSame($url, $assignedVariables['link']['url']); | ||
247 | static::assertTrue($assignedVariables['link_is_new']); | ||
248 | } | ||
249 | |||
250 | /** | ||
251 | * Test displaying bookmark create form | ||
252 | * When markdown formatter is enabled, the no markdown tag should be added to existing tags. | ||
253 | */ | ||
254 | public function testDisplayCreateFormWithMarkdownEnabled(): void | ||
255 | { | ||
256 | $assignedVariables = []; | ||
257 | $this->assignTemplateVars($assignedVariables); | ||
258 | |||
259 | $this->container->conf = $this->createMock(ConfigManager::class); | ||
260 | $this->container->conf | ||
261 | ->expects(static::atLeastOnce()) | ||
262 | ->method('get')->willReturnCallback(function (string $key): ?string { | ||
263 | if ($key === 'formatter') { | ||
264 | return 'markdown'; | ||
265 | } | ||
266 | |||
267 | return $key; | ||
268 | }) | ||
269 | ; | ||
270 | |||
271 | $request = $this->createMock(Request::class); | ||
272 | $response = new Response(); | ||
273 | |||
274 | $result = $this->controller->displayCreateForm($request, $response); | ||
275 | |||
276 | static::assertSame(200, $result->getStatusCode()); | ||
277 | static::assertSame('editlink', (string) $result->getBody()); | ||
278 | static::assertSame(['nomarkdown' => 1], $assignedVariables['tags']); | ||
279 | } | ||
280 | |||
281 | /** | ||
282 | * Test displaying bookmark create form | ||
283 | * When an existing URL is submitted, we want to edit the existing link. | ||
284 | */ | ||
285 | public function testDisplayCreateFormWithExistingUrl(): void | ||
286 | { | ||
287 | $assignedVariables = []; | ||
288 | $this->assignTemplateVars($assignedVariables); | ||
289 | |||
290 | $url = 'http://url.tld/other?part=3&utm_ad=pay#hash'; | ||
291 | $expectedUrl = str_replace('&utm_ad=pay', '', $url); | ||
292 | |||
293 | $request = $this->createMock(Request::class); | ||
294 | $request | ||
295 | ->method('getParam') | ||
296 | ->willReturnCallback(function (string $key) use ($url): ?string { | ||
297 | return $key === 'post' ? $url : null; | ||
298 | }); | ||
299 | $response = new Response(); | ||
300 | |||
301 | $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); | ||
302 | $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); | ||
303 | |||
304 | $this->container->bookmarkService | ||
305 | ->expects(static::once()) | ||
306 | ->method('findByUrl') | ||
307 | ->with($expectedUrl) | ||
308 | ->willReturn( | ||
309 | (new Bookmark()) | ||
310 | ->setId($id = 23) | ||
311 | ->setUrl($expectedUrl) | ||
312 | ->setTitle($title = 'Bookmark Title') | ||
313 | ->setDescription($description = 'Bookmark description.') | ||
314 | ->setTags($tags = ['abc', 'def']) | ||
315 | ->setPrivate(true) | ||
316 | ->setCreated($createdAt = new \DateTime('2020-06-10 18:45:44')) | ||
317 | ) | ||
318 | ; | ||
319 | |||
320 | $result = $this->controller->displayCreateForm($request, $response); | ||
321 | |||
322 | static::assertSame(200, $result->getStatusCode()); | ||
323 | static::assertSame('editlink', (string) $result->getBody()); | ||
324 | |||
325 | static::assertSame('Edit Shaare - Shaarli', $assignedVariables['pagetitle']); | ||
326 | static::assertFalse($assignedVariables['link_is_new']); | ||
327 | |||
328 | static::assertSame($id, $assignedVariables['link']['id']); | ||
329 | static::assertSame($expectedUrl, $assignedVariables['link']['url']); | ||
330 | static::assertSame($title, $assignedVariables['link']['title']); | ||
331 | static::assertSame($description, $assignedVariables['link']['description']); | ||
332 | static::assertSame(implode(' ', $tags), $assignedVariables['link']['tags']); | ||
333 | static::assertTrue($assignedVariables['link']['private']); | ||
334 | static::assertSame($createdAt, $assignedVariables['link']['created']); | ||
335 | } | ||
336 | |||
337 | /** | ||
338 | * Test displaying bookmark edit form | ||
339 | * When an existing ID is provided, ensure that default workflow works properly. | ||
340 | */ | ||
341 | public function testDisplayEditFormDefault(): void | ||
342 | { | ||
343 | $assignedVariables = []; | ||
344 | $this->assignTemplateVars($assignedVariables); | ||
345 | |||
346 | $id = 11; | ||
347 | |||
348 | $request = $this->createMock(Request::class); | ||
349 | $response = new Response(); | ||
350 | |||
351 | $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); | ||
352 | $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); | ||
353 | |||
354 | $this->container->bookmarkService | ||
355 | ->expects(static::once()) | ||
356 | ->method('get') | ||
357 | ->with($id) | ||
358 | ->willReturn( | ||
359 | (new Bookmark()) | ||
360 | ->setId($id) | ||
361 | ->setUrl($url = 'http://domain.tld') | ||
362 | ->setTitle($title = 'Bookmark Title') | ||
363 | ->setDescription($description = 'Bookmark description.') | ||
364 | ->setTags($tags = ['abc', 'def']) | ||
365 | ->setPrivate(true) | ||
366 | ->setCreated($createdAt = new \DateTime('2020-06-10 18:45:44')) | ||
367 | ) | ||
368 | ; | ||
369 | |||
370 | $result = $this->controller->displayEditForm($request, $response, ['id' => (string) $id]); | ||
371 | |||
372 | static::assertSame(200, $result->getStatusCode()); | ||
373 | static::assertSame('editlink', (string) $result->getBody()); | ||
374 | |||
375 | static::assertSame('Edit Shaare - Shaarli', $assignedVariables['pagetitle']); | ||
376 | static::assertFalse($assignedVariables['link_is_new']); | ||
377 | |||
378 | static::assertSame($id, $assignedVariables['link']['id']); | ||
379 | static::assertSame($url, $assignedVariables['link']['url']); | ||
380 | static::assertSame($title, $assignedVariables['link']['title']); | ||
381 | static::assertSame($description, $assignedVariables['link']['description']); | ||
382 | static::assertSame(implode(' ', $tags), $assignedVariables['link']['tags']); | ||
383 | static::assertTrue($assignedVariables['link']['private']); | ||
384 | static::assertSame($createdAt, $assignedVariables['link']['created']); | ||
385 | } | ||
386 | |||
387 | /** | ||
388 | * Test save a new bookmark | ||
389 | */ | ||
390 | public function testSaveBookmark(): void | ||
391 | { | ||
392 | $id = 21; | ||
393 | $parameters = [ | ||
394 | 'lf_url' => 'http://url.tld/other?part=3#hash', | ||
395 | 'lf_title' => 'Provided Title', | ||
396 | 'lf_description' => 'Provided description.', | ||
397 | 'lf_tags' => 'abc def', | ||
398 | 'lf_private' => '1', | ||
399 | 'returnurl' => 'http://shaarli.tld/subfolder/add-shaare' | ||
400 | ]; | ||
401 | |||
402 | $request = $this->createMock(Request::class); | ||
403 | $request | ||
404 | ->method('getParam') | ||
405 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
406 | return $parameters[$key] ?? null; | ||
407 | }) | ||
408 | ; | ||
409 | $request->method('getUri')->willReturnCallback(function (): Uri { | ||
410 | $uri = $this->createMock(Uri::class); | ||
411 | $uri->method('getBasePath')->willReturn('/subfolder'); | ||
412 | |||
413 | return $uri; | ||
414 | }); | ||
415 | $response = new Response(); | ||
416 | |||
417 | $checkBookmark = function (Bookmark $bookmark) use ($parameters) { | ||
418 | static::assertSame($parameters['lf_url'], $bookmark->getUrl()); | ||
419 | static::assertSame($parameters['lf_title'], $bookmark->getTitle()); | ||
420 | static::assertSame($parameters['lf_description'], $bookmark->getDescription()); | ||
421 | static::assertSame($parameters['lf_tags'], $bookmark->getTagsString()); | ||
422 | static::assertTrue($bookmark->isPrivate()); | ||
423 | }; | ||
424 | |||
425 | $this->container->bookmarkService | ||
426 | ->expects(static::once()) | ||
427 | ->method('addOrSet') | ||
428 | ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void { | ||
429 | static::assertFalse($save); | ||
430 | |||
431 | $checkBookmark($bookmark); | ||
432 | |||
433 | $bookmark->setId($id); | ||
434 | }) | ||
435 | ; | ||
436 | $this->container->bookmarkService | ||
437 | ->expects(static::once()) | ||
438 | ->method('set') | ||
439 | ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void { | ||
440 | static::assertTrue($save); | ||
441 | |||
442 | $checkBookmark($bookmark); | ||
443 | |||
444 | static::assertSame($id, $bookmark->getId()); | ||
445 | }) | ||
446 | ; | ||
447 | |||
448 | // Make sure that PluginManager hook is triggered | ||
449 | $this->container->pluginManager | ||
450 | ->expects(static::at(0)) | ||
451 | ->method('executeHooks') | ||
452 | ->willReturnCallback(function (string $hook, array $data) use ($parameters, $id): array { | ||
453 | static::assertSame('save_link', $hook); | ||
454 | |||
455 | static::assertSame($id, $data['id']); | ||
456 | static::assertSame($parameters['lf_url'], $data['url']); | ||
457 | static::assertSame($parameters['lf_title'], $data['title']); | ||
458 | static::assertSame($parameters['lf_description'], $data['description']); | ||
459 | static::assertSame($parameters['lf_tags'], $data['tags']); | ||
460 | static::assertTrue($data['private']); | ||
461 | |||
462 | return $data; | ||
463 | }) | ||
464 | ; | ||
465 | |||
466 | $result = $this->controller->save($request, $response); | ||
467 | |||
468 | static::assertSame(302, $result->getStatusCode()); | ||
469 | static::assertRegExp('@/subfolder/#\w{6}@', $result->getHeader('location')[0]); | ||
470 | } | ||
471 | |||
472 | |||
473 | /** | ||
474 | * Test save an existing bookmark | ||
475 | */ | ||
476 | public function testSaveExistingBookmark(): void | ||
477 | { | ||
478 | $id = 21; | ||
479 | $parameters = [ | ||
480 | 'lf_id' => (string) $id, | ||
481 | 'lf_url' => 'http://url.tld/other?part=3#hash', | ||
482 | 'lf_title' => 'Provided Title', | ||
483 | 'lf_description' => 'Provided description.', | ||
484 | 'lf_tags' => 'abc def', | ||
485 | 'lf_private' => '1', | ||
486 | 'returnurl' => 'http://shaarli.tld/subfolder/?page=2' | ||
487 | ]; | ||
488 | |||
489 | $request = $this->createMock(Request::class); | ||
490 | $request | ||
491 | ->method('getParam') | ||
492 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
493 | return $parameters[$key] ?? null; | ||
494 | }) | ||
495 | ; | ||
496 | $request->method('getUri')->willReturnCallback(function (): Uri { | ||
497 | $uri = $this->createMock(Uri::class); | ||
498 | $uri->method('getBasePath')->willReturn('/subfolder'); | ||
499 | |||
500 | return $uri; | ||
501 | }); | ||
502 | $response = new Response(); | ||
503 | |||
504 | $checkBookmark = function (Bookmark $bookmark) use ($parameters, $id) { | ||
505 | static::assertSame($id, $bookmark->getId()); | ||
506 | static::assertSame($parameters['lf_url'], $bookmark->getUrl()); | ||
507 | static::assertSame($parameters['lf_title'], $bookmark->getTitle()); | ||
508 | static::assertSame($parameters['lf_description'], $bookmark->getDescription()); | ||
509 | static::assertSame($parameters['lf_tags'], $bookmark->getTagsString()); | ||
510 | static::assertTrue($bookmark->isPrivate()); | ||
511 | }; | ||
512 | |||
513 | $this->container->bookmarkService->expects(static::atLeastOnce())->method('exists')->willReturn(true); | ||
514 | $this->container->bookmarkService | ||
515 | ->expects(static::once()) | ||
516 | ->method('get') | ||
517 | ->willReturn((new Bookmark())->setId($id)->setUrl('http://other.url')) | ||
518 | ; | ||
519 | $this->container->bookmarkService | ||
520 | ->expects(static::once()) | ||
521 | ->method('addOrSet') | ||
522 | ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void { | ||
523 | static::assertFalse($save); | ||
524 | |||
525 | $checkBookmark($bookmark); | ||
526 | }) | ||
527 | ; | ||
528 | $this->container->bookmarkService | ||
529 | ->expects(static::once()) | ||
530 | ->method('set') | ||
531 | ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void { | ||
532 | static::assertTrue($save); | ||
533 | |||
534 | $checkBookmark($bookmark); | ||
535 | |||
536 | static::assertSame($id, $bookmark->getId()); | ||
537 | }) | ||
538 | ; | ||
539 | |||
540 | // Make sure that PluginManager hook is triggered | ||
541 | $this->container->pluginManager | ||
542 | ->expects(static::at(0)) | ||
543 | ->method('executeHooks') | ||
544 | ->willReturnCallback(function (string $hook, array $data) use ($parameters, $id): array { | ||
545 | static::assertSame('save_link', $hook); | ||
546 | |||
547 | static::assertSame($id, $data['id']); | ||
548 | static::assertSame($parameters['lf_url'], $data['url']); | ||
549 | static::assertSame($parameters['lf_title'], $data['title']); | ||
550 | static::assertSame($parameters['lf_description'], $data['description']); | ||
551 | static::assertSame($parameters['lf_tags'], $data['tags']); | ||
552 | static::assertTrue($data['private']); | ||
553 | |||
554 | return $data; | ||
555 | }) | ||
556 | ; | ||
557 | |||
558 | $result = $this->controller->save($request, $response); | ||
559 | |||
560 | static::assertSame(302, $result->getStatusCode()); | ||
561 | static::assertRegExp('@/subfolder/\?page=2#\w{6}@', $result->getHeader('location')[0]); | ||
562 | } | ||
563 | |||
564 | /** | ||
565 | * Test save a bookmark - try to retrieve the thumbnail | ||
566 | */ | ||
567 | public function testSaveBookmarkWithThumbnail(): void | ||
568 | { | ||
569 | $parameters = ['lf_url' => 'http://url.tld/other?part=3#hash']; | ||
570 | |||
571 | $request = $this->createMock(Request::class); | ||
572 | $request | ||
573 | ->method('getParam') | ||
574 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
575 | return $parameters[$key] ?? null; | ||
576 | }) | ||
577 | ; | ||
578 | $request->method('getUri')->willReturnCallback(function (): Uri { | ||
579 | $uri = $this->createMock(Uri::class); | ||
580 | $uri->method('getBasePath')->willReturn('/subfolder'); | ||
581 | |||
582 | return $uri; | ||
583 | }); | ||
584 | $response = new Response(); | ||
585 | |||
586 | $this->container->conf = $this->createMock(ConfigManager::class); | ||
587 | $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { | ||
588 | return $key === 'thumbnails.mode' ? Thumbnailer::MODE_ALL : $default; | ||
589 | }); | ||
590 | |||
591 | $this->container->thumbnailer = $this->createMock(Thumbnailer::class); | ||
592 | $this->container->thumbnailer | ||
593 | ->expects(static::once()) | ||
594 | ->method('get') | ||
595 | ->with($parameters['lf_url']) | ||
596 | ->willReturn($thumb = 'http://thumb.url') | ||
597 | ; | ||
598 | |||
599 | $this->container->bookmarkService | ||
600 | ->expects(static::once()) | ||
601 | ->method('addOrSet') | ||
602 | ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($thumb): void { | ||
603 | static::assertSame($thumb, $bookmark->getThumbnail()); | ||
604 | }) | ||
605 | ; | ||
606 | |||
607 | $result = $this->controller->save($request, $response); | ||
608 | |||
609 | static::assertSame(302, $result->getStatusCode()); | ||
610 | } | ||
611 | |||
612 | /** | ||
613 | * Change the password with a wrong existing password | ||
614 | */ | ||
615 | public function testSaveBookmarkFromBookmarklet(): void | ||
616 | { | ||
617 | $parameters = ['source' => 'bookmarklet']; | ||
618 | |||
619 | $request = $this->createMock(Request::class); | ||
620 | $request | ||
621 | ->method('getParam') | ||
622 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
623 | return $parameters[$key] ?? null; | ||
624 | }) | ||
625 | ; | ||
626 | $response = new Response(); | ||
627 | |||
628 | $result = $this->controller->save($request, $response); | ||
629 | |||
630 | static::assertSame(200, $result->getStatusCode()); | ||
631 | static::assertSame('<script>self.close();</script>', (string) $result->getBody()); | ||
632 | } | ||
633 | |||
634 | /** | ||
635 | * Change the password with a wrong existing password | ||
636 | */ | ||
637 | public function testSaveBookmarkWrongToken(): void | ||
638 | { | ||
639 | $this->container->sessionManager = $this->createMock(SessionManager::class); | ||
640 | $this->container->sessionManager->method('checkToken')->willReturn(false); | ||
641 | |||
642 | $this->container->bookmarkService->expects(static::never())->method('addOrSet'); | ||
643 | $this->container->bookmarkService->expects(static::never())->method('set'); | ||
644 | |||
645 | $request = $this->createMock(Request::class); | ||
646 | $response = new Response(); | ||
647 | |||
648 | $this->expectException(WrongTokenException::class); | ||
649 | |||
650 | $this->controller->save($request, $response); | ||
651 | } | ||
652 | } | ||