]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - tests/front/controller/DailyControllerTest.php
Process OpenSearch controller through Slim
[github/shaarli/Shaarli.git] / tests / front / controller / DailyControllerTest.php
CommitLineData
69e29ff6
A
1<?php
2
3declare(strict_types=1);
4
5namespace Shaarli\Front\Controller;
6
7use PHPUnit\Framework\TestCase;
8use Shaarli\Bookmark\Bookmark;
9use Shaarli\Bookmark\BookmarkServiceInterface;
10use Shaarli\Config\ConfigManager;
11use Shaarli\Container\ShaarliContainer;
c4d5be53 12use Shaarli\Feed\CachedPage;
69e29ff6
A
13use Shaarli\Formatter\BookmarkFormatter;
14use Shaarli\Formatter\BookmarkRawFormatter;
15use Shaarli\Formatter\FormatterFactory;
16use Shaarli\Plugin\PluginManager;
17use Shaarli\Render\PageBuilder;
c4d5be53 18use Shaarli\Render\PageCacheManager;
69e29ff6
A
19use Shaarli\Security\LoginManager;
20use Slim\Http\Request;
21use Slim\Http\Response;
22
23class DailyControllerTest extends TestCase
24{
25 /** @var ShaarliContainer */
26 protected $container;
27
28 /** @var DailyController */
29 protected $controller;
30
31 public function setUp(): void
32 {
33 $this->container = $this->createMock(ShaarliContainer::class);
34 $this->controller = new DailyController($this->container);
c4d5be53 35 DailyController::$DAILY_RSS_NB_DAYS = 2;
69e29ff6
A
36 }
37
c4d5be53 38 public function testValidIndexControllerInvokeDefault(): void
69e29ff6
A
39 {
40 $this->createValidContainerMockSet();
41
42 $currentDay = new \DateTimeImmutable('2020-05-13');
43
44 $request = $this->createMock(Request::class);
45 $request->method('getQueryParam')->willReturn($currentDay->format('Ymd'));
46 $response = new Response();
47
48 // Save RainTPL assigned variables
49 $assignedVariables = [];
50 $this->assignTemplateVars($assignedVariables);
51
52 // Links dataset: 2 links with thumbnails
53 $this->container->bookmarkService
54 ->expects(static::once())
55 ->method('days')
56 ->willReturnCallback(function () use ($currentDay): array {
57 return [
58 '20200510',
59 $currentDay->format('Ymd'),
60 '20200516',
61 ];
62 })
63 ;
64 $this->container->bookmarkService
65 ->expects(static::once())
66 ->method('filterDay')
67 ->willReturnCallback(function (): array {
68 return [
69 (new Bookmark())
70 ->setId(1)
71 ->setUrl('http://url.tld')
72 ->setTitle(static::generateContent(50))
73 ->setDescription(static::generateContent(500))
74 ,
75 (new Bookmark())
76 ->setId(2)
77 ->setUrl('http://url2.tld')
78 ->setTitle(static::generateContent(50))
79 ->setDescription(static::generateContent(500))
80 ,
81 (new Bookmark())
82 ->setId(3)
83 ->setUrl('http://url3.tld')
84 ->setTitle(static::generateContent(50))
85 ->setDescription(static::generateContent(500))
86 ,
87 ];
88 })
89 ;
90
91 // Make sure that PluginManager hook is triggered
92 $this->container->pluginManager
93 ->expects(static::at(0))
94 ->method('executeHooks')
95 ->willReturnCallback(function (string $hook, array $data, array $param) use ($currentDay): array {
96 static::assertSame('render_daily', $hook);
97
98 static::assertArrayHasKey('linksToDisplay', $data);
99 static::assertCount(3, $data['linksToDisplay']);
100 static::assertSame(1, $data['linksToDisplay'][0]['id']);
101 static::assertSame($currentDay->getTimestamp(), $data['day']);
102 static::assertSame('20200510', $data['previousday']);
103 static::assertSame('20200516', $data['nextday']);
104
105 static::assertArrayHasKey('loggedin', $param);
106
107 return $data;
108 });
109
110 $result = $this->controller->index($request, $response);
111
112 static::assertSame(200, $result->getStatusCode());
113 static::assertSame('daily', (string) $result->getBody());
114 static::assertSame(
115 'Daily - '. format_date($currentDay, false, true) .' - Shaarli',
116 $assignedVariables['pagetitle']
117 );
e3d28be9
A
118 static::assertEquals($currentDay, $assignedVariables['dayDate']);
119 static::assertEquals($currentDay->getTimestamp(), $assignedVariables['day']);
69e29ff6
A
120 static::assertCount(3, $assignedVariables['linksToDisplay']);
121
122 $link = $assignedVariables['linksToDisplay'][0];
123
124 static::assertSame(1, $link['id']);
125 static::assertSame('http://url.tld', $link['url']);
126 static::assertNotEmpty($link['title']);
127 static::assertNotEmpty($link['description']);
128 static::assertNotEmpty($link['formatedDescription']);
129
130 $link = $assignedVariables['linksToDisplay'][1];
131
132 static::assertSame(2, $link['id']);
133 static::assertSame('http://url2.tld', $link['url']);
134 static::assertNotEmpty($link['title']);
135 static::assertNotEmpty($link['description']);
136 static::assertNotEmpty($link['formatedDescription']);
137
138 $link = $assignedVariables['linksToDisplay'][2];
139
140 static::assertSame(3, $link['id']);
141 static::assertSame('http://url3.tld', $link['url']);
142 static::assertNotEmpty($link['title']);
143 static::assertNotEmpty($link['description']);
144 static::assertNotEmpty($link['formatedDescription']);
145
146 static::assertCount(3, $assignedVariables['cols']);
147 static::assertCount(1, $assignedVariables['cols'][0]);
148 static::assertCount(1, $assignedVariables['cols'][1]);
149 static::assertCount(1, $assignedVariables['cols'][2]);
150
151 $link = $assignedVariables['cols'][0][0];
152
153 static::assertSame(1, $link['id']);
154 static::assertSame('http://url.tld', $link['url']);
155 static::assertNotEmpty($link['title']);
156 static::assertNotEmpty($link['description']);
157 static::assertNotEmpty($link['formatedDescription']);
158
159 $link = $assignedVariables['cols'][1][0];
160
161 static::assertSame(2, $link['id']);
162 static::assertSame('http://url2.tld', $link['url']);
163 static::assertNotEmpty($link['title']);
164 static::assertNotEmpty($link['description']);
165 static::assertNotEmpty($link['formatedDescription']);
166
167 $link = $assignedVariables['cols'][2][0];
168
169 static::assertSame(3, $link['id']);
170 static::assertSame('http://url3.tld', $link['url']);
171 static::assertNotEmpty($link['title']);
172 static::assertNotEmpty($link['description']);
173 static::assertNotEmpty($link['formatedDescription']);
174 }
175
176 /**
177 * Daily page - test that everything goes fine with no future or past bookmarks
178 */
c4d5be53 179 public function testValidIndexControllerInvokeNoFutureOrPast(): void
69e29ff6
A
180 {
181 $this->createValidContainerMockSet();
182
183 $currentDay = new \DateTimeImmutable('2020-05-13');
184
185 $request = $this->createMock(Request::class);
186 $response = new Response();
187
188 // Save RainTPL assigned variables
189 $assignedVariables = [];
190 $this->assignTemplateVars($assignedVariables);
191
192 // Links dataset: 2 links with thumbnails
193 $this->container->bookmarkService
194 ->expects(static::once())
195 ->method('days')
196 ->willReturnCallback(function () use ($currentDay): array {
197 return [
198 $currentDay->format($currentDay->format('Ymd')),
199 ];
200 })
201 ;
202 $this->container->bookmarkService
203 ->expects(static::once())
204 ->method('filterDay')
205 ->willReturnCallback(function (): array {
206 return [
207 (new Bookmark())
208 ->setId(1)
209 ->setUrl('http://url.tld')
210 ->setTitle(static::generateContent(50))
211 ->setDescription(static::generateContent(500))
212 ,
213 ];
214 })
215 ;
216
217 // Make sure that PluginManager hook is triggered
218 $this->container->pluginManager
219 ->expects(static::at(0))
220 ->method('executeHooks')
221 ->willReturnCallback(function (string $hook, array $data, array $param) use ($currentDay): array {
222 static::assertSame('render_daily', $hook);
223
224 static::assertArrayHasKey('linksToDisplay', $data);
225 static::assertCount(1, $data['linksToDisplay']);
226 static::assertSame(1, $data['linksToDisplay'][0]['id']);
227 static::assertSame($currentDay->getTimestamp(), $data['day']);
228 static::assertEmpty($data['previousday']);
229 static::assertEmpty($data['nextday']);
230
231 static::assertArrayHasKey('loggedin', $param);
232
233 return $data;
234 });
235
236 $result = $this->controller->index($request, $response);
237
238 static::assertSame(200, $result->getStatusCode());
239 static::assertSame('daily', (string) $result->getBody());
240 static::assertSame(
241 'Daily - '. format_date($currentDay, false, true) .' - Shaarli',
242 $assignedVariables['pagetitle']
243 );
244 static::assertCount(1, $assignedVariables['linksToDisplay']);
245
246 $link = $assignedVariables['linksToDisplay'][0];
247 static::assertSame(1, $link['id']);
248 }
249
250 /**
251 * Daily page - test that height adjustment in columns is working
252 */
c4d5be53 253 public function testValidIndexControllerInvokeHeightAdjustment(): void
69e29ff6
A
254 {
255 $this->createValidContainerMockSet();
256
257 $currentDay = new \DateTimeImmutable('2020-05-13');
258
259 $request = $this->createMock(Request::class);
260 $response = new Response();
261
262 // Save RainTPL assigned variables
263 $assignedVariables = [];
264 $this->assignTemplateVars($assignedVariables);
265
266 // Links dataset: 2 links with thumbnails
267 $this->container->bookmarkService
268 ->expects(static::once())
269 ->method('days')
270 ->willReturnCallback(function () use ($currentDay): array {
271 return [
272 $currentDay->format($currentDay->format('Ymd')),
273 ];
274 })
275 ;
276 $this->container->bookmarkService
277 ->expects(static::once())
278 ->method('filterDay')
279 ->willReturnCallback(function (): array {
280 return [
281 (new Bookmark())->setId(1)->setUrl('http://url.tld')->setTitle('title'),
282 (new Bookmark())
283 ->setId(2)
284 ->setUrl('http://url.tld')
285 ->setTitle(static::generateContent(50))
286 ->setDescription(static::generateContent(5000))
287 ,
288 (new Bookmark())->setId(3)->setUrl('http://url.tld')->setTitle('title'),
289 (new Bookmark())->setId(4)->setUrl('http://url.tld')->setTitle('title'),
290 (new Bookmark())->setId(5)->setUrl('http://url.tld')->setTitle('title'),
291 (new Bookmark())->setId(6)->setUrl('http://url.tld')->setTitle('title'),
292 (new Bookmark())->setId(7)->setUrl('http://url.tld')->setTitle('title'),
293 ];
294 })
295 ;
296
297 // Make sure that PluginManager hook is triggered
298 $this->container->pluginManager
299 ->expects(static::at(0))
300 ->method('executeHooks')
301 ->willReturnCallback(function (string $hook, array $data, array $param): array {
302 return $data;
303 })
304 ;
305
306 $result = $this->controller->index($request, $response);
307
308 static::assertSame(200, $result->getStatusCode());
309 static::assertSame('daily', (string) $result->getBody());
310 static::assertCount(7, $assignedVariables['linksToDisplay']);
311
312 $columnIds = function (array $column): array {
313 return array_map(function (array $item): int { return $item['id']; }, $column);
314 };
315
316 static::assertSame([1, 4, 6], $columnIds($assignedVariables['cols'][0]));
317 static::assertSame([2], $columnIds($assignedVariables['cols'][1]));
318 static::assertSame([3, 5, 7], $columnIds($assignedVariables['cols'][2]));
319 }
320
321 /**
322 * Daily page - no bookmark
323 */
c4d5be53 324 public function testValidIndexControllerInvokeNoBookmark(): void
69e29ff6
A
325 {
326 $this->createValidContainerMockSet();
327
328 $request = $this->createMock(Request::class);
329 $response = new Response();
330
331 // Save RainTPL assigned variables
332 $assignedVariables = [];
333 $this->assignTemplateVars($assignedVariables);
334
335 // Links dataset: 2 links with thumbnails
336 $this->container->bookmarkService
337 ->expects(static::once())
338 ->method('days')
339 ->willReturnCallback(function (): array {
340 return [];
341 })
342 ;
343 $this->container->bookmarkService
344 ->expects(static::once())
345 ->method('filterDay')
346 ->willReturnCallback(function (): array {
347 return [];
348 })
349 ;
350
351 // Make sure that PluginManager hook is triggered
352 $this->container->pluginManager
353 ->expects(static::at(0))
354 ->method('executeHooks')
355 ->willReturnCallback(function (string $hook, array $data, array $param): array {
356 return $data;
357 })
358 ;
359
360 $result = $this->controller->index($request, $response);
361
362 static::assertSame(200, $result->getStatusCode());
363 static::assertSame('daily', (string) $result->getBody());
364 static::assertCount(0, $assignedVariables['linksToDisplay']);
365 static::assertSame('Today', $assignedVariables['dayDesc']);
e3d28be9
A
366 static::assertEquals((new \DateTime())->setTime(0, 0)->getTimestamp(), $assignedVariables['day']);
367 static::assertEquals((new \DateTime())->setTime(0, 0), $assignedVariables['dayDate']);
69e29ff6
A
368 }
369
c4d5be53
A
370 /**
371 * Daily RSS - default behaviour
372 */
373 public function testValidRssControllerInvokeDefault(): void
374 {
375 $this->createValidContainerMockSet();
376
377 $dates = [
378 new \DateTimeImmutable('2020-05-17'),
379 new \DateTimeImmutable('2020-05-15'),
380 new \DateTimeImmutable('2020-05-13'),
381 ];
382
383 $request = $this->createMock(Request::class);
384 $response = new Response();
385
386 $this->container->bookmarkService->expects(static::once())->method('search')->willReturn([
387 (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'),
388 (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'),
389 (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'),
390 (new Bookmark())->setId(4)->setCreated($dates[2])->setUrl('http://domain.tld/4'),
391 ]);
392
393 $this->container->pageCacheManager
394 ->expects(static::once())
395 ->method('getCachePage')
396 ->willReturnCallback(function (): CachedPage {
397 $cachedPage = $this->createMock(CachedPage::class);
398 $cachedPage->expects(static::once())->method('cache')->with('dailyrss');
399
400 return $cachedPage;
401 }
402 );
403
404 // Save RainTPL assigned variables
405 $assignedVariables = [];
406 $this->assignTemplateVars($assignedVariables);
407
408 $result = $this->controller->rss($request, $response);
409
410 static::assertSame(200, $result->getStatusCode());
411 static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]);
412 static::assertSame('dailyrss', (string) $result->getBody());
413 static::assertSame('Shaarli', $assignedVariables['title']);
414 static::assertSame('http://shaarli', $assignedVariables['index_url']);
415 static::assertSame('http://shaarli/daily-rss', $assignedVariables['page_url']);
416 static::assertFalse($assignedVariables['hide_timestamps']);
417 static::assertCount(2, $assignedVariables['days']);
418
419 $day = $assignedVariables['days'][$dates[0]->format('Ymd')];
420
421 static::assertEquals($dates[0], $day['date']);
029ada5a 422 static::assertSame($dates[0]->format(\DateTime::RSS), $day['date_rss']);
c4d5be53
A
423 static::assertSame(format_date($dates[0], false), $day['date_human']);
424 static::assertSame('http://shaarli/daily?day='. $dates[0]->format('Ymd'), $day['absolute_url']);
425 static::assertCount(1, $day['links']);
426 static::assertSame(1, $day['links'][0]['id']);
427 static::assertSame('http://domain.tld/1', $day['links'][0]['url']);
428 static::assertEquals($dates[0], $day['links'][0]['created']);
429
430 $day = $assignedVariables['days'][$dates[1]->format('Ymd')];
431
432 static::assertEquals($dates[1], $day['date']);
029ada5a 433 static::assertSame($dates[1]->format(\DateTime::RSS), $day['date_rss']);
c4d5be53
A
434 static::assertSame(format_date($dates[1], false), $day['date_human']);
435 static::assertSame('http://shaarli/daily?day='. $dates[1]->format('Ymd'), $day['absolute_url']);
436 static::assertCount(2, $day['links']);
437
438 static::assertSame(2, $day['links'][0]['id']);
439 static::assertSame('http://domain.tld/2', $day['links'][0]['url']);
440 static::assertEquals($dates[1], $day['links'][0]['created']);
441 static::assertSame(3, $day['links'][1]['id']);
442 static::assertSame('http://domain.tld/3', $day['links'][1]['url']);
443 static::assertEquals($dates[1], $day['links'][1]['created']);
444 }
445
446 /**
447 * Daily RSS - trigger cache rendering
448 */
449 public function testValidRssControllerInvokeTriggerCache(): void
450 {
451 $this->createValidContainerMockSet();
452
453 $request = $this->createMock(Request::class);
454 $response = new Response();
455
456 $this->container->pageCacheManager->method('getCachePage')->willReturnCallback(function (): CachedPage {
457 $cachedPage = $this->createMock(CachedPage::class);
458 $cachedPage->method('cachedVersion')->willReturn('this is cache!');
459
460 return $cachedPage;
461 });
462
463 $this->container->bookmarkService->expects(static::never())->method('search');
464
465 $result = $this->controller->rss($request, $response);
466
467 static::assertSame(200, $result->getStatusCode());
468 static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]);
469 static::assertSame('this is cache!', (string) $result->getBody());
470 }
471
472 /**
473 * Daily RSS - No bookmark
474 */
475 public function testValidRssControllerInvokeNoBookmark(): void
476 {
477 $this->createValidContainerMockSet();
478
479 $request = $this->createMock(Request::class);
480 $response = new Response();
481
482 $this->container->bookmarkService->expects(static::once())->method('search')->willReturn([]);
483
484 // Save RainTPL assigned variables
485 $assignedVariables = [];
486 $this->assignTemplateVars($assignedVariables);
487
488 $result = $this->controller->rss($request, $response);
489
490 static::assertSame(200, $result->getStatusCode());
491 static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]);
492 static::assertSame('dailyrss', (string) $result->getBody());
493 static::assertSame('Shaarli', $assignedVariables['title']);
494 static::assertSame('http://shaarli', $assignedVariables['index_url']);
495 static::assertSame('http://shaarli/daily-rss', $assignedVariables['page_url']);
496 static::assertFalse($assignedVariables['hide_timestamps']);
497 static::assertCount(0, $assignedVariables['days']);
498 }
499
69e29ff6
A
500 protected function createValidContainerMockSet(): void
501 {
502 $loginManager = $this->createMock(LoginManager::class);
503 $this->container->loginManager = $loginManager;
504
505 // Config
506 $conf = $this->createMock(ConfigManager::class);
507 $this->container->conf = $conf;
508 $this->container->conf->method('get')->willReturnCallback(function (string $parameter, $default) {
509 return $default;
510 });
511
512 // PageBuilder
513 $pageBuilder = $this->createMock(PageBuilder::class);
514 $pageBuilder
515 ->method('render')
516 ->willReturnCallback(function (string $template): string {
517 return $template;
518 })
519 ;
520 $this->container->pageBuilder = $pageBuilder;
521
522 // Plugin Manager
523 $pluginManager = $this->createMock(PluginManager::class);
524 $this->container->pluginManager = $pluginManager;
525
526 // BookmarkService
527 $bookmarkService = $this->createMock(BookmarkServiceInterface::class);
528 $this->container->bookmarkService = $bookmarkService;
529
530 // Formatter
531 $formatterFactory = $this->createMock(FormatterFactory::class);
532 $formatterFactory
533 ->method('getFormatter')
534 ->willReturnCallback(function (): BookmarkFormatter {
535 return new BookmarkRawFormatter($this->container->conf, true);
536 })
537 ;
538 $this->container->formatterFactory = $formatterFactory;
c4d5be53
A
539
540 // CacheManager
541 $pageCacheManager = $this->createMock(PageCacheManager::class);
542 $this->container->pageCacheManager = $pageCacheManager;
543
544 // $_SERVER
545 $this->container->environment = [
546 'SERVER_NAME' => 'shaarli',
547 'SERVER_PORT' => '80',
548 'REQUEST_URI' => '/daily-rss',
549 ];
69e29ff6
A
550 }
551
552 protected function assignTemplateVars(array &$variables): void
553 {
554 $this->container->pageBuilder
555 ->expects(static::atLeastOnce())
556 ->method('assign')
557 ->willReturnCallback(function ($key, $value) use (&$variables) {
558 $variables[$key] = $value;
559
560 return $this;
561 })
562 ;
563 }
564
565 protected static function generateContent(int $length): string
566 {
567 // bin2hex(random_bytes) generates string twice as long as given parameter
568 $length = (int) ceil($length / 2);
569 return bin2hex(random_bytes($length));
570 }
571}