aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/front/controller/admin/ShaareManageControllerTest
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2020-10-10 17:40:26 +0200
committerArthurHoaro <arthur@hoa.ro>2020-10-27 20:11:30 +0100
commit5d8de7587d67b5c3e5d1fed8562d9b87ecde80c1 (patch)
tree2236e571035332a63f87a09222f2278b93f63515 /tests/front/controller/admin/ShaareManageControllerTest
parentb8e5a253ab5521ce2be6c0d3e04e0101527df3c1 (diff)
downloadShaarli-5d8de7587d67b5c3e5d1fed8562d9b87ecde80c1.tar.gz
Shaarli-5d8de7587d67b5c3e5d1fed8562d9b87ecde80c1.tar.zst
Shaarli-5d8de7587d67b5c3e5d1fed8562d9b87ecde80c1.zip
Feature: bulk creation of bookmarks
This changes creates a new form in addlink page allowing to create multiple bookmarks at once more easily. It focuses on re-using as much existing code and template component as possible. These changes includes: - a new form in addlink (hidden behind a button by default), containing a text area for URL, and tags/private status to apply to created links - this form displays a new template called editlink.batch, itself including editlink template multiple times - User interation in this new templates are handle by a new JS script (shaare-batch.js) making AJAX requests, and therefore does not need page reloading - ManageShaareController has been split into 3 distinct controllers: + ShaareAdd: displays addlink template + ShaareManage: various operation applied on existing shaares (change visibility, pin, deletion, etc.) + ShaarePublish: handles creation/edit forms and saving Shaare's form - Updated translations Fixes #137
Diffstat (limited to 'tests/front/controller/admin/ShaareManageControllerTest')
-rw-r--r--tests/front/controller/admin/ShaareManageControllerTest/ChangeVisibilityBookmarkTest.php418
-rw-r--r--tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php380
-rw-r--r--tests/front/controller/admin/ShaareManageControllerTest/PinBookmarkTest.php145
-rw-r--r--tests/front/controller/admin/ShaareManageControllerTest/SharePrivateTest.php139
4 files changed, 1082 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
3declare(strict_types=1);
4
5namespace Shaarli\Front\Controller\Admin\ShaareManageControllerTest;
6
7use Shaarli\Bookmark\Bookmark;
8use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
9use Shaarli\Formatter\BookmarkFormatter;
10use Shaarli\Formatter\BookmarkRawFormatter;
11use Shaarli\Formatter\FormatterFactory;
12use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper;
13use Shaarli\Front\Controller\Admin\ShaareManageController;
14use Shaarli\Http\HttpAccess;
15use Shaarli\Security\SessionManager;
16use Shaarli\TestCase;
17use Slim\Http\Request;
18use Slim\Http\Response;
19
20class 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..770a16d7
--- /dev/null
+++ b/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php
@@ -0,0 +1,380 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Shaarli\Front\Controller\Admin\ShaareManageControllerTest;
6
7use Shaarli\Bookmark\Bookmark;
8use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
9use Shaarli\Formatter\BookmarkFormatter;
10use Shaarli\Formatter\FormatterFactory;
11use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper;
12use Shaarli\Front\Controller\Admin\ShaareManageController;
13use Shaarli\Http\HttpAccess;
14use Shaarli\Security\SessionManager;
15use Shaarli\TestCase;
16use Slim\Http\Request;
17use Slim\Http\Response;
18
19class 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 $request = $this->createMock(Request::class);
42 $request
43 ->method('getParam')
44 ->willReturnCallback(function (string $key) use ($parameters): ?string {
45 return $parameters[$key] ?? null;
46 })
47 ;
48 $response = new Response();
49
50 $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123');
51
52 $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark);
53 $this->container->bookmarkService->expects(static::once())->method('remove')->with($bookmark, false);
54 $this->container->bookmarkService->expects(static::once())->method('save');
55 $this->container->formatterFactory = $this->createMock(FormatterFactory::class);
56 $this->container->formatterFactory
57 ->expects(static::once())
58 ->method('getFormatter')
59 ->with('raw')
60 ->willReturnCallback(function () use ($bookmark): BookmarkFormatter {
61 $formatter = $this->createMock(BookmarkFormatter::class);
62 $formatter
63 ->expects(static::once())
64 ->method('format')
65 ->with($bookmark)
66 ->willReturn(['formatted' => $bookmark])
67 ;
68
69 return $formatter;
70 })
71 ;
72
73 // Make sure that PluginManager hook is triggered
74 $this->container->pluginManager
75 ->expects(static::once())
76 ->method('executeHooks')
77 ->with('delete_link', ['formatted' => $bookmark])
78 ;
79
80 $result = $this->controller->deleteBookmark($request, $response);
81
82 static::assertSame(302, $result->getStatusCode());
83 static::assertSame(['/subfolder/'], $result->getHeader('location'));
84 }
85
86 /**
87 * Delete bookmark - Multiple bookmarks with valid parameters
88 */
89 public function testDeleteMultipleBookmarks(): void
90 {
91 $parameters = ['id' => '123 456 789'];
92
93 $request = $this->createMock(Request::class);
94 $request
95 ->method('getParam')
96 ->willReturnCallback(function (string $key) use ($parameters): ?string {
97 return $parameters[$key] ?? null;
98 })
99 ;
100 $response = new Response();
101
102 $bookmarks = [
103 (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'),
104 (new Bookmark())->setId(456)->setUrl('http://domain.tld')->setTitle('Title 456'),
105 (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'),
106 ];
107
108 $this->container->bookmarkService
109 ->expects(static::exactly(3))
110 ->method('get')
111 ->withConsecutive([123], [456], [789])
112 ->willReturnOnConsecutiveCalls(...$bookmarks)
113 ;
114 $this->container->bookmarkService
115 ->expects(static::exactly(3))
116 ->method('remove')
117 ->withConsecutive(...array_map(function (Bookmark $bookmark): array {
118 return [$bookmark, false];
119 }, $bookmarks))
120 ;
121 $this->container->bookmarkService->expects(static::once())->method('save');
122 $this->container->formatterFactory = $this->createMock(FormatterFactory::class);
123 $this->container->formatterFactory
124 ->expects(static::once())
125 ->method('getFormatter')
126 ->with('raw')
127 ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter {
128 $formatter = $this->createMock(BookmarkFormatter::class);
129
130 $formatter
131 ->expects(static::exactly(3))
132 ->method('format')
133 ->withConsecutive(...array_map(function (Bookmark $bookmark): array {
134 return [$bookmark];
135 }, $bookmarks))
136 ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array {
137 return ['formatted' => $bookmark];
138 }, $bookmarks))
139 ;
140
141 return $formatter;
142 })
143 ;
144
145 // Make sure that PluginManager hook is triggered
146 $this->container->pluginManager
147 ->expects(static::exactly(3))
148 ->method('executeHooks')
149 ->with('delete_link')
150 ;
151
152 $result = $this->controller->deleteBookmark($request, $response);
153
154 static::assertSame(302, $result->getStatusCode());
155 static::assertSame(['/subfolder/'], $result->getHeader('location'));
156 }
157
158 /**
159 * Delete bookmark - Single bookmark not found in the data store
160 */
161 public function testDeleteSingleBookmarkNotFound(): void
162 {
163 $parameters = ['id' => '123'];
164
165 $request = $this->createMock(Request::class);
166 $request
167 ->method('getParam')
168 ->willReturnCallback(function (string $key) use ($parameters): ?string {
169 return $parameters[$key] ?? null;
170 })
171 ;
172 $response = new Response();
173
174 $this->container->bookmarkService
175 ->expects(static::once())
176 ->method('get')
177 ->willThrowException(new BookmarkNotFoundException())
178 ;
179 $this->container->bookmarkService->expects(static::never())->method('remove');
180 $this->container->bookmarkService->expects(static::never())->method('save');
181 $this->container->formatterFactory = $this->createMock(FormatterFactory::class);
182 $this->container->formatterFactory
183 ->expects(static::once())
184 ->method('getFormatter')
185 ->with('raw')
186 ->willReturnCallback(function (): BookmarkFormatter {
187 $formatter = $this->createMock(BookmarkFormatter::class);
188
189 $formatter->expects(static::never())->method('format');
190
191 return $formatter;
192 })
193 ;
194 // Make sure that PluginManager hook is not triggered
195 $this->container->pluginManager
196 ->expects(static::never())
197 ->method('executeHooks')
198 ->with('delete_link')
199 ;
200
201 $result = $this->controller->deleteBookmark($request, $response);
202
203 static::assertSame(302, $result->getStatusCode());
204 static::assertSame(['/subfolder/'], $result->getHeader('location'));
205 }
206
207 /**
208 * Delete bookmark - Multiple bookmarks with one not found in the data store
209 */
210 public function testDeleteMultipleBookmarksOneNotFound(): void
211 {
212 $parameters = ['id' => '123 456 789'];
213
214 $request = $this->createMock(Request::class);
215 $request
216 ->method('getParam')
217 ->willReturnCallback(function (string $key) use ($parameters): ?string {
218 return $parameters[$key] ?? null;
219 })
220 ;
221 $response = new Response();
222
223 $bookmarks = [
224 (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'),
225 (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'),
226 ];
227
228 $this->container->bookmarkService
229 ->expects(static::exactly(3))
230 ->method('get')
231 ->withConsecutive([123], [456], [789])
232 ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark {
233 if ($id === 123) {
234 return $bookmarks[0];
235 }
236 if ($id === 789) {
237 return $bookmarks[1];
238 }
239 throw new BookmarkNotFoundException();
240 })
241 ;
242 $this->container->bookmarkService
243 ->expects(static::exactly(2))
244 ->method('remove')
245 ->withConsecutive(...array_map(function (Bookmark $bookmark): array {
246 return [$bookmark, false];
247 }, $bookmarks))
248 ;
249 $this->container->bookmarkService->expects(static::once())->method('save');
250 $this->container->formatterFactory = $this->createMock(FormatterFactory::class);
251 $this->container->formatterFactory
252 ->expects(static::once())
253 ->method('getFormatter')
254 ->with('raw')
255 ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter {
256 $formatter = $this->createMock(BookmarkFormatter::class);
257
258 $formatter
259 ->expects(static::exactly(2))
260 ->method('format')
261 ->withConsecutive(...array_map(function (Bookmark $bookmark): array {
262 return [$bookmark];
263 }, $bookmarks))
264 ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array {
265 return ['formatted' => $bookmark];
266 }, $bookmarks))
267 ;
268
269 return $formatter;
270 })
271 ;
272
273 // Make sure that PluginManager hook is not triggered
274 $this->container->pluginManager
275 ->expects(static::exactly(2))
276 ->method('executeHooks')
277 ->with('delete_link')
278 ;
279
280 $this->container->sessionManager
281 ->expects(static::once())
282 ->method('setSessionParameter')
283 ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 456 could not be found.'])
284 ;
285
286 $result = $this->controller->deleteBookmark($request, $response);
287
288 static::assertSame(302, $result->getStatusCode());
289 static::assertSame(['/subfolder/'], $result->getHeader('location'));
290 }
291
292 /**
293 * Delete bookmark - Invalid ID
294 */
295 public function testDeleteInvalidId(): void
296 {
297 $parameters = ['id' => 'nope not an ID'];
298
299 $request = $this->createMock(Request::class);
300 $request
301 ->method('getParam')
302 ->willReturnCallback(function (string $key) use ($parameters): ?string {
303 return $parameters[$key] ?? null;
304 })
305 ;
306 $response = new Response();
307
308 $this->container->sessionManager
309 ->expects(static::once())
310 ->method('setSessionParameter')
311 ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.'])
312 ;
313
314 $result = $this->controller->deleteBookmark($request, $response);
315
316 static::assertSame(302, $result->getStatusCode());
317 static::assertSame(['/subfolder/'], $result->getHeader('location'));
318 }
319
320 /**
321 * Delete bookmark - Empty ID
322 */
323 public function testDeleteEmptyId(): void
324 {
325 $request = $this->createMock(Request::class);
326 $response = new Response();
327
328 $this->container->sessionManager
329 ->expects(static::once())
330 ->method('setSessionParameter')
331 ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.'])
332 ;
333
334 $result = $this->controller->deleteBookmark($request, $response);
335
336 static::assertSame(302, $result->getStatusCode());
337 static::assertSame(['/subfolder/'], $result->getHeader('location'));
338 }
339
340 /**
341 * Delete bookmark - from bookmarklet
342 */
343 public function testDeleteBookmarkFromBookmarklet(): void
344 {
345 $parameters = [
346 'id' => '123',
347 'source' => 'bookmarklet',
348 ];
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->bookmarkService->method('get')->with('123')->willReturn(
360 (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')
361 );
362
363 $this->container->formatterFactory = $this->createMock(FormatterFactory::class);
364 $this->container->formatterFactory
365 ->expects(static::once())
366 ->method('getFormatter')
367 ->willReturnCallback(function (): BookmarkFormatter {
368 $formatter = $this->createMock(BookmarkFormatter::class);
369 $formatter->method('format')->willReturn(['formatted']);
370
371 return $formatter;
372 })
373 ;
374
375 $result = $this->controller->deleteBookmark($request, $response);
376
377 static::assertSame(200, $result->getStatusCode());
378 static::assertSame('<script>self.close();</script>', (string) $result->getBody('location'));
379 }
380}
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
3declare(strict_types=1);
4
5namespace Shaarli\Front\Controller\Admin\ShaareManageControllerTest;
6
7use Shaarli\Bookmark\Bookmark;
8use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
9use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper;
10use Shaarli\Front\Controller\Admin\ShaareManageController;
11use Shaarli\Http\HttpAccess;
12use Shaarli\Security\SessionManager;
13use Shaarli\TestCase;
14use Slim\Http\Request;
15use Slim\Http\Response;
16
17class 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
3declare(strict_types=1);
4
5namespace Shaarli\Front\Controller\Admin\ShaareManageControllerTest;
6
7use Shaarli\Bookmark\Bookmark;
8use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper;
9use Shaarli\Front\Controller\Admin\ShaareManageController;
10use Shaarli\Http\HttpAccess;
11use Shaarli\TestCase;
12use Slim\Http\Request;
13use Slim\Http\Response;
14
15/**
16 * Test GET /admin/shaare/private/{hash}
17 */
18class 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}