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::assertCount(3, $assignedVariables['linksToDisplay']);
117 $link = $assignedVariables['linksToDisplay'][0];
119 static::assertSame(1, $link['id']);
120 static::assertSame('http://url.tld', $link['url']);
121 static::assertNotEmpty($link['title']);
122 static::assertNotEmpty($link['description']);
123 static::assertNotEmpty($link['formatedDescription']);
125 $link = $assignedVariables['linksToDisplay'][1];
127 static::assertSame(2, $link['id']);
128 static::assertSame('http://url2.tld', $link['url']);
129 static::assertNotEmpty($link['title']);
130 static::assertNotEmpty($link['description']);
131 static::assertNotEmpty($link['formatedDescription']);
133 $link = $assignedVariables['linksToDisplay'][2];
135 static::assertSame(3, $link['id']);
136 static::assertSame('http://url3.tld', $link['url']);
137 static::assertNotEmpty($link['title']);
138 static::assertNotEmpty($link['description']);
139 static::assertNotEmpty($link['formatedDescription']);
141 static::assertCount(3, $assignedVariables['cols']);
142 static::assertCount(1, $assignedVariables['cols'][0]);
143 static::assertCount(1, $assignedVariables['cols'][1]);
144 static::assertCount(1, $assignedVariables['cols'][2]);
146 $link = $assignedVariables['cols'][0][0];
148 static::assertSame(1, $link['id']);
149 static::assertSame('http://url.tld', $link['url']);
150 static::assertNotEmpty($link['title']);
151 static::assertNotEmpty($link['description']);
152 static::assertNotEmpty($link['formatedDescription']);
154 $link = $assignedVariables['cols'][1][0];
156 static::assertSame(2, $link['id']);
157 static::assertSame('http://url2.tld', $link['url']);
158 static::assertNotEmpty($link['title']);
159 static::assertNotEmpty($link['description']);
160 static::assertNotEmpty($link['formatedDescription']);
162 $link = $assignedVariables['cols'][2][0];
164 static::assertSame(3, $link['id']);
165 static::assertSame('http://url3.tld', $link['url']);
166 static::assertNotEmpty($link['title']);
167 static::assertNotEmpty($link['description']);
168 static::assertNotEmpty($link['formatedDescription']);
172 * Daily page - test that everything goes fine with no future or past bookmarks
174 public function testValidControllerInvokeNoFutureOrPast(): void
176 $this->createValidContainerMockSet();
178 $currentDay = new \
DateTimeImmutable('2020-05-13');
180 $request = $this->createMock(Request
::class);
181 $response = new Response();
183 // Save RainTPL assigned variables
184 $assignedVariables = [];
185 $this->assignTemplateVars($assignedVariables);
187 // Links dataset: 2 links with thumbnails
188 $this->container
->bookmarkService
189 ->expects(static::once())
191 ->willReturnCallback(function () use ($currentDay): array {
193 $currentDay->format($currentDay->format('Ymd')),
197 $this->container
->bookmarkService
198 ->expects(static::once())
199 ->method('filterDay')
200 ->willReturnCallback(function (): array {
204 ->setUrl('http://url.tld')
205 ->setTitle(static::generateContent(50))
206 ->setDescription(static::generateContent(500))
212 // Make sure that PluginManager hook is triggered
213 $this->container
->pluginManager
214 ->expects(static::at(0))
215 ->method('executeHooks')
216 ->willReturnCallback(function (string $hook, array $data, array $param) use ($currentDay): array {
217 static::assertSame('render_daily', $hook);
219 static::assertArrayHasKey('linksToDisplay', $data);
220 static::assertCount(1, $data['linksToDisplay']);
221 static::assertSame(1, $data['linksToDisplay'][0]['id']);
222 static::assertSame($currentDay->getTimestamp(), $data['day']);
223 static::assertEmpty($data['previousday']);
224 static::assertEmpty($data['nextday']);
226 static::assertArrayHasKey('loggedin', $param);
231 $result = $this->controller
->index($request, $response);
233 static::assertSame(200, $result->getStatusCode());
234 static::assertSame('daily', (string) $result->getBody());
236 'Daily - '. format_date($currentDay, false, true) .' - Shaarli',
237 $assignedVariables['pagetitle']
239 static::assertCount(1, $assignedVariables['linksToDisplay']);
241 $link = $assignedVariables['linksToDisplay'][0];
242 static::assertSame(1, $link['id']);
246 * Daily page - test that height adjustment in columns is working
248 public function testValidControllerInvokeHeightAdjustment(): void
250 $this->createValidContainerMockSet();
252 $currentDay = new \
DateTimeImmutable('2020-05-13');
254 $request = $this->createMock(Request
::class);
255 $response = new Response();
257 // Save RainTPL assigned variables
258 $assignedVariables = [];
259 $this->assignTemplateVars($assignedVariables);
261 // Links dataset: 2 links with thumbnails
262 $this->container
->bookmarkService
263 ->expects(static::once())
265 ->willReturnCallback(function () use ($currentDay): array {
267 $currentDay->format($currentDay->format('Ymd')),
271 $this->container
->bookmarkService
272 ->expects(static::once())
273 ->method('filterDay')
274 ->willReturnCallback(function (): array {
276 (new Bookmark())->setId(1)->setUrl('http://url.tld')->setTitle('title'),
279 ->setUrl('http://url.tld')
280 ->setTitle(static::generateContent(50))
281 ->setDescription(static::generateContent(5000))
283 (new Bookmark())->setId(3)->setUrl('http://url.tld')->setTitle('title'),
284 (new Bookmark())->setId(4)->setUrl('http://url.tld')->setTitle('title'),
285 (new Bookmark())->setId(5)->setUrl('http://url.tld')->setTitle('title'),
286 (new Bookmark())->setId(6)->setUrl('http://url.tld')->setTitle('title'),
287 (new Bookmark())->setId(7)->setUrl('http://url.tld')->setTitle('title'),
292 // Make sure that PluginManager hook is triggered
293 $this->container
->pluginManager
294 ->expects(static::at(0))
295 ->method('executeHooks')
296 ->willReturnCallback(function (string $hook, array $data, array $param): array {
301 $result = $this->controller
->index($request, $response);
303 static::assertSame(200, $result->getStatusCode());
304 static::assertSame('daily', (string) $result->getBody());
305 static::assertCount(7, $assignedVariables['linksToDisplay']);
307 $columnIds = function (array $column): array {
308 return array_map(function (array $item): int {
return $item
['id']; }, $column);
311 static::assertSame([1, 4, 6], $columnIds($assignedVariables['cols'][0]));
312 static::assertSame([2], $columnIds($assignedVariables['cols'][1]));
313 static::assertSame([3, 5, 7], $columnIds($assignedVariables['cols'][2]));
317 * Daily page - no bookmark
319 public function testValidControllerInvokeNoBookmark(): void
321 $this->createValidContainerMockSet();
323 $request = $this->createMock(Request
::class);
324 $response = new Response();
326 // Save RainTPL assigned variables
327 $assignedVariables = [];
328 $this->assignTemplateVars($assignedVariables);
330 // Links dataset: 2 links with thumbnails
331 $this->container
->bookmarkService
332 ->expects(static::once())
334 ->willReturnCallback(function (): array {
338 $this->container
->bookmarkService
339 ->expects(static::once())
340 ->method('filterDay')
341 ->willReturnCallback(function (): array {
346 // Make sure that PluginManager hook is triggered
347 $this->container
->pluginManager
348 ->expects(static::at(0))
349 ->method('executeHooks')
350 ->willReturnCallback(function (string $hook, array $data, array $param): array {
355 $result = $this->controller
->index($request, $response);
357 static::assertSame(200, $result->getStatusCode());
358 static::assertSame('daily', (string) $result->getBody());
359 static::assertCount(0, $assignedVariables['linksToDisplay']);
360 static::assertSame('Today', $assignedVariables['dayDesc']);
363 protected function createValidContainerMockSet(): void
365 $loginManager = $this->createMock(LoginManager
::class);
366 $this->container
->loginManager
= $loginManager;
369 $conf = $this->createMock(ConfigManager
::class);
370 $this->container
->conf
= $conf;
371 $this->container
->conf
->method('get')->willReturnCallback(function (string $parameter, $default) {
376 $pageBuilder = $this->createMock(PageBuilder
::class);
379 ->willReturnCallback(function (string $template): string {
383 $this->container
->pageBuilder
= $pageBuilder;
386 $pluginManager = $this->createMock(PluginManager
::class);
387 $this->container
->pluginManager
= $pluginManager;
390 $bookmarkService = $this->createMock(BookmarkServiceInterface
::class);
391 $this->container
->bookmarkService
= $bookmarkService;
394 $formatterFactory = $this->createMock(FormatterFactory
::class);
396 ->method('getFormatter')
397 ->willReturnCallback(function (): BookmarkFormatter
{
398 return new BookmarkRawFormatter($this->container
->conf
, true);
401 $this->container
->formatterFactory
= $formatterFactory;
404 protected function assignTemplateVars(array &$variables): void
406 $this->container
->pageBuilder
407 ->expects(static::atLeastOnce())
409 ->willReturnCallback(function ($key, $value) use (&$variables) {
410 $variables[$key] = $value;
417 protected static function generateContent(int $length): string
419 // bin2hex(random_bytes) generates string twice as long as given parameter
420 $length = (int) ceil($length / 2);
421 return bin2hex(random_bytes($length));