3 declare(strict_types
=1);
5 namespace Shaarli\Front\Controller
;
7 use PHPUnit\Framework\TestCase
;
8 use Shaarli\Bookmark\Bookmark
;
9 use Shaarli\Feed\CachedPage
;
10 use Slim\Http\Request
;
11 use Slim\Http\Response
;
13 class DailyControllerTest
extends TestCase
15 use FrontControllerMockHelper
;
17 /** @var DailyController */
18 protected $controller;
20 public function setUp(): void
22 $this->createContainer();
24 $this->controller
= new DailyController($this->container
);
25 DailyController
::$DAILY_RSS_NB_DAYS = 2;
28 public function testValidIndexControllerInvokeDefault(): void
30 $this->createValidContainerMockSet();
32 $currentDay = new \
DateTimeImmutable('2020-05-13');
34 $request = $this->createMock(Request
::class);
35 $request->method('getQueryParam')->willReturn($currentDay->format('Ymd'));
36 $response = new Response();
38 // Save RainTPL assigned variables
39 $assignedVariables = [];
40 $this->assignTemplateVars($assignedVariables);
42 // Links dataset: 2 links with thumbnails
43 $this->container
->bookmarkService
44 ->expects(static::once())
46 ->willReturnCallback(function () use ($currentDay): array {
49 $currentDay->format('Ymd'),
54 $this->container
->bookmarkService
55 ->expects(static::once())
57 ->willReturnCallback(function (): array {
61 ->setUrl('http://url.tld')
62 ->setTitle(static::generateContent(50))
63 ->setDescription(static::generateContent(500))
67 ->setUrl('http://url2.tld')
68 ->setTitle(static::generateContent(50))
69 ->setDescription(static::generateContent(500))
73 ->setUrl('http://url3.tld')
74 ->setTitle(static::generateContent(50))
75 ->setDescription(static::generateContent(500))
81 // Make sure that PluginManager hook is triggered
82 $this->container
->pluginManager
83 ->expects(static::at(0))
84 ->method('executeHooks')
85 ->willReturnCallback(function (string $hook, array $data, array $param) use ($currentDay): array {
86 static::assertSame('render_daily', $hook);
88 static::assertArrayHasKey('linksToDisplay', $data);
89 static::assertCount(3, $data['linksToDisplay']);
90 static::assertSame(1, $data['linksToDisplay'][0]['id']);
91 static::assertSame($currentDay->getTimestamp(), $data['day']);
92 static::assertSame('20200510', $data['previousday']);
93 static::assertSame('20200516', $data['nextday']);
95 static::assertArrayHasKey('loggedin', $param);
101 $result = $this->controller
->index($request, $response);
103 static::assertSame(200, $result->getStatusCode());
104 static::assertSame('daily', (string) $result->getBody());
106 'Daily - '. format_date($currentDay, false, true) .' - Shaarli',
107 $assignedVariables['pagetitle']
109 static::assertEquals($currentDay, $assignedVariables['dayDate']);
110 static::assertEquals($currentDay->getTimestamp(), $assignedVariables['day']);
111 static::assertCount(3, $assignedVariables['linksToDisplay']);
113 $link = $assignedVariables['linksToDisplay'][0];
115 static::assertSame(1, $link['id']);
116 static::assertSame('http://url.tld', $link['url']);
117 static::assertNotEmpty($link['title']);
118 static::assertNotEmpty($link['description']);
119 static::assertNotEmpty($link['formatedDescription']);
121 $link = $assignedVariables['linksToDisplay'][1];
123 static::assertSame(2, $link['id']);
124 static::assertSame('http://url2.tld', $link['url']);
125 static::assertNotEmpty($link['title']);
126 static::assertNotEmpty($link['description']);
127 static::assertNotEmpty($link['formatedDescription']);
129 $link = $assignedVariables['linksToDisplay'][2];
131 static::assertSame(3, $link['id']);
132 static::assertSame('http://url3.tld', $link['url']);
133 static::assertNotEmpty($link['title']);
134 static::assertNotEmpty($link['description']);
135 static::assertNotEmpty($link['formatedDescription']);
137 static::assertCount(3, $assignedVariables['cols']);
138 static::assertCount(1, $assignedVariables['cols'][0]);
139 static::assertCount(1, $assignedVariables['cols'][1]);
140 static::assertCount(1, $assignedVariables['cols'][2]);
142 $link = $assignedVariables['cols'][0][0];
144 static::assertSame(1, $link['id']);
145 static::assertSame('http://url.tld', $link['url']);
146 static::assertNotEmpty($link['title']);
147 static::assertNotEmpty($link['description']);
148 static::assertNotEmpty($link['formatedDescription']);
150 $link = $assignedVariables['cols'][1][0];
152 static::assertSame(2, $link['id']);
153 static::assertSame('http://url2.tld', $link['url']);
154 static::assertNotEmpty($link['title']);
155 static::assertNotEmpty($link['description']);
156 static::assertNotEmpty($link['formatedDescription']);
158 $link = $assignedVariables['cols'][2][0];
160 static::assertSame(3, $link['id']);
161 static::assertSame('http://url3.tld', $link['url']);
162 static::assertNotEmpty($link['title']);
163 static::assertNotEmpty($link['description']);
164 static::assertNotEmpty($link['formatedDescription']);
168 * Daily page - test that everything goes fine with no future or past bookmarks
170 public function testValidIndexControllerInvokeNoFutureOrPast(): void
172 $this->createValidContainerMockSet();
174 $currentDay = new \
DateTimeImmutable('2020-05-13');
176 $request = $this->createMock(Request
::class);
177 $response = new Response();
179 // Save RainTPL assigned variables
180 $assignedVariables = [];
181 $this->assignTemplateVars($assignedVariables);
183 // Links dataset: 2 links with thumbnails
184 $this->container
->bookmarkService
185 ->expects(static::once())
187 ->willReturnCallback(function () use ($currentDay): array {
189 $currentDay->format($currentDay->format('Ymd')),
193 $this->container
->bookmarkService
194 ->expects(static::once())
195 ->method('filterDay')
196 ->willReturnCallback(function (): array {
200 ->setUrl('http://url.tld')
201 ->setTitle(static::generateContent(50))
202 ->setDescription(static::generateContent(500))
208 // Make sure that PluginManager hook is triggered
209 $this->container
->pluginManager
210 ->expects(static::at(0))
211 ->method('executeHooks')
212 ->willReturnCallback(function (string $hook, array $data, array $param) use ($currentDay): array {
213 static::assertSame('render_daily', $hook);
215 static::assertArrayHasKey('linksToDisplay', $data);
216 static::assertCount(1, $data['linksToDisplay']);
217 static::assertSame(1, $data['linksToDisplay'][0]['id']);
218 static::assertSame($currentDay->getTimestamp(), $data['day']);
219 static::assertEmpty($data['previousday']);
220 static::assertEmpty($data['nextday']);
222 static::assertArrayHasKey('loggedin', $param);
227 $result = $this->controller
->index($request, $response);
229 static::assertSame(200, $result->getStatusCode());
230 static::assertSame('daily', (string) $result->getBody());
232 'Daily - '. format_date($currentDay, false, true) .' - Shaarli',
233 $assignedVariables['pagetitle']
235 static::assertCount(1, $assignedVariables['linksToDisplay']);
237 $link = $assignedVariables['linksToDisplay'][0];
238 static::assertSame(1, $link['id']);
242 * Daily page - test that height adjustment in columns is working
244 public function testValidIndexControllerInvokeHeightAdjustment(): void
246 $this->createValidContainerMockSet();
248 $currentDay = new \
DateTimeImmutable('2020-05-13');
250 $request = $this->createMock(Request
::class);
251 $response = new Response();
253 // Save RainTPL assigned variables
254 $assignedVariables = [];
255 $this->assignTemplateVars($assignedVariables);
257 // Links dataset: 2 links with thumbnails
258 $this->container
->bookmarkService
259 ->expects(static::once())
261 ->willReturnCallback(function () use ($currentDay): array {
263 $currentDay->format($currentDay->format('Ymd')),
267 $this->container
->bookmarkService
268 ->expects(static::once())
269 ->method('filterDay')
270 ->willReturnCallback(function (): array {
272 (new Bookmark())->setId(1)->setUrl('http://url.tld')->setTitle('title'),
275 ->setUrl('http://url.tld')
276 ->setTitle(static::generateContent(50))
277 ->setDescription(static::generateContent(5000))
279 (new Bookmark())->setId(3)->setUrl('http://url.tld')->setTitle('title'),
280 (new Bookmark())->setId(4)->setUrl('http://url.tld')->setTitle('title'),
281 (new Bookmark())->setId(5)->setUrl('http://url.tld')->setTitle('title'),
282 (new Bookmark())->setId(6)->setUrl('http://url.tld')->setTitle('title'),
283 (new Bookmark())->setId(7)->setUrl('http://url.tld')->setTitle('title'),
288 // Make sure that PluginManager hook is triggered
289 $this->container
->pluginManager
290 ->expects(static::at(0))
291 ->method('executeHooks')
292 ->willReturnCallback(function (string $hook, array $data, array $param): array {
297 $result = $this->controller
->index($request, $response);
299 static::assertSame(200, $result->getStatusCode());
300 static::assertSame('daily', (string) $result->getBody());
301 static::assertCount(7, $assignedVariables['linksToDisplay']);
303 $columnIds = function (array $column): array {
304 return array_map(function (array $item): int {
return $item
['id']; }, $column);
307 static::assertSame([1, 4, 6], $columnIds($assignedVariables['cols'][0]));
308 static::assertSame([2], $columnIds($assignedVariables['cols'][1]));
309 static::assertSame([3, 5, 7], $columnIds($assignedVariables['cols'][2]));
313 * Daily page - no bookmark
315 public function testValidIndexControllerInvokeNoBookmark(): void
317 $this->createValidContainerMockSet();
319 $request = $this->createMock(Request
::class);
320 $response = new Response();
322 // Save RainTPL assigned variables
323 $assignedVariables = [];
324 $this->assignTemplateVars($assignedVariables);
326 // Links dataset: 2 links with thumbnails
327 $this->container
->bookmarkService
328 ->expects(static::once())
330 ->willReturnCallback(function (): array {
334 $this->container
->bookmarkService
335 ->expects(static::once())
336 ->method('filterDay')
337 ->willReturnCallback(function (): array {
342 // Make sure that PluginManager hook is triggered
343 $this->container
->pluginManager
344 ->expects(static::at(0))
345 ->method('executeHooks')
346 ->willReturnCallback(function (string $hook, array $data, array $param): array {
351 $result = $this->controller
->index($request, $response);
353 static::assertSame(200, $result->getStatusCode());
354 static::assertSame('daily', (string) $result->getBody());
355 static::assertCount(0, $assignedVariables['linksToDisplay']);
356 static::assertSame('Today', $assignedVariables['dayDesc']);
357 static::assertEquals((new \
DateTime())->setTime(0, 0)->getTimestamp(), $assignedVariables['day']);
358 static::assertEquals((new \
DateTime())->setTime(0, 0), $assignedVariables['dayDate']);
362 * Daily RSS - default behaviour
364 public function testValidRssControllerInvokeDefault(): void
366 $this->createValidContainerMockSet();
369 new \
DateTimeImmutable('2020-05-17'),
370 new \
DateTimeImmutable('2020-05-15'),
371 new \
DateTimeImmutable('2020-05-13'),
374 $request = $this->createMock(Request
::class);
375 $response = new Response();
377 $this->container
->bookmarkService
->expects(static::once())->method('search')->willReturn([
378 (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'),
379 (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'),
380 (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'),
381 (new Bookmark())->setId(4)->setCreated($dates[2])->setUrl('http://domain.tld/4'),
384 $this->container
->pageCacheManager
385 ->expects(static::once())
386 ->method('getCachePage')
387 ->willReturnCallback(function (): CachedPage
{
388 $cachedPage = $this->createMock(CachedPage
::class);
389 $cachedPage->expects(static::once())->method('cache')->with('dailyrss');
395 // Save RainTPL assigned variables
396 $assignedVariables = [];
397 $this->assignTemplateVars($assignedVariables);
399 $result = $this->controller
->rss($request, $response);
401 static::assertSame(200, $result->getStatusCode());
402 static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]);
403 static::assertSame('dailyrss', (string) $result->getBody());
404 static::assertSame('Shaarli', $assignedVariables['title']);
405 static::assertSame('http://shaarli', $assignedVariables['index_url']);
406 static::assertSame('http://shaarli/daily-rss', $assignedVariables['page_url']);
407 static::assertFalse($assignedVariables['hide_timestamps']);
408 static::assertCount(2, $assignedVariables['days']);
410 $day = $assignedVariables['days'][$dates[0]->format('Ymd')];
412 static::assertEquals($dates[0], $day['date']);
413 static::assertSame($dates[0]->format(\DateTime
::RSS
), $day['date_rss']);
414 static::assertSame(format_date($dates[0], false), $day['date_human']);
415 static::assertSame('http://shaarli/daily?day='. $dates[0]->format('Ymd'), $day['absolute_url']);
416 static::assertCount(1, $day['links']);
417 static::assertSame(1, $day['links'][0]['id']);
418 static::assertSame('http://domain.tld/1', $day['links'][0]['url']);
419 static::assertEquals($dates[0], $day['links'][0]['created']);
421 $day = $assignedVariables['days'][$dates[1]->format('Ymd')];
423 static::assertEquals($dates[1], $day['date']);
424 static::assertSame($dates[1]->format(\DateTime
::RSS
), $day['date_rss']);
425 static::assertSame(format_date($dates[1], false), $day['date_human']);
426 static::assertSame('http://shaarli/daily?day='. $dates[1]->format('Ymd'), $day['absolute_url']);
427 static::assertCount(2, $day['links']);
429 static::assertSame(2, $day['links'][0]['id']);
430 static::assertSame('http://domain.tld/2', $day['links'][0]['url']);
431 static::assertEquals($dates[1], $day['links'][0]['created']);
432 static::assertSame(3, $day['links'][1]['id']);
433 static::assertSame('http://domain.tld/3', $day['links'][1]['url']);
434 static::assertEquals($dates[1], $day['links'][1]['created']);
438 * Daily RSS - trigger cache rendering
440 public function testValidRssControllerInvokeTriggerCache(): void
442 $this->createValidContainerMockSet();
444 $request = $this->createMock(Request
::class);
445 $response = new Response();
447 $this->container
->pageCacheManager
->method('getCachePage')->willReturnCallback(function (): CachedPage
{
448 $cachedPage = $this->createMock(CachedPage
::class);
449 $cachedPage->method('cachedVersion')->willReturn('this is cache!');
454 $this->container
->bookmarkService
->expects(static::never())->method('search');
456 $result = $this->controller
->rss($request, $response);
458 static::assertSame(200, $result->getStatusCode());
459 static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]);
460 static::assertSame('this is cache!', (string) $result->getBody());
464 * Daily RSS - No bookmark
466 public function testValidRssControllerInvokeNoBookmark(): void
468 $this->createValidContainerMockSet();
470 $request = $this->createMock(Request
::class);
471 $response = new Response();
473 $this->container
->bookmarkService
->expects(static::once())->method('search')->willReturn([]);
475 // Save RainTPL assigned variables
476 $assignedVariables = [];
477 $this->assignTemplateVars($assignedVariables);
479 $result = $this->controller
->rss($request, $response);
481 static::assertSame(200, $result->getStatusCode());
482 static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]);
483 static::assertSame('dailyrss', (string) $result->getBody());
484 static::assertSame('Shaarli', $assignedVariables['title']);
485 static::assertSame('http://shaarli', $assignedVariables['index_url']);
486 static::assertSame('http://shaarli/daily-rss', $assignedVariables['page_url']);
487 static::assertFalse($assignedVariables['hide_timestamps']);
488 static::assertCount(0, $assignedVariables['days']);
491 protected static function generateContent(int $length): string
493 // bin2hex(random_bytes) generates string twice as long as given parameter
494 $length = (int) ceil($length / 2);
495 return bin2hex(random_bytes($length));