diff options
Diffstat (limited to 'tests/front/controller/admin/ShaareManageControllerTest')
4 files changed, 1086 insertions, 0 deletions
diff --git a/tests/front/controller/admin/ShaareManageControllerTest/ChangeVisibilityBookmarkTest.php b/tests/front/controller/admin/ShaareManageControllerTest/ChangeVisibilityBookmarkTest.php new file mode 100644 index 00000000..28b1c023 --- /dev/null +++ b/tests/front/controller/admin/ShaareManageControllerTest/ChangeVisibilityBookmarkTest.php | |||
@@ -0,0 +1,418 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Front\Controller\Admin\ShaareManageControllerTest; | ||
6 | |||
7 | use Shaarli\Bookmark\Bookmark; | ||
8 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; | ||
9 | use Shaarli\Formatter\BookmarkFormatter; | ||
10 | use Shaarli\Formatter\BookmarkRawFormatter; | ||
11 | use Shaarli\Formatter\FormatterFactory; | ||
12 | use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper; | ||
13 | use Shaarli\Front\Controller\Admin\ShaareManageController; | ||
14 | use Shaarli\Http\HttpAccess; | ||
15 | use Shaarli\Security\SessionManager; | ||
16 | use Shaarli\TestCase; | ||
17 | use Slim\Http\Request; | ||
18 | use Slim\Http\Response; | ||
19 | |||
20 | class ChangeVisibilityBookmarkTest extends TestCase | ||
21 | { | ||
22 | use FrontAdminControllerMockHelper; | ||
23 | |||
24 | /** @var ShaareManageController */ | ||
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 ShaareManageController($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 | } | ||
diff --git a/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php b/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php new file mode 100644 index 00000000..a276d988 --- /dev/null +++ b/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php | |||
@@ -0,0 +1,384 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Front\Controller\Admin\ShaareManageControllerTest; | ||
6 | |||
7 | use Shaarli\Bookmark\Bookmark; | ||
8 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; | ||
9 | use Shaarli\Formatter\BookmarkFormatter; | ||
10 | use Shaarli\Formatter\FormatterFactory; | ||
11 | use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper; | ||
12 | use Shaarli\Front\Controller\Admin\ShaareManageController; | ||
13 | use Shaarli\Http\HttpAccess; | ||
14 | use Shaarli\Security\SessionManager; | ||
15 | use Shaarli\TestCase; | ||
16 | use Slim\Http\Request; | ||
17 | use Slim\Http\Response; | ||
18 | |||
19 | class DeleteBookmarkTest extends TestCase | ||
20 | { | ||
21 | use FrontAdminControllerMockHelper; | ||
22 | |||
23 | /** @var ShaareManageController */ | ||
24 | protected $controller; | ||
25 | |||
26 | public function setUp(): void | ||
27 | { | ||
28 | $this->createContainer(); | ||
29 | |||
30 | $this->container->httpAccess = $this->createMock(HttpAccess::class); | ||
31 | $this->controller = new ShaareManageController($this->container); | ||
32 | } | ||
33 | |||
34 | /** | ||
35 | * Delete bookmark - Single bookmark with valid parameters | ||
36 | */ | ||
37 | public function testDeleteSingleBookmark(): void | ||
38 | { | ||
39 | $parameters = ['id' => '123']; | ||
40 | |||
41 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/shaare/abcdef'; | ||
42 | |||
43 | $request = $this->createMock(Request::class); | ||
44 | $request | ||
45 | ->method('getParam') | ||
46 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
47 | return $parameters[$key] ?? null; | ||
48 | }) | ||
49 | ; | ||
50 | $response = new Response(); | ||
51 | |||
52 | $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'); | ||
53 | |||
54 | $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); | ||
55 | $this->container->bookmarkService->expects(static::once())->method('remove')->with($bookmark, false); | ||
56 | $this->container->bookmarkService->expects(static::once())->method('save'); | ||
57 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
58 | $this->container->formatterFactory | ||
59 | ->expects(static::once()) | ||
60 | ->method('getFormatter') | ||
61 | ->with('raw') | ||
62 | ->willReturnCallback(function () use ($bookmark): BookmarkFormatter { | ||
63 | $formatter = $this->createMock(BookmarkFormatter::class); | ||
64 | $formatter | ||
65 | ->expects(static::once()) | ||
66 | ->method('format') | ||
67 | ->with($bookmark) | ||
68 | ->willReturn(['formatted' => $bookmark]) | ||
69 | ; | ||
70 | |||
71 | return $formatter; | ||
72 | }) | ||
73 | ; | ||
74 | |||
75 | // Make sure that PluginManager hook is triggered | ||
76 | $this->container->pluginManager | ||
77 | ->expects(static::once()) | ||
78 | ->method('executeHooks') | ||
79 | ->with('delete_link', ['formatted' => $bookmark]) | ||
80 | ; | ||
81 | |||
82 | $result = $this->controller->deleteBookmark($request, $response); | ||
83 | |||
84 | static::assertSame(302, $result->getStatusCode()); | ||
85 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * Delete bookmark - Multiple bookmarks with valid parameters | ||
90 | */ | ||
91 | public function testDeleteMultipleBookmarks(): void | ||
92 | { | ||
93 | $parameters = ['id' => '123 456 789']; | ||
94 | |||
95 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/?searchtags=abcdef'; | ||
96 | |||
97 | $request = $this->createMock(Request::class); | ||
98 | $request | ||
99 | ->method('getParam') | ||
100 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
101 | return $parameters[$key] ?? null; | ||
102 | }) | ||
103 | ; | ||
104 | $response = new Response(); | ||
105 | |||
106 | $bookmarks = [ | ||
107 | (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'), | ||
108 | (new Bookmark())->setId(456)->setUrl('http://domain.tld')->setTitle('Title 456'), | ||
109 | (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'), | ||
110 | ]; | ||
111 | |||
112 | $this->container->bookmarkService | ||
113 | ->expects(static::exactly(3)) | ||
114 | ->method('get') | ||
115 | ->withConsecutive([123], [456], [789]) | ||
116 | ->willReturnOnConsecutiveCalls(...$bookmarks) | ||
117 | ; | ||
118 | $this->container->bookmarkService | ||
119 | ->expects(static::exactly(3)) | ||
120 | ->method('remove') | ||
121 | ->withConsecutive(...array_map(function (Bookmark $bookmark): array { | ||
122 | return [$bookmark, false]; | ||
123 | }, $bookmarks)) | ||
124 | ; | ||
125 | $this->container->bookmarkService->expects(static::once())->method('save'); | ||
126 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
127 | $this->container->formatterFactory | ||
128 | ->expects(static::once()) | ||
129 | ->method('getFormatter') | ||
130 | ->with('raw') | ||
131 | ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter { | ||
132 | $formatter = $this->createMock(BookmarkFormatter::class); | ||
133 | |||
134 | $formatter | ||
135 | ->expects(static::exactly(3)) | ||
136 | ->method('format') | ||
137 | ->withConsecutive(...array_map(function (Bookmark $bookmark): array { | ||
138 | return [$bookmark]; | ||
139 | }, $bookmarks)) | ||
140 | ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array { | ||
141 | return ['formatted' => $bookmark]; | ||
142 | }, $bookmarks)) | ||
143 | ; | ||
144 | |||
145 | return $formatter; | ||
146 | }) | ||
147 | ; | ||
148 | |||
149 | // Make sure that PluginManager hook is triggered | ||
150 | $this->container->pluginManager | ||
151 | ->expects(static::exactly(3)) | ||
152 | ->method('executeHooks') | ||
153 | ->with('delete_link') | ||
154 | ; | ||
155 | |||
156 | $result = $this->controller->deleteBookmark($request, $response); | ||
157 | |||
158 | static::assertSame(302, $result->getStatusCode()); | ||
159 | static::assertSame(['/subfolder/?searchtags=abcdef'], $result->getHeader('location')); | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * Delete bookmark - Single bookmark not found in the data store | ||
164 | */ | ||
165 | public function testDeleteSingleBookmarkNotFound(): void | ||
166 | { | ||
167 | $parameters = ['id' => '123']; | ||
168 | |||
169 | $request = $this->createMock(Request::class); | ||
170 | $request | ||
171 | ->method('getParam') | ||
172 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
173 | return $parameters[$key] ?? null; | ||
174 | }) | ||
175 | ; | ||
176 | $response = new Response(); | ||
177 | |||
178 | $this->container->bookmarkService | ||
179 | ->expects(static::once()) | ||
180 | ->method('get') | ||
181 | ->willThrowException(new BookmarkNotFoundException()) | ||
182 | ; | ||
183 | $this->container->bookmarkService->expects(static::never())->method('remove'); | ||
184 | $this->container->bookmarkService->expects(static::never())->method('save'); | ||
185 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
186 | $this->container->formatterFactory | ||
187 | ->expects(static::once()) | ||
188 | ->method('getFormatter') | ||
189 | ->with('raw') | ||
190 | ->willReturnCallback(function (): BookmarkFormatter { | ||
191 | $formatter = $this->createMock(BookmarkFormatter::class); | ||
192 | |||
193 | $formatter->expects(static::never())->method('format'); | ||
194 | |||
195 | return $formatter; | ||
196 | }) | ||
197 | ; | ||
198 | // Make sure that PluginManager hook is not triggered | ||
199 | $this->container->pluginManager | ||
200 | ->expects(static::never()) | ||
201 | ->method('executeHooks') | ||
202 | ->with('delete_link') | ||
203 | ; | ||
204 | |||
205 | $result = $this->controller->deleteBookmark($request, $response); | ||
206 | |||
207 | static::assertSame(302, $result->getStatusCode()); | ||
208 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
209 | } | ||
210 | |||
211 | /** | ||
212 | * Delete bookmark - Multiple bookmarks with one not found in the data store | ||
213 | */ | ||
214 | public function testDeleteMultipleBookmarksOneNotFound(): void | ||
215 | { | ||
216 | $parameters = ['id' => '123 456 789']; | ||
217 | |||
218 | $request = $this->createMock(Request::class); | ||
219 | $request | ||
220 | ->method('getParam') | ||
221 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
222 | return $parameters[$key] ?? null; | ||
223 | }) | ||
224 | ; | ||
225 | $response = new Response(); | ||
226 | |||
227 | $bookmarks = [ | ||
228 | (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'), | ||
229 | (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'), | ||
230 | ]; | ||
231 | |||
232 | $this->container->bookmarkService | ||
233 | ->expects(static::exactly(3)) | ||
234 | ->method('get') | ||
235 | ->withConsecutive([123], [456], [789]) | ||
236 | ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark { | ||
237 | if ($id === 123) { | ||
238 | return $bookmarks[0]; | ||
239 | } | ||
240 | if ($id === 789) { | ||
241 | return $bookmarks[1]; | ||
242 | } | ||
243 | throw new BookmarkNotFoundException(); | ||
244 | }) | ||
245 | ; | ||
246 | $this->container->bookmarkService | ||
247 | ->expects(static::exactly(2)) | ||
248 | ->method('remove') | ||
249 | ->withConsecutive(...array_map(function (Bookmark $bookmark): array { | ||
250 | return [$bookmark, false]; | ||
251 | }, $bookmarks)) | ||
252 | ; | ||
253 | $this->container->bookmarkService->expects(static::once())->method('save'); | ||
254 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
255 | $this->container->formatterFactory | ||
256 | ->expects(static::once()) | ||
257 | ->method('getFormatter') | ||
258 | ->with('raw') | ||
259 | ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter { | ||
260 | $formatter = $this->createMock(BookmarkFormatter::class); | ||
261 | |||
262 | $formatter | ||
263 | ->expects(static::exactly(2)) | ||
264 | ->method('format') | ||
265 | ->withConsecutive(...array_map(function (Bookmark $bookmark): array { | ||
266 | return [$bookmark]; | ||
267 | }, $bookmarks)) | ||
268 | ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array { | ||
269 | return ['formatted' => $bookmark]; | ||
270 | }, $bookmarks)) | ||
271 | ; | ||
272 | |||
273 | return $formatter; | ||
274 | }) | ||
275 | ; | ||
276 | |||
277 | // Make sure that PluginManager hook is not triggered | ||
278 | $this->container->pluginManager | ||
279 | ->expects(static::exactly(2)) | ||
280 | ->method('executeHooks') | ||
281 | ->with('delete_link') | ||
282 | ; | ||
283 | |||
284 | $this->container->sessionManager | ||
285 | ->expects(static::once()) | ||
286 | ->method('setSessionParameter') | ||
287 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 456 could not be found.']) | ||
288 | ; | ||
289 | |||
290 | $result = $this->controller->deleteBookmark($request, $response); | ||
291 | |||
292 | static::assertSame(302, $result->getStatusCode()); | ||
293 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * Delete bookmark - Invalid ID | ||
298 | */ | ||
299 | public function testDeleteInvalidId(): void | ||
300 | { | ||
301 | $parameters = ['id' => 'nope not an ID']; | ||
302 | |||
303 | $request = $this->createMock(Request::class); | ||
304 | $request | ||
305 | ->method('getParam') | ||
306 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
307 | return $parameters[$key] ?? null; | ||
308 | }) | ||
309 | ; | ||
310 | $response = new Response(); | ||
311 | |||
312 | $this->container->sessionManager | ||
313 | ->expects(static::once()) | ||
314 | ->method('setSessionParameter') | ||
315 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) | ||
316 | ; | ||
317 | |||
318 | $result = $this->controller->deleteBookmark($request, $response); | ||
319 | |||
320 | static::assertSame(302, $result->getStatusCode()); | ||
321 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * Delete bookmark - Empty ID | ||
326 | */ | ||
327 | public function testDeleteEmptyId(): void | ||
328 | { | ||
329 | $request = $this->createMock(Request::class); | ||
330 | $response = new Response(); | ||
331 | |||
332 | $this->container->sessionManager | ||
333 | ->expects(static::once()) | ||
334 | ->method('setSessionParameter') | ||
335 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) | ||
336 | ; | ||
337 | |||
338 | $result = $this->controller->deleteBookmark($request, $response); | ||
339 | |||
340 | static::assertSame(302, $result->getStatusCode()); | ||
341 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
342 | } | ||
343 | |||
344 | /** | ||
345 | * Delete bookmark - from bookmarklet | ||
346 | */ | ||
347 | public function testDeleteBookmarkFromBookmarklet(): void | ||
348 | { | ||
349 | $parameters = [ | ||
350 | 'id' => '123', | ||
351 | 'source' => 'bookmarklet', | ||
352 | ]; | ||
353 | |||
354 | $request = $this->createMock(Request::class); | ||
355 | $request | ||
356 | ->method('getParam') | ||
357 | ->willReturnCallback(function (string $key) use ($parameters): ?string { | ||
358 | return $parameters[$key] ?? null; | ||
359 | }) | ||
360 | ; | ||
361 | $response = new Response(); | ||
362 | |||
363 | $this->container->bookmarkService->method('get')->with('123')->willReturn( | ||
364 | (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123') | ||
365 | ); | ||
366 | |||
367 | $this->container->formatterFactory = $this->createMock(FormatterFactory::class); | ||
368 | $this->container->formatterFactory | ||
369 | ->expects(static::once()) | ||
370 | ->method('getFormatter') | ||
371 | ->willReturnCallback(function (): BookmarkFormatter { | ||
372 | $formatter = $this->createMock(BookmarkFormatter::class); | ||
373 | $formatter->method('format')->willReturn(['formatted']); | ||
374 | |||
375 | return $formatter; | ||
376 | }) | ||
377 | ; | ||
378 | |||
379 | $result = $this->controller->deleteBookmark($request, $response); | ||
380 | |||
381 | static::assertSame(200, $result->getStatusCode()); | ||
382 | static::assertSame('<script>self.close();</script>', (string) $result->getBody('location')); | ||
383 | } | ||
384 | } | ||
diff --git a/tests/front/controller/admin/ShaareManageControllerTest/PinBookmarkTest.php b/tests/front/controller/admin/ShaareManageControllerTest/PinBookmarkTest.php new file mode 100644 index 00000000..b89206ce --- /dev/null +++ b/tests/front/controller/admin/ShaareManageControllerTest/PinBookmarkTest.php | |||
@@ -0,0 +1,145 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Front\Controller\Admin\ShaareManageControllerTest; | ||
6 | |||
7 | use Shaarli\Bookmark\Bookmark; | ||
8 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; | ||
9 | use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper; | ||
10 | use Shaarli\Front\Controller\Admin\ShaareManageController; | ||
11 | use Shaarli\Http\HttpAccess; | ||
12 | use Shaarli\Security\SessionManager; | ||
13 | use Shaarli\TestCase; | ||
14 | use Slim\Http\Request; | ||
15 | use Slim\Http\Response; | ||
16 | |||
17 | class PinBookmarkTest extends TestCase | ||
18 | { | ||
19 | use FrontAdminControllerMockHelper; | ||
20 | |||
21 | /** @var ShaareManageController */ | ||
22 | protected $controller; | ||
23 | |||
24 | public function setUp(): void | ||
25 | { | ||
26 | $this->createContainer(); | ||
27 | |||
28 | $this->container->httpAccess = $this->createMock(HttpAccess::class); | ||
29 | $this->controller = new ShaareManageController($this->container); | ||
30 | } | ||
31 | |||
32 | /** | ||
33 | * Test pin bookmark - with valid input | ||
34 | * | ||
35 | * @dataProvider initialStickyValuesProvider() | ||
36 | */ | ||
37 | public function testPinBookmarkIsStickyNull(?bool $sticky, bool $expectedValue): void | ||
38 | { | ||
39 | $id = 123; | ||
40 | |||
41 | $request = $this->createMock(Request::class); | ||
42 | $response = new Response(); | ||
43 | |||
44 | $bookmark = (new Bookmark()) | ||
45 | ->setId(123) | ||
46 | ->setUrl('http://domain.tld') | ||
47 | ->setTitle('Title 123') | ||
48 | ->setSticky($sticky) | ||
49 | ; | ||
50 | |||
51 | $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); | ||
52 | $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, true); | ||
53 | |||
54 | // Make sure that PluginManager hook is triggered | ||
55 | $this->container->pluginManager | ||
56 | ->expects(static::once()) | ||
57 | ->method('executeHooks') | ||
58 | ->with('save_link') | ||
59 | ; | ||
60 | |||
61 | $result = $this->controller->pinBookmark($request, $response, ['id' => (string) $id]); | ||
62 | |||
63 | static::assertSame(302, $result->getStatusCode()); | ||
64 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
65 | |||
66 | static::assertSame($expectedValue, $bookmark->isSticky()); | ||
67 | } | ||
68 | |||
69 | public function initialStickyValuesProvider(): array | ||
70 | { | ||
71 | // [initialStickyState, isStickyAfterPin] | ||
72 | return [[null, true], [false, true], [true, false]]; | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * Test pin bookmark - invalid bookmark ID | ||
77 | */ | ||
78 | public function testDisplayEditFormInvalidId(): void | ||
79 | { | ||
80 | $id = 'invalid'; | ||
81 | |||
82 | $request = $this->createMock(Request::class); | ||
83 | $response = new Response(); | ||
84 | |||
85 | $this->container->sessionManager | ||
86 | ->expects(static::once()) | ||
87 | ->method('setSessionParameter') | ||
88 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier invalid could not be found.']) | ||
89 | ; | ||
90 | |||
91 | $result = $this->controller->pinBookmark($request, $response, ['id' => $id]); | ||
92 | |||
93 | static::assertSame(302, $result->getStatusCode()); | ||
94 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * Test pin bookmark - Bookmark ID not provided | ||
99 | */ | ||
100 | public function testDisplayEditFormIdNotProvided(): void | ||
101 | { | ||
102 | $request = $this->createMock(Request::class); | ||
103 | $response = new Response(); | ||
104 | |||
105 | $this->container->sessionManager | ||
106 | ->expects(static::once()) | ||
107 | ->method('setSessionParameter') | ||
108 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier could not be found.']) | ||
109 | ; | ||
110 | |||
111 | $result = $this->controller->pinBookmark($request, $response, []); | ||
112 | |||
113 | static::assertSame(302, $result->getStatusCode()); | ||
114 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * Test pin bookmark - bookmark not found | ||
119 | */ | ||
120 | public function testDisplayEditFormBookmarkNotFound(): void | ||
121 | { | ||
122 | $id = 123; | ||
123 | |||
124 | $request = $this->createMock(Request::class); | ||
125 | $response = new Response(); | ||
126 | |||
127 | $this->container->bookmarkService | ||
128 | ->expects(static::once()) | ||
129 | ->method('get') | ||
130 | ->with($id) | ||
131 | ->willThrowException(new BookmarkNotFoundException()) | ||
132 | ; | ||
133 | |||
134 | $this->container->sessionManager | ||
135 | ->expects(static::once()) | ||
136 | ->method('setSessionParameter') | ||
137 | ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 123 could not be found.']) | ||
138 | ; | ||
139 | |||
140 | $result = $this->controller->pinBookmark($request, $response, ['id' => (string) $id]); | ||
141 | |||
142 | static::assertSame(302, $result->getStatusCode()); | ||
143 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
144 | } | ||
145 | } | ||
diff --git a/tests/front/controller/admin/ShaareManageControllerTest/SharePrivateTest.php b/tests/front/controller/admin/ShaareManageControllerTest/SharePrivateTest.php new file mode 100644 index 00000000..ae61dfb7 --- /dev/null +++ b/tests/front/controller/admin/ShaareManageControllerTest/SharePrivateTest.php | |||
@@ -0,0 +1,139 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Front\Controller\Admin\ShaareManageControllerTest; | ||
6 | |||
7 | use Shaarli\Bookmark\Bookmark; | ||
8 | use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper; | ||
9 | use Shaarli\Front\Controller\Admin\ShaareManageController; | ||
10 | use Shaarli\Http\HttpAccess; | ||
11 | use Shaarli\TestCase; | ||
12 | use Slim\Http\Request; | ||
13 | use Slim\Http\Response; | ||
14 | |||
15 | /** | ||
16 | * Test GET /admin/shaare/private/{hash} | ||
17 | */ | ||
18 | class SharePrivateTest extends TestCase | ||
19 | { | ||
20 | use FrontAdminControllerMockHelper; | ||
21 | |||
22 | /** @var ShaareManageController */ | ||
23 | protected $controller; | ||
24 | |||
25 | public function setUp(): void | ||
26 | { | ||
27 | $this->createContainer(); | ||
28 | |||
29 | $this->container->httpAccess = $this->createMock(HttpAccess::class); | ||
30 | $this->controller = new ShaareManageController($this->container); | ||
31 | } | ||
32 | |||
33 | /** | ||
34 | * Test shaare private with a private bookmark which does not have a key yet. | ||
35 | */ | ||
36 | public function testSharePrivateWithNewPrivateBookmark(): void | ||
37 | { | ||
38 | $hash = 'abcdcef'; | ||
39 | $request = $this->createMock(Request::class); | ||
40 | $response = new Response(); | ||
41 | |||
42 | $bookmark = (new Bookmark()) | ||
43 | ->setId(123) | ||
44 | ->setUrl('http://domain.tld') | ||
45 | ->setTitle('Title 123') | ||
46 | ->setPrivate(true) | ||
47 | ; | ||
48 | |||
49 | $this->container->bookmarkService | ||
50 | ->expects(static::once()) | ||
51 | ->method('findByHash') | ||
52 | ->with($hash) | ||
53 | ->willReturn($bookmark) | ||
54 | ; | ||
55 | $this->container->bookmarkService | ||
56 | ->expects(static::once()) | ||
57 | ->method('set') | ||
58 | ->with($bookmark, true) | ||
59 | ->willReturnCallback(function (Bookmark $bookmark): Bookmark { | ||
60 | static::assertSame(32, strlen($bookmark->getAdditionalContentEntry('private_key'))); | ||
61 | |||
62 | return $bookmark; | ||
63 | }) | ||
64 | ; | ||
65 | |||
66 | $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); | ||
67 | |||
68 | static::assertSame(302, $result->getStatusCode()); | ||
69 | static::assertRegExp('#/subfolder/shaare/' . $hash . '\?key=\w{32}#', $result->getHeaderLine('Location')); | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * Test shaare private with a private bookmark which does already have a key. | ||
74 | */ | ||
75 | public function testSharePrivateWithExistingPrivateBookmark(): void | ||
76 | { | ||
77 | $hash = 'abcdcef'; | ||
78 | $existingKey = 'this is a private key'; | ||
79 | $request = $this->createMock(Request::class); | ||
80 | $response = new Response(); | ||
81 | |||
82 | $bookmark = (new Bookmark()) | ||
83 | ->setId(123) | ||
84 | ->setUrl('http://domain.tld') | ||
85 | ->setTitle('Title 123') | ||
86 | ->setPrivate(true) | ||
87 | ->addAdditionalContentEntry('private_key', $existingKey) | ||
88 | ; | ||
89 | |||
90 | $this->container->bookmarkService | ||
91 | ->expects(static::once()) | ||
92 | ->method('findByHash') | ||
93 | ->with($hash) | ||
94 | ->willReturn($bookmark) | ||
95 | ; | ||
96 | $this->container->bookmarkService | ||
97 | ->expects(static::never()) | ||
98 | ->method('set') | ||
99 | ; | ||
100 | |||
101 | $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); | ||
102 | |||
103 | static::assertSame(302, $result->getStatusCode()); | ||
104 | static::assertSame('/subfolder/shaare/' . $hash . '?key=' . $existingKey, $result->getHeaderLine('Location')); | ||
105 | } | ||
106 | |||
107 | /** | ||
108 | * Test shaare private with a public bookmark. | ||
109 | */ | ||
110 | public function testSharePrivateWithPublicBookmark(): void | ||
111 | { | ||
112 | $hash = 'abcdcef'; | ||
113 | $request = $this->createMock(Request::class); | ||
114 | $response = new Response(); | ||
115 | |||
116 | $bookmark = (new Bookmark()) | ||
117 | ->setId(123) | ||
118 | ->setUrl('http://domain.tld') | ||
119 | ->setTitle('Title 123') | ||
120 | ->setPrivate(false) | ||
121 | ; | ||
122 | |||
123 | $this->container->bookmarkService | ||
124 | ->expects(static::once()) | ||
125 | ->method('findByHash') | ||
126 | ->with($hash) | ||
127 | ->willReturn($bookmark) | ||
128 | ; | ||
129 | $this->container->bookmarkService | ||
130 | ->expects(static::never()) | ||
131 | ->method('set') | ||
132 | ; | ||
133 | |||
134 | $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); | ||
135 | |||
136 | static::assertSame(302, $result->getStatusCode()); | ||
137 | static::assertSame('/subfolder/shaare/' . $hash, $result->getHeaderLine('Location')); | ||
138 | } | ||
139 | } | ||