diff options
author | ArthurHoaro <arthur@hoa.ro> | 2020-06-13 19:40:32 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2020-07-23 21:19:21 +0200 |
commit | 7b8a6f2858248601d43c1b8247deb91b74392d2e (patch) | |
tree | d11d87fbacbb454727b5c5e9357f14f76faf5bec | |
parent | 1ab675445e52000d8b667c898aae041357304a33 (diff) | |
download | Shaarli-7b8a6f2858248601d43c1b8247deb91b74392d2e.tar.gz Shaarli-7b8a6f2858248601d43c1b8247deb91b74392d2e.tar.zst Shaarli-7b8a6f2858248601d43c1b8247deb91b74392d2e.zip |
Process change visibility action through Slim controller
-rw-r--r-- | application/front/controller/admin/ManageShaareController.php | 70 | ||||
-rw-r--r-- | assets/default/js/base.js | 2 | ||||
-rw-r--r-- | index.php | 51 | ||||
-rw-r--r-- | tests/front/controller/admin/ManageShaareControllerTest/ChangeVisibilityBookmarkTest.php | 418 |
4 files changed, 492 insertions, 49 deletions
diff --git a/application/front/controller/admin/ManageShaareController.php b/application/front/controller/admin/ManageShaareController.php index 620bbc40..ff330a99 100644 --- a/application/front/controller/admin/ManageShaareController.php +++ b/application/front/controller/admin/ManageShaareController.php | |||
@@ -174,7 +174,7 @@ class ManageShaareController extends ShaarliAdminController | |||
174 | } | 174 | } |
175 | 175 | ||
176 | /** | 176 | /** |
177 | * GET /admin/shaare/delete | 177 | * GET /admin/shaare/delete - Delete one or multiple bookmarks (depending on `id` query parameter). |
178 | */ | 178 | */ |
179 | public function deleteBookmark(Request $request, Response $response): Response | 179 | public function deleteBookmark(Request $request, Response $response): Response |
180 | { | 180 | { |
@@ -229,6 +229,74 @@ class ManageShaareController extends ShaarliAdminController | |||
229 | } | 229 | } |
230 | 230 | ||
231 | /** | 231 | /** |
232 | * GET /admin/shaare/visibility | ||
233 | * | ||
234 | * Change visibility (public/private) of one or multiple bookmarks (depending on `id` query parameter). | ||
235 | */ | ||
236 | public function changeVisibility(Request $request, Response $response): Response | ||
237 | { | ||
238 | $this->checkToken($request); | ||
239 | |||
240 | $ids = trim(escape($request->getParam('id') ?? '')); | ||
241 | if (empty($ids) || strpos($ids, ' ') !== false) { | ||
242 | // multiple, space-separated ids provided | ||
243 | $ids = array_values(array_filter(preg_split('/\s+/', $ids), 'ctype_digit')); | ||
244 | } else { | ||
245 | // only a single id provided | ||
246 | $ids = [$ids]; | ||
247 | } | ||
248 | |||
249 | // assert at least one id is given | ||
250 | if (0 === count($ids)) { | ||
251 | $this->saveErrorMessage(t('Invalid bookmark ID provided.')); | ||
252 | |||
253 | return $this->redirectFromReferer($request, $response, [], ['change_visibility']); | ||
254 | } | ||
255 | |||
256 | // assert that the visibility is valid | ||
257 | $visibility = $request->getParam('newVisibility'); | ||
258 | if (null === $visibility || false === in_array($visibility, ['public', 'private'], true)) { | ||
259 | $this->saveErrorMessage(t('Invalid visibility provided.')); | ||
260 | |||
261 | return $this->redirectFromReferer($request, $response, [], ['change_visibility']); | ||
262 | } else { | ||
263 | $isPrivate = $visibility === 'private'; | ||
264 | } | ||
265 | |||
266 | $formatter = $this->container->formatterFactory->getFormatter('raw'); | ||
267 | $count = 0; | ||
268 | |||
269 | foreach ($ids as $id) { | ||
270 | try { | ||
271 | $bookmark = $this->container->bookmarkService->get((int) $id); | ||
272 | } catch (BookmarkNotFoundException $e) { | ||
273 | $this->saveErrorMessage(sprintf( | ||
274 | t('Bookmark with identifier %s could not be found.'), | ||
275 | $id | ||
276 | )); | ||
277 | |||
278 | continue; | ||
279 | } | ||
280 | |||
281 | $bookmark->setPrivate($isPrivate); | ||
282 | |||
283 | // To preserve backward compatibility with 3rd parties, plugins still use arrays | ||
284 | $data = $formatter->format($bookmark); | ||
285 | $this->container->pluginManager->executeHooks('save_link', $data); | ||
286 | $bookmark->fromArray($data); | ||
287 | |||
288 | $this->container->bookmarkService->set($bookmark, false); | ||
289 | ++$count; | ||
290 | } | ||
291 | |||
292 | if ($count > 0) { | ||
293 | $this->container->bookmarkService->save(); | ||
294 | } | ||
295 | |||
296 | return $this->redirectFromReferer($request, $response, ['/visibility'], ['change_visibility']); | ||
297 | } | ||
298 | |||
299 | /** | ||
232 | * Helper function used to display the shaare form whether it's a new or existing bookmark. | 300 | * Helper function used to display the shaare form whether it's a new or existing bookmark. |
233 | * | 301 | * |
234 | * @param array $link data used in template, either from parameters or from the data store | 302 | * @param array $link data used in template, either from parameters or from the data store |
diff --git a/assets/default/js/base.js b/assets/default/js/base.js index 9f67d980..af3d650c 100644 --- a/assets/default/js/base.js +++ b/assets/default/js/base.js | |||
@@ -486,7 +486,7 @@ function init(description) { | |||
486 | 486 | ||
487 | const ids = links.map(item => item.id); | 487 | const ids = links.map(item => item.id); |
488 | window.location = | 488 | window.location = |
489 | `${basePath}/?change_visibility&token=${token.value}&newVisibility=${visibility}&ids=${ids.join('+')}`; | 489 | `${basePath}/admin/shaare/visibility?token=${token.value}&newVisibility=${visibility}&id=${ids.join('+')}`; |
490 | }); | 490 | }); |
491 | }); | 491 | }); |
492 | } | 492 | } |
@@ -499,6 +499,8 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM | |||
499 | 499 | ||
500 | // -------- All other functions are reserved for the registered user: | 500 | // -------- All other functions are reserved for the registered user: |
501 | 501 | ||
502 | // TODO: Remove legacy admin route redirections. We'll only keep public URL. | ||
503 | |||
502 | // -------- Display the Tools menu if requested (import/export/bookmarklet...) | 504 | // -------- Display the Tools menu if requested (import/export/bookmarklet...) |
503 | if ($targetPage == Router::$PAGE_TOOLS) { | 505 | if ($targetPage == Router::$PAGE_TOOLS) { |
504 | header('Location: ./admin/tools'); | 506 | header('Location: ./admin/tools'); |
@@ -547,53 +549,7 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM | |||
547 | 549 | ||
548 | // -------- User clicked either "Set public" or "Set private" bulk operation | 550 | // -------- User clicked either "Set public" or "Set private" bulk operation |
549 | if ($targetPage == Router::$PAGE_CHANGE_VISIBILITY) { | 551 | if ($targetPage == Router::$PAGE_CHANGE_VISIBILITY) { |
550 | if (! $sessionManager->checkToken($_GET['token'])) { | 552 | header('Location: ./admin/shaare/visibility?id=' . $_GET['token']); |
551 | die(t('Wrong token.')); | ||
552 | } | ||
553 | |||
554 | $ids = trim($_GET['ids']); | ||
555 | if (strpos($ids, ' ') !== false) { | ||
556 | // multiple, space-separated ids provided | ||
557 | $ids = array_values(array_filter(preg_split('/\s+/', escape($ids)))); | ||
558 | } else { | ||
559 | // only a single id provided | ||
560 | $ids = [$ids]; | ||
561 | } | ||
562 | |||
563 | // assert at least one id is given | ||
564 | if (!count($ids)) { | ||
565 | die('no id provided'); | ||
566 | } | ||
567 | // assert that the visibility is valid | ||
568 | if (!isset($_GET['newVisibility']) || !in_array($_GET['newVisibility'], ['public', 'private'])) { | ||
569 | die('invalid visibility'); | ||
570 | } else { | ||
571 | $private = $_GET['newVisibility'] === 'private'; | ||
572 | } | ||
573 | $factory = new FormatterFactory($conf, $loginManager->isLoggedIn()); | ||
574 | $formatter = $factory->getFormatter('raw'); | ||
575 | foreach ($ids as $id) { | ||
576 | $id = (int) escape($id); | ||
577 | $bookmark = $bookmarkService->get($id); | ||
578 | $bookmark->setPrivate($private); | ||
579 | |||
580 | // To preserve backward compatibility with 3rd parties, plugins still use arrays | ||
581 | $data = $formatter->format($bookmark); | ||
582 | $pluginManager->executeHooks('save_link', $data); | ||
583 | $bookmark->fromArray($data); | ||
584 | |||
585 | $bookmarkService->set($bookmark); | ||
586 | } | ||
587 | $bookmarkService->save(); | ||
588 | |||
589 | $location = '?'; | ||
590 | if (isset($_SERVER['HTTP_REFERER'])) { | ||
591 | $location = generateLocation( | ||
592 | $_SERVER['HTTP_REFERER'], | ||
593 | $_SERVER['HTTP_HOST'] | ||
594 | ); | ||
595 | } | ||
596 | header('Location: ' . $location); // After deleting the link, redirect to appropriate location | ||
597 | exit; | 553 | exit; |
598 | } | 554 | } |
599 | 555 | ||
@@ -1164,6 +1120,7 @@ $app->group('', function () { | |||
1164 | $this->get('/admin/shaare/{id:[0-9]+}', '\Shaarli\Front\Controller\Admin\ManageShaareController:displayEditForm'); | 1120 | $this->get('/admin/shaare/{id:[0-9]+}', '\Shaarli\Front\Controller\Admin\ManageShaareController:displayEditForm'); |
1165 | $this->post('/admin/shaare', '\Shaarli\Front\Controller\Admin\ManageShaareController:save'); | 1121 | $this->post('/admin/shaare', '\Shaarli\Front\Controller\Admin\ManageShaareController:save'); |
1166 | $this->get('/admin/shaare/delete', '\Shaarli\Front\Controller\Admin\ManageShaareController:deleteBookmark'); | 1122 | $this->get('/admin/shaare/delete', '\Shaarli\Front\Controller\Admin\ManageShaareController:deleteBookmark'); |
1123 | $this->get('/admin/shaare/visibility', '\Shaarli\Front\Controller\Admin\ManageShaareController:changeVisibility'); | ||
1167 | 1124 | ||
1168 | $this->get('/links-per-page', '\Shaarli\Front\Controller\Admin\SessionFilterController:linksPerPage'); | 1125 | $this->get('/links-per-page', '\Shaarli\Front\Controller\Admin\SessionFilterController:linksPerPage'); |
1169 | $this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility'); | 1126 | $this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility'); |
diff --git a/tests/front/controller/admin/ManageShaareControllerTest/ChangeVisibilityBookmarkTest.php b/tests/front/controller/admin/ManageShaareControllerTest/ChangeVisibilityBookmarkTest.php new file mode 100644 index 00000000..5a615791 --- /dev/null +++ b/tests/front/controller/admin/ManageShaareControllerTest/ChangeVisibilityBookmarkTest.php | |||
@@ -0,0 +1,418 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Front\Controller\Admin\ManageShaareControllerTest; | ||
6 | |||
7 | use PHPUnit\Framework\TestCase; | ||
8 | use Shaarli\Bookmark\Bookmark; | ||
9 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; | ||
10 | use Shaarli\Formatter\BookmarkFormatter; | ||
11 | use Shaarli\Formatter\BookmarkRawFormatter; | ||
12 | use Shaarli\Formatter\FormatterFactory; | ||
13 | use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper; | ||
14 | use Shaarli\Front\Controller\Admin\ManageShaareController; | ||
15 | use Shaarli\Http\HttpAccess; | ||
16 | use Shaarli\Security\SessionManager; | ||
17 | use Slim\Http\Request; | ||
18 | use Slim\Http\Response; | ||
19 | |||
20 | class ChangeVisibilityBookmarkTest extends TestCase | ||
21 | { | ||
22 | use FrontAdminControllerMockHelper; | ||
23 | |||
24 | /** @var ManageShaareController */ | ||
25 | protected $controller; | ||
26 | |||
27 | public function setUp(): void | ||
28 | { | ||
29 | $this->createContainer(); | ||
30 | |||
31 | $this->container->httpAccess = $this->createMock(HttpAccess::class); | ||
32 | $this->controller = new ManageShaareController($this->container); | ||
33 | } | ||
34 | |||
35 | /** | ||
36 | * Change bookmark visibility - Set private - Single public bookmark with valid parameters | ||
37 | */ | ||
38 | public function testSetSingleBookmarkPrivate(): void | ||
39 | { | ||
40 | $parameters = ['id' => '123', 'newVisibility' => 'private']; | ||
41 | |||
42 | $request = $this->createMock(Request::class); | ||
43 | $request | ||
44 | ->method('getParam') | ||
45 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
46 | return $parameters[$key] ?? null; | ||
47 | }) | ||
48 | ; | ||
49 | $response = new Response(); | ||
50 | |||
51 | $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(false); | ||
52 | |||
53 | static::assertFalse($bookmark->isPrivate()); | ||
54 | |||
55 | $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); | ||
56 | $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, false); | ||
57 | $this->container->bookmarkService->expects(static::once())->method('save'); | ||
58 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
59 | $this->container->formatterFactory | ||
60 | ->expects(static::once()) | ||
61 | ->method('getFormatter') | ||
62 | ->with('raw') | ||
63 | ->willReturnCallback(function () use ($bookmark): BookmarkFormatter { | ||
64 | return new BookmarkRawFormatter($this->container->conf, true); | ||
65 | }) | ||
66 | ; | ||
67 | |||
68 | // Make sure that PluginManager hook is triggered | ||
69 | $this->container->pluginManager | ||
70 | ->expects(static::once()) | ||
71 | ->method('executeHooks') | ||
72 | ->with('save_link') | ||
73 | ; | ||
74 | |||
75 | $result = $this->controller->changeVisibility($request, $response); | ||
76 | |||
77 | static::assertTrue($bookmark->isPrivate()); | ||
78 | |||
79 | static::assertSame(302, $result->getStatusCode()); | ||
80 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * Change bookmark visibility - Set public - Single private bookmark with valid parameters | ||
85 | */ | ||
86 | public function testSetSingleBookmarkPublic(): void | ||
87 | { | ||
88 | $parameters = ['id' => '123', 'newVisibility' => 'public']; | ||
89 | |||
90 | $request = $this->createMock(Request::class); | ||
91 | $request | ||
92 | ->method('getParam') | ||
93 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
94 | return $parameters[$key] ?? null; | ||
95 | }) | ||
96 | ; | ||
97 | $response = new Response(); | ||
98 | |||
99 | $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(true); | ||
100 | |||
101 | static::assertTrue($bookmark->isPrivate()); | ||
102 | |||
103 | $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); | ||
104 | $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, false); | ||
105 | $this->container->bookmarkService->expects(static::once())->method('save'); | ||
106 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
107 | $this->container->formatterFactory | ||
108 | ->expects(static::once()) | ||
109 | ->method('getFormatter') | ||
110 | ->with('raw') | ||
111 | ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) | ||
112 | ; | ||
113 | |||
114 | // Make sure that PluginManager hook is triggered | ||
115 | $this->container->pluginManager | ||
116 | ->expects(static::once()) | ||
117 | ->method('executeHooks') | ||
118 | ->with('save_link') | ||
119 | ; | ||
120 | |||
121 | $result = $this->controller->changeVisibility($request, $response); | ||
122 | |||
123 | static::assertFalse($bookmark->isPrivate()); | ||
124 | |||
125 | static::assertSame(302, $result->getStatusCode()); | ||
126 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * Change bookmark visibility - Set private on single already private bookmark | ||
131 | */ | ||
132 | public function testSetSinglePrivateBookmarkPrivate(): void | ||
133 | { | ||
134 | $parameters = ['id' => '123', 'newVisibility' => 'private']; | ||
135 | |||
136 | $request = $this->createMock(Request::class); | ||
137 | $request | ||
138 | ->method('getParam') | ||
139 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
140 | return $parameters[$key] ?? null; | ||
141 | }) | ||
142 | ; | ||
143 | $response = new Response(); | ||
144 | |||
145 | $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(true); | ||
146 | |||
147 | static::assertTrue($bookmark->isPrivate()); | ||
148 | |||
149 | $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); | ||
150 | $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, false); | ||
151 | $this->container->bookmarkService->expects(static::once())->method('save'); | ||
152 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
153 | $this->container->formatterFactory | ||
154 | ->expects(static::once()) | ||
155 | ->method('getFormatter') | ||
156 | ->with('raw') | ||
157 | ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) | ||
158 | ; | ||
159 | |||
160 | // Make sure that PluginManager hook is triggered | ||
161 | $this->container->pluginManager | ||
162 | ->expects(static::once()) | ||
163 | ->method('executeHooks') | ||
164 | ->with('save_link') | ||
165 | ; | ||
166 | |||
167 | $result = $this->controller->changeVisibility($request, $response); | ||
168 | |||
169 | static::assertTrue($bookmark->isPrivate()); | ||
170 | |||
171 | static::assertSame(302, $result->getStatusCode()); | ||
172 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * Change bookmark visibility - Set multiple bookmarks private | ||
177 | */ | ||
178 | public function testSetMultipleBookmarksPrivate(): void | ||
179 | { | ||
180 | $parameters = ['id' => '123 456 789', 'newVisibility' => 'private']; | ||
181 | |||
182 | $request = $this->createMock(Request::class); | ||
183 | $request | ||
184 | ->method('getParam') | ||
185 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
186 | return $parameters[$key] ?? null; | ||
187 | }) | ||
188 | ; | ||
189 | $response = new Response(); | ||
190 | |||
191 | $bookmarks = [ | ||
192 | (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(false), | ||
193 | (new Bookmark())->setId(456)->setUrl('http://domain.tld')->setTitle('Title 456')->setPrivate(true), | ||
194 | (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789')->setPrivate(false), | ||
195 | ]; | ||
196 | |||
197 | $this->container->bookmarkService | ||
198 | ->expects(static::exactly(3)) | ||
199 | ->method('get') | ||
200 | ->withConsecutive([123], [456], [789]) | ||
201 | ->willReturnOnConsecutiveCalls(...$bookmarks) | ||
202 | ; | ||
203 | $this->container->bookmarkService | ||
204 | ->expects(static::exactly(3)) | ||
205 | ->method('set') | ||
206 | ->withConsecutive(...array_map(function (Bookmark $bookmark): array { | ||
207 | return [$bookmark, false]; | ||
208 | }, $bookmarks)) | ||
209 | ; | ||
210 | $this->container->bookmarkService->expects(static::once())->method('save'); | ||
211 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
212 | $this->container->formatterFactory | ||
213 | ->expects(static::once()) | ||
214 | ->method('getFormatter') | ||
215 | ->with('raw') | ||
216 | ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) | ||
217 | ; | ||
218 | |||
219 | // Make sure that PluginManager hook is triggered | ||
220 | $this->container->pluginManager | ||
221 | ->expects(static::exactly(3)) | ||
222 | ->method('executeHooks') | ||
223 | ->with('save_link') | ||
224 | ; | ||
225 | |||
226 | $result = $this->controller->changeVisibility($request, $response); | ||
227 | |||
228 | static::assertTrue($bookmarks[0]->isPrivate()); | ||
229 | static::assertTrue($bookmarks[1]->isPrivate()); | ||
230 | static::assertTrue($bookmarks[2]->isPrivate()); | ||
231 | |||
232 | static::assertSame(302, $result->getStatusCode()); | ||
233 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
234 | } | ||
235 | |||
236 | /** | ||
237 | * Change bookmark visibility - Single bookmark not found. | ||
238 | */ | ||
239 | public function testChangeVisibilitySingleBookmarkNotFound(): void | ||
240 | { | ||
241 | $parameters = ['id' => '123', 'newVisibility' => 'private']; | ||
242 | |||
243 | $request = $this->createMock(Request::class); | ||
244 | $request | ||
245 | ->method('getParam') | ||
246 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
247 | return $parameters[$key] ?? null; | ||
248 | }) | ||
249 | ; | ||
250 | $response = new Response(); | ||
251 | |||
252 | $this->container->bookmarkService | ||
253 | ->expects(static::once()) | ||
254 | ->method('get') | ||
255 | ->willThrowException(new BookmarkNotFoundException()) | ||
256 | ; | ||
257 | $this->container->bookmarkService->expects(static::never())->method('set'); | ||
258 | $this->container->bookmarkService->expects(static::never())->method('save'); | ||
259 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
260 | $this->container->formatterFactory | ||
261 | ->expects(static::once()) | ||
262 | ->method('getFormatter') | ||
263 | ->with('raw') | ||
264 | ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) | ||
265 | ; | ||
266 | |||
267 | // Make sure that PluginManager hook is not triggered | ||
268 | $this->container->pluginManager | ||
269 | ->expects(static::never()) | ||
270 | ->method('executeHooks') | ||
271 | ->with('save_link') | ||
272 | ; | ||
273 | |||
274 | $result = $this->controller->changeVisibility($request, $response); | ||
275 | |||
276 | static::assertSame(302, $result->getStatusCode()); | ||
277 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * Change bookmark visibility - Multiple bookmarks with one not found. | ||
282 | */ | ||
283 | public function testChangeVisibilityMultipleBookmarksOneNotFound(): void | ||
284 | { | ||
285 | $parameters = ['id' => '123 456 789', 'newVisibility' => 'public']; | ||
286 | |||
287 | $request = $this->createMock(Request::class); | ||
288 | $request | ||
289 | ->method('getParam') | ||
290 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
291 | return $parameters[$key] ?? null; | ||
292 | }) | ||
293 | ; | ||
294 | $response = new Response(); | ||
295 | |||
296 | $bookmarks = [ | ||
297 | (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(true), | ||
298 | (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789')->setPrivate(false), | ||
299 | ]; | ||
300 | |||
301 | $this->container->bookmarkService | ||
302 | ->expects(static::exactly(3)) | ||
303 | ->method('get') | ||
304 | ->withConsecutive([123], [456], [789]) | ||
305 | ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark { | ||
306 | if ($id === 123) { | ||
307 | return $bookmarks[0]; | ||
308 | } | ||
309 | if ($id === 789) { | ||
310 | return $bookmarks[1]; | ||
311 | } | ||
312 | throw new BookmarkNotFoundException(); | ||
313 | }) | ||
314 | ; | ||
315 | $this->container->bookmarkService | ||
316 | ->expects(static::exactly(2)) | ||
317 | ->method('set') | ||
318 | ->withConsecutive(...array_map(function (Bookmark $bookmark): array { | ||
319 | return [$bookmark, false]; | ||
320 | }, $bookmarks)) | ||
321 | ; | ||
322 | $this->container->bookmarkService->expects(static::once())->method('save'); | ||
323 | |||
324 | // Make sure that PluginManager hook is not triggered | ||
325 | $this->container->pluginManager | ||
326 | ->expects(static::exactly(2)) | ||
327 | ->method('executeHooks') | ||
328 | ->with('save_link') | ||
329 | ; | ||
330 | |||
331 | $this->container->sessionManager | ||
332 | ->expects(static::once()) | ||
333 | ->method('setSessionParameter') | ||
334 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 456 could not be found.']) | ||
335 | ; | ||
336 | |||
337 | $result = $this->controller->changeVisibility($request, $response); | ||
338 | |||
339 | static::assertSame(302, $result->getStatusCode()); | ||
340 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * Change bookmark visibility - Invalid ID | ||
345 | */ | ||
346 | public function testChangeVisibilityInvalidId(): void | ||
347 | { | ||
348 | $parameters = ['id' => 'nope not an ID', 'newVisibility' => 'private']; | ||
349 | |||
350 | $request = $this->createMock(Request::class); | ||
351 | $request | ||
352 | ->method('getParam') | ||
353 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
354 | return $parameters[$key] ?? null; | ||
355 | }) | ||
356 | ; | ||
357 | $response = new Response(); | ||
358 | |||
359 | $this->container->sessionManager | ||
360 | ->expects(static::once()) | ||
361 | ->method('setSessionParameter') | ||
362 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) | ||
363 | ; | ||
364 | |||
365 | $result = $this->controller->changeVisibility($request, $response); | ||
366 | |||
367 | static::assertSame(302, $result->getStatusCode()); | ||
368 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * Change bookmark visibility - Empty ID | ||
373 | */ | ||
374 | public function testChangeVisibilityEmptyId(): void | ||
375 | { | ||
376 | $request = $this->createMock(Request::class); | ||
377 | $response = new Response(); | ||
378 | |||
379 | $this->container->sessionManager | ||
380 | ->expects(static::once()) | ||
381 | ->method('setSessionParameter') | ||
382 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) | ||
383 | ; | ||
384 | |||
385 | $result = $this->controller->changeVisibility($request, $response); | ||
386 | |||
387 | static::assertSame(302, $result->getStatusCode()); | ||
388 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * Change bookmark visibility - with invalid visibility | ||
393 | */ | ||
394 | public function testChangeVisibilityWithInvalidVisibility(): void | ||
395 | { | ||
396 | $parameters = ['id' => '123', 'newVisibility' => 'invalid']; | ||
397 | |||
398 | $request = $this->createMock(Request::class); | ||
399 | $request | ||
400 | ->method('getParam') | ||
401 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
402 | return $parameters[$key] ?? null; | ||
403 | }) | ||
404 | ; | ||
405 | $response = new Response(); | ||
406 | |||
407 | $this->container->sessionManager | ||
408 | ->expects(static::once()) | ||
409 | ->method('setSessionParameter') | ||
410 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid visibility provided.']) | ||
411 | ; | ||
412 | |||
413 | $result = $this->controller->changeVisibility($request, $response); | ||
414 | |||
415 | static::assertSame(302, $result->getStatusCode()); | ||
416 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
417 | } | ||
418 | } | ||