"source": {
"type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git",
- "reference": "ec1a75b10126327b351fdea7c2b9bfb94e2f6f35"
+ "reference": "5a342e2dc0408d026b97ee3176b5b406e54e3766"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/ec1a75b10126327b351fdea7c2b9bfb94e2f6f35",
- "reference": "ec1a75b10126327b351fdea7c2b9bfb94e2f6f35",
+ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/5a342e2dc0408d026b97ee3176b5b406e54e3766",
+ "reference": "5a342e2dc0408d026b97ee3176b5b406e54e3766",
"shasum": ""
},
"conflict": {
"titon/framework": ">=0,<9.9.99",
"truckersmp/phpwhois": "<=4.3.1",
"twig/twig": "<1.38|>=2,<2.7",
- "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.30|>=9,<9.5.12|>=10,<10.2.1",
- "typo3/cms-core": ">=8,<8.7.30|>=9,<9.5.12|>=10,<10.2.1",
+ "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.30|>=9,<9.5.17|>=10,<10.4.2",
+ "typo3/cms-core": ">=8,<8.7.30|>=9,<9.5.17|>=10,<10.4.2",
"typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.10|>=3.1,<3.1.7|>=3.2,<3.2.7|>=3.3,<3.3.5",
"typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4",
"typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1",
}
],
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
- "time": "2020-05-09T00:00:21+00:00"
+ "time": "2020-05-12T11:18:47+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.16.0",
+ "version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "1aab00e39cebaef4d8652497f46c15c1b7e45294"
+ "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1aab00e39cebaef4d8652497f46c15c1b7e45294",
- "reference": "1aab00e39cebaef4d8652497f46c15c1b7e45294",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
+ "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
"shasum": ""
},
"require": {
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.16-dev"
+ "dev-master": "1.17-dev"
}
},
"autoload": {
"polyfill",
"portable"
],
- "time": "2020-05-08T16:50:20+00:00"
+ "time": "2020-05-12T16:14:59+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.16.0",
+ "version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "a54881ec0ab3b2005c406aed0023c062879031e7"
+ "reference": "fa79b11539418b02fc5e1897267673ba2c19419c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a54881ec0ab3b2005c406aed0023c062879031e7",
- "reference": "a54881ec0ab3b2005c406aed0023c062879031e7",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c",
+ "reference": "fa79b11539418b02fc5e1897267673ba2c19419c",
"shasum": ""
},
"require": {
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.16-dev"
+ "dev-master": "1.17-dev"
}
},
"autoload": {
"portable",
"shim"
],
- "time": "2020-05-08T16:50:20+00:00"
+ "time": "2020-05-12T16:47:27+00:00"
},
{
"name": "symfony/polyfill-php73",
- "version": "v1.16.0",
+ "version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
- "reference": "7e95fe59d12169fcf4041487e4bf34fca37ee0ed"
+ "reference": "a760d8964ff79ab9bf057613a5808284ec852ccc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/7e95fe59d12169fcf4041487e4bf34fca37ee0ed",
- "reference": "7e95fe59d12169fcf4041487e4bf34fca37ee0ed",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a760d8964ff79ab9bf057613a5808284ec852ccc",
+ "reference": "a760d8964ff79ab9bf057613a5808284ec852ccc",
"shasum": ""
},
"require": {
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.16-dev"
+ "dev-master": "1.17-dev"
}
},
"autoload": {
"portable",
"shim"
],
- "time": "2020-05-02T14:56:09+00:00"
+ "time": "2020-05-12T16:47:27+00:00"
},
{
"name": "symfony/service-contracts",
--- /dev/null
+<?php
+
+declare(strict_types=1);
+
+namespace Shaarli\Front\Controller;
+
+use PHPUnit\Framework\TestCase;
+use Shaarli\Bookmark\BookmarkFilter;
+use Shaarli\Bookmark\BookmarkServiceInterface;
+use Shaarli\Config\ConfigManager;
+use Shaarli\Container\ShaarliContainer;
+use Shaarli\Plugin\PluginManager;
+use Shaarli\Render\PageBuilder;
+use Shaarli\Security\LoginManager;
+use Shaarli\Security\SessionManager;
+use Slim\Http\Request;
+use Slim\Http\Response;
+
+class TagCloudControllerTest extends TestCase
+{
+ /** @var ShaarliContainer */
+ protected $container;
+
+ /** @var TagCloudController */
+ protected $controller;
+
+ public function setUp(): void
+ {
+ $this->container = $this->createMock(ShaarliContainer::class);
+ $this->controller = new TagCloudController($this->container);
+ }
+
+ public function testValidCloudControllerInvokeDefault(): void
+ {
+ $this->createValidContainerMockSet();
+
+ $allTags = [
+ 'ghi' => 1,
+ 'abc' => 3,
+ 'def' => 12,
+ ];
+ $expectedOrder = ['abc', 'def', 'ghi'];
+
+ $request = $this->createMock(Request::class);
+ $request->expects(static::once())->method('getQueryParam')->with('searchtags')->willReturn(null);
+ $response = new Response();
+
+ // Save RainTPL assigned variables
+ $assignedVariables = [];
+ $this->assignTemplateVars($assignedVariables);
+
+ $this->container->bookmarkService
+ ->expects(static::once())
+ ->method('bookmarksCountPerTag')
+ ->with([], null)
+ ->willReturnCallback(function () use ($allTags): array {
+ return $allTags;
+ })
+ ;
+
+ // Make sure that PluginManager hook is triggered
+ $this->container->pluginManager
+ ->expects(static::at(0))
+ ->method('executeHooks')
+ ->willReturnCallback(function (string $hook, array $data, array $param): array {
+ static::assertSame('render_tagcloud', $hook);
+ static::assertSame('', $data['search_tags']);
+ static::assertCount(3, $data['tags']);
+
+ static::assertArrayHasKey('loggedin', $param);
+
+ return $data;
+ })
+ ;
+
+ $result = $this->controller->index($request, $response);
+
+ static::assertSame(200, $result->getStatusCode());
+ static::assertSame('tag.cloud', (string) $result->getBody());
+ static::assertSame('Tag cloud - Shaarli', $assignedVariables['pagetitle']);
+
+ static::assertSame('', $assignedVariables['search_tags']);
+ static::assertCount(3, $assignedVariables['tags']);
+ static::assertSame($expectedOrder, array_keys($assignedVariables['tags']));
+
+ foreach ($allTags as $tag => $count) {
+ static::assertArrayHasKey($tag, $assignedVariables['tags']);
+ static::assertSame($count, $assignedVariables['tags'][$tag]['count']);
+ static::assertGreaterThan(0, $assignedVariables['tags'][$tag]['size']);
+ static::assertLessThan(5, $assignedVariables['tags'][$tag]['size']);
+ }
+ }
+
+ /**
+ * Additional parameters:
+ * - logged in
+ * - visibility private
+ * - search tags: `ghi` and `def` (note that filtered tags are not displayed anymore)
+ */
+ public function testValidCloudControllerInvokeWithParameters(): void
+ {
+ $this->createValidContainerMockSet();
+
+ $allTags = [
+ 'ghi' => 1,
+ 'abc' => 3,
+ 'def' => 12,
+ ];
+
+ $request = $this->createMock(Request::class);
+ $request
+ ->expects(static::once())
+ ->method('getQueryParam')
+ ->with('searchtags')
+ ->willReturn('ghi def')
+ ;
+ $response = new Response();
+
+ // Save RainTPL assigned variables
+ $assignedVariables = [];
+ $this->assignTemplateVars($assignedVariables);
+
+ $this->container->loginManager->method('isLoggedin')->willReturn(true);
+ $this->container->sessionManager->expects(static::once())->method('getSessionParameter')->willReturn('private');
+
+ $this->container->bookmarkService
+ ->expects(static::once())
+ ->method('bookmarksCountPerTag')
+ ->with(['ghi', 'def'], BookmarkFilter::$PRIVATE)
+ ->willReturnCallback(function () use ($allTags): array {
+ return $allTags;
+ })
+ ;
+
+ // Make sure that PluginManager hook is triggered
+ $this->container->pluginManager
+ ->expects(static::at(0))
+ ->method('executeHooks')
+ ->willReturnCallback(function (string $hook, array $data, array $param): array {
+ static::assertSame('render_tagcloud', $hook);
+ static::assertSame('ghi def', $data['search_tags']);
+ static::assertCount(1, $data['tags']);
+
+ static::assertArrayHasKey('loggedin', $param);
+
+ return $data;
+ })
+ ;
+
+ $result = $this->controller->index($request, $response);
+
+ static::assertSame(200, $result->getStatusCode());
+ static::assertSame('tag.cloud', (string) $result->getBody());
+ static::assertSame('ghi def - Tag cloud - Shaarli', $assignedVariables['pagetitle']);
+
+ static::assertSame('ghi def', $assignedVariables['search_tags']);
+ static::assertCount(1, $assignedVariables['tags']);
+
+ static::assertArrayHasKey('abc', $assignedVariables['tags']);
+ static::assertSame(3, $assignedVariables['tags']['abc']['count']);
+ static::assertGreaterThan(0, $assignedVariables['tags']['abc']['size']);
+ static::assertLessThan(5, $assignedVariables['tags']['abc']['size']);
+ }
+
+ public function testEmptyCloud(): void
+ {
+ $this->createValidContainerMockSet();
+
+ $request = $this->createMock(Request::class);
+ $request->expects(static::once())->method('getQueryParam')->with('searchtags')->willReturn(null);
+ $response = new Response();
+
+ // Save RainTPL assigned variables
+ $assignedVariables = [];
+ $this->assignTemplateVars($assignedVariables);
+
+ $this->container->bookmarkService
+ ->expects(static::once())
+ ->method('bookmarksCountPerTag')
+ ->with([], null)
+ ->willReturnCallback(function (array $parameters, ?string $visibility): array {
+ return [];
+ })
+ ;
+
+ // Make sure that PluginManager hook is triggered
+ $this->container->pluginManager
+ ->expects(static::at(0))
+ ->method('executeHooks')
+ ->willReturnCallback(function (string $hook, array $data, array $param): array {
+ static::assertSame('render_tagcloud', $hook);
+ static::assertSame('', $data['search_tags']);
+ static::assertCount(0, $data['tags']);
+
+ static::assertArrayHasKey('loggedin', $param);
+
+ return $data;
+ })
+ ;
+
+ $result = $this->controller->index($request, $response);
+
+ static::assertSame(200, $result->getStatusCode());
+ static::assertSame('tag.cloud', (string) $result->getBody());
+ static::assertSame('Tag cloud - Shaarli', $assignedVariables['pagetitle']);
+
+ static::assertSame('', $assignedVariables['search_tags']);
+ static::assertCount(0, $assignedVariables['tags']);
+ }
+
+ protected function createValidContainerMockSet(): void
+ {
+ $loginManager = $this->createMock(LoginManager::class);
+ $this->container->loginManager = $loginManager;
+
+ $sessionManager = $this->createMock(SessionManager::class);
+ $this->container->sessionManager = $sessionManager;
+
+ // Config
+ $conf = $this->createMock(ConfigManager::class);
+ $this->container->conf = $conf;
+
+ $this->container->conf->method('get')->willReturnCallback(function (string $parameter, $default) {
+ return $default;
+ });
+
+ // PageBuilder
+ $pageBuilder = $this->createMock(PageBuilder::class);
+ $pageBuilder
+ ->method('render')
+ ->willReturnCallback(function (string $template): string {
+ return $template;
+ })
+ ;
+ $this->container->pageBuilder = $pageBuilder;
+
+ // Plugin Manager
+ $pluginManager = $this->createMock(PluginManager::class);
+ $this->container->pluginManager = $pluginManager;
+
+ // BookmarkService
+ $bookmarkService = $this->createMock(BookmarkServiceInterface::class);
+ $this->container->bookmarkService = $bookmarkService;
+ }
+
+ protected function assignTemplateVars(array &$variables): void
+ {
+ $this->container->pageBuilder
+ ->expects(static::atLeastOnce())
+ ->method('assign')
+ ->willReturnCallback(function ($key, $value) use (&$variables) {
+ $variables[$key] = $value;
+
+ return $this;
+ })
+ ;
+ }
+}