3 declare(strict_types
=1);
5 namespace Shaarli\Front\Controller
;
7 use PHPUnit\Framework\TestCase
;
8 use Shaarli\Bookmark\Bookmark
;
9 use Shaarli\Bookmark\BookmarkServiceInterface
;
10 use Shaarli\Config\ConfigManager
;
11 use Shaarli\Container\ShaarliContainer
;
12 use Shaarli\Formatter\BookmarkFormatter
;
13 use Shaarli\Formatter\BookmarkRawFormatter
;
14 use Shaarli\Formatter\FormatterFactory
;
15 use Shaarli\Plugin\PluginManager
;
16 use Shaarli\Render\PageBuilder
;
17 use Shaarli\Security\LoginManager
;
18 use Slim\Http\Request
;
19 use Slim\Http\Response
;
21 class DailyControllerTest
extends TestCase
23 /** @var ShaarliContainer */
26 /** @var DailyController */
27 protected $controller;
29 public function setUp(): void
31 $this->container
= $this->createMock(ShaarliContainer
::class);
32 $this->controller
= new DailyController($this->container
);
35 public function testValidControllerInvokeDefault(): void
37 $this->createValidContainerMockSet();
39 $currentDay = new \
DateTimeImmutable('2020-05-13');
41 $request = $this->createMock(Request
::class);
42 $request->method('getQueryParam')->willReturn($currentDay->format('Ymd'));
43 $response = new Response();
45 // Save RainTPL assigned variables
46 $assignedVariables = [];
47 $this->assignTemplateVars($assignedVariables);
49 // Links dataset: 2 links with thumbnails
50 $this->container
->bookmarkService
51 ->expects(static::once())
53 ->willReturnCallback(function () use ($currentDay): array {
56 $currentDay->format('Ymd'),
61 $this->container
->bookmarkService
62 ->expects(static::once())
64 ->willReturnCallback(function (): array {
68 ->setUrl('http://url.tld')
69 ->setTitle(static::generateContent(50))
70 ->setDescription(static::generateContent(500))
74 ->setUrl('http://url2.tld')
75 ->setTitle(static::generateContent(50))
76 ->setDescription(static::generateContent(500))
80 ->setUrl('http://url3.tld')
81 ->setTitle(static::generateContent(50))
82 ->setDescription(static::generateContent(500))
88 // Make sure that PluginManager hook is triggered
89 $this->container
->pluginManager
90 ->expects(static::at(0))
91 ->method('executeHooks')
92 ->willReturnCallback(function (string $hook, array $data, array $param) use ($currentDay): array {
93 static::assertSame('render_daily', $hook);
95 static::assertArrayHasKey('linksToDisplay', $data);
96 static::assertCount(3, $data['linksToDisplay']);
97 static::assertSame(1, $data['linksToDisplay'][0]['id']);
98 static::assertSame($currentDay->getTimestamp(), $data['day']);
99 static::assertSame('20200510', $data['previousday']);
100 static::assertSame('20200516', $data['nextday']);
102 static::assertArrayHasKey('loggedin', $param);
107 $result = $this->controller
->index($request, $response);
109 static::assertSame(200, $result->getStatusCode());
110 static::assertSame('daily', (string) $result->getBody());
112 'Daily - '. format_date($currentDay, false, true) .' - Shaarli',
113 $assignedVariables['pagetitle']
115 static::assertEquals($currentDay, $assignedVariables['dayDate']);
116 static::assertEquals($currentDay->getTimestamp(), $assignedVariables['day']);
117 static::assertCount(3, $assignedVariables['linksToDisplay']);
119 $link = $assignedVariables['linksToDisplay'][0];
121 static::assertSame(1, $link['id']);
122 static::assertSame('http://url.tld', $link['url']);
123 static::assertNotEmpty($link['title']);
124 static::assertNotEmpty($link['description']);
125 static::assertNotEmpty($link['formatedDescription']);
127 $link = $assignedVariables['linksToDisplay'][1];
129 static::assertSame(2, $link['id']);
130 static::assertSame('http://url2.tld', $link['url']);
131 static::assertNotEmpty($link['title']);
132 static::assertNotEmpty($link['description']);
133 static::assertNotEmpty($link['formatedDescription']);
135 $link = $assignedVariables['linksToDisplay'][2];
137 static::assertSame(3, $link['id']);
138 static::assertSame('http://url3.tld', $link['url']);
139 static::assertNotEmpty($link['title']);
140 static::assertNotEmpty($link['description']);
141 static::assertNotEmpty($link['formatedDescription']);
143 static::assertCount(3, $assignedVariables['cols']);
144 static::assertCount(1, $assignedVariables['cols'][0]);
145 static::assertCount(1, $assignedVariables['cols'][1]);
146 static::assertCount(1, $assignedVariables['cols'][2]);
148 $link = $assignedVariables['cols'][0][0];
150 static::assertSame(1, $link['id']);
151 static::assertSame('http://url.tld', $link['url']);
152 static::assertNotEmpty($link['title']);
153 static::assertNotEmpty($link['description']);
154 static::assertNotEmpty($link['formatedDescription']);
156 $link = $assignedVariables['cols'][1][0];
158 static::assertSame(2, $link['id']);
159 static::assertSame('http://url2.tld', $link['url']);
160 static::assertNotEmpty($link['title']);
161 static::assertNotEmpty($link['description']);
162 static::assertNotEmpty($link['formatedDescription']);
164 $link = $assignedVariables['cols'][2][0];
166 static::assertSame(3, $link['id']);
167 static::assertSame('http://url3.tld', $link['url']);
168 static::assertNotEmpty($link['title']);
169 static::assertNotEmpty($link['description']);
170 static::assertNotEmpty($link['formatedDescription']);
174 * Daily page - test that everything goes fine with no future or past bookmarks
176 public function testValidControllerInvokeNoFutureOrPast(): void
178 $this->createValidContainerMockSet();
180 $currentDay = new \
DateTimeImmutable('2020-05-13');
182 $request = $this->createMock(Request
::class);
183 $response = new Response();
185 // Save RainTPL assigned variables
186 $assignedVariables = [];
187 $this->assignTemplateVars($assignedVariables);
189 // Links dataset: 2 links with thumbnails
190 $this->container
->bookmarkService
191 ->expects(static::once())
193 ->willReturnCallback(function () use ($currentDay): array {
195 $currentDay->format($currentDay->format('Ymd')),
199 $this->container
->bookmarkService
200 ->expects(static::once())
201 ->method('filterDay')
202 ->willReturnCallback(function (): array {
206 ->setUrl('http://url.tld')
207 ->setTitle(static::generateContent(50))
208 ->setDescription(static::generateContent(500))
214 // Make sure that PluginManager hook is triggered
215 $this->container
->pluginManager
216 ->expects(static::at(0))
217 ->method('executeHooks')
218 ->willReturnCallback(function (string $hook, array $data, array $param) use ($currentDay): array {
219 static::assertSame('render_daily', $hook);
221 static::assertArrayHasKey('linksToDisplay', $data);
222 static::assertCount(1, $data['linksToDisplay']);
223 static::assertSame(1, $data['linksToDisplay'][0]['id']);
224 static::assertSame($currentDay->getTimestamp(), $data['day']);
225 static::assertEmpty($data['previousday']);
226 static::assertEmpty($data['nextday']);
228 static::assertArrayHasKey('loggedin', $param);
233 $result = $this->controller
->index($request, $response);
235 static::assertSame(200, $result->getStatusCode());
236 static::assertSame('daily', (string) $result->getBody());
238 'Daily - '. format_date($currentDay, false, true) .' - Shaarli',
239 $assignedVariables['pagetitle']
241 static::assertCount(1, $assignedVariables['linksToDisplay']);
243 $link = $assignedVariables['linksToDisplay'][0];
244 static::assertSame(1, $link['id']);
248 * Daily page - test that height adjustment in columns is working
250 public function testValidControllerInvokeHeightAdjustment(): void
252 $this->createValidContainerMockSet();
254 $currentDay = new \
DateTimeImmutable('2020-05-13');
256 $request = $this->createMock(Request
::class);
257 $response = new Response();
259 // Save RainTPL assigned variables
260 $assignedVariables = [];
261 $this->assignTemplateVars($assignedVariables);
263 // Links dataset: 2 links with thumbnails
264 $this->container
->bookmarkService
265 ->expects(static::once())
267 ->willReturnCallback(function () use ($currentDay): array {
269 $currentDay->format($currentDay->format('Ymd')),
273 $this->container
->bookmarkService
274 ->expects(static::once())
275 ->method('filterDay')
276 ->willReturnCallback(function (): array {
278 (new Bookmark())->setId(1)->setUrl('http://url.tld')->setTitle('title'),
281 ->setUrl('http://url.tld')
282 ->setTitle(static::generateContent(50))
283 ->setDescription(static::generateContent(5000))
285 (new Bookmark())->setId(3)->setUrl('http://url.tld')->setTitle('title'),
286 (new Bookmark())->setId(4)->setUrl('http://url.tld')->setTitle('title'),
287 (new Bookmark())->setId(5)->setUrl('http://url.tld')->setTitle('title'),
288 (new Bookmark())->setId(6)->setUrl('http://url.tld')->setTitle('title'),
289 (new Bookmark())->setId(7)->setUrl('http://url.tld')->setTitle('title'),
294 // Make sure that PluginManager hook is triggered
295 $this->container
->pluginManager
296 ->expects(static::at(0))
297 ->method('executeHooks')
298 ->willReturnCallback(function (string $hook, array $data, array $param): array {
303 $result = $this->controller
->index($request, $response);
305 static::assertSame(200, $result->getStatusCode());
306 static::assertSame('daily', (string) $result->getBody());
307 static::assertCount(7, $assignedVariables['linksToDisplay']);
309 $columnIds = function (array $column): array {
310 return array_map(function (array $item): int {
return $item
['id']; }, $column);
313 static::assertSame([1, 4, 6], $columnIds($assignedVariables['cols'][0]));
314 static::assertSame([2], $columnIds($assignedVariables['cols'][1]));
315 static::assertSame([3, 5, 7], $columnIds($assignedVariables['cols'][2]));
319 * Daily page - no bookmark
321 public function testValidControllerInvokeNoBookmark(): void
323 $this->createValidContainerMockSet();
325 $request = $this->createMock(Request
::class);
326 $response = new Response();
328 // Save RainTPL assigned variables
329 $assignedVariables = [];
330 $this->assignTemplateVars($assignedVariables);
332 // Links dataset: 2 links with thumbnails
333 $this->container
->bookmarkService
334 ->expects(static::once())
336 ->willReturnCallback(function (): array {
340 $this->container
->bookmarkService
341 ->expects(static::once())
342 ->method('filterDay')
343 ->willReturnCallback(function (): array {
348 // Make sure that PluginManager hook is triggered
349 $this->container
->pluginManager
350 ->expects(static::at(0))
351 ->method('executeHooks')
352 ->willReturnCallback(function (string $hook, array $data, array $param): array {
357 $result = $this->controller
->index($request, $response);
359 static::assertSame(200, $result->getStatusCode());
360 static::assertSame('daily', (string) $result->getBody());
361 static::assertCount(0, $assignedVariables['linksToDisplay']);
362 static::assertSame('Today', $assignedVariables['dayDesc']);
363 static::assertEquals((new \
DateTime())->setTime(0, 0)->getTimestamp(), $assignedVariables['day']);
364 static::assertEquals((new \
DateTime())->setTime(0, 0), $assignedVariables['dayDate']);
367 protected function createValidContainerMockSet(): void
369 $loginManager = $this->createMock(LoginManager
::class);
370 $this->container
->loginManager
= $loginManager;
373 $conf = $this->createMock(ConfigManager
::class);
374 $this->container
->conf
= $conf;
375 $this->container
->conf
->method('get')->willReturnCallback(function (string $parameter, $default) {
380 $pageBuilder = $this->createMock(PageBuilder
::class);
383 ->willReturnCallback(function (string $template): string {
387 $this->container
->pageBuilder
= $pageBuilder;
390 $pluginManager = $this->createMock(PluginManager
::class);
391 $this->container
->pluginManager
= $pluginManager;
394 $bookmarkService = $this->createMock(BookmarkServiceInterface
::class);
395 $this->container
->bookmarkService
= $bookmarkService;
398 $formatterFactory = $this->createMock(FormatterFactory
::class);
400 ->method('getFormatter')
401 ->willReturnCallback(function (): BookmarkFormatter
{
402 return new BookmarkRawFormatter($this->container
->conf
, true);
405 $this->container
->formatterFactory
= $formatterFactory;
408 protected function assignTemplateVars(array &$variables): void
410 $this->container
->pageBuilder
411 ->expects(static::atLeastOnce())
413 ->willReturnCallback(function ($key, $value) use (&$variables) {
414 $variables[$key] = $value;
421 protected static function generateContent(int $length): string
423 // bin2hex(random_bytes) generates string twice as long as given parameter
424 $length = (int) ceil($length / 2);
425 return bin2hex(random_bytes($length));