3 declare(strict_types
=1);
5 namespace Shaarli\Front\Controller\Admin\ShaareManageControllerTest
;
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
;
16 use Slim\Http\Request
;
17 use Slim\Http\Response
;
19 class DeleteBookmarkTest
extends TestCase
21 use FrontAdminControllerMockHelper
;
23 /** @var ShaareManageController */
24 protected $controller;
26 public function setUp(): void
28 $this->createContainer();
30 $this->container
->httpAccess
= $this->createMock(HttpAccess
::class);
31 $this->controller
= new ShaareManageController($this->container
);
35 * Delete bookmark - Single bookmark with valid parameters
37 public function testDeleteSingleBookmark(): void
39 $parameters = ['id' => '123'];
41 $request = $this->createMock(Request
::class);
44 ->willReturnCallback(function (string $key) use ($parameters): ?string {
45 return $parameters[$key] ?? null;
48 $response = new Response();
50 $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123');
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')
60 ->willReturnCallback(function () use ($bookmark): BookmarkFormatter
{
61 $formatter = $this->createMock(BookmarkFormatter
::class);
63 ->expects(static::once())
66 ->willReturn(['formatted' => $bookmark])
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])
80 $result = $this->controller
->deleteBookmark($request, $response);
82 static::assertSame(302, $result->getStatusCode());
83 static::assertSame(['/subfolder/'], $result->getHeader('location'));
87 * Delete bookmark - Multiple bookmarks with valid parameters
89 public function testDeleteMultipleBookmarks(): void
91 $parameters = ['id' => '123 456 789'];
93 $request = $this->createMock(Request
::class);
96 ->willReturnCallback(function (string $key) use ($parameters): ?string {
97 return $parameters[$key] ?? null;
100 $response = new Response();
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'),
108 $this->container
->bookmarkService
109 ->expects(static::exactly(3))
111 ->withConsecutive([123], [456], [789])
112 ->willReturnOnConsecutiveCalls(...$bookmarks)
114 $this->container
->bookmarkService
115 ->expects(static::exactly(3))
117 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
118 return [$bookmark, false];
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')
127 ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter
{
128 $formatter = $this->createMock(BookmarkFormatter
::class);
131 ->expects(static::exactly(3))
133 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
136 ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark
$bookmark): array {
137 return ['formatted' => $bookmark];
145 // Make sure that PluginManager hook is triggered
146 $this->container
->pluginManager
147 ->expects(static::exactly(3))
148 ->method('executeHooks')
149 ->with('delete_link')
152 $result = $this->controller
->deleteBookmark($request, $response);
154 static::assertSame(302, $result->getStatusCode());
155 static::assertSame(['/subfolder/'], $result->getHeader('location'));
159 * Delete bookmark - Single bookmark not found in the data store
161 public function testDeleteSingleBookmarkNotFound(): void
163 $parameters = ['id' => '123'];
165 $request = $this->createMock(Request
::class);
168 ->willReturnCallback(function (string $key) use ($parameters): ?string {
169 return $parameters[$key] ?? null;
172 $response = new Response();
174 $this->container
->bookmarkService
175 ->expects(static::once())
177 ->willThrowException(new BookmarkNotFoundException())
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')
186 ->willReturnCallback(function (): BookmarkFormatter
{
187 $formatter = $this->createMock(BookmarkFormatter
::class);
189 $formatter->expects(static::never())->method('format');
194 // Make sure that PluginManager hook is not triggered
195 $this->container
->pluginManager
196 ->expects(static::never())
197 ->method('executeHooks')
198 ->with('delete_link')
201 $result = $this->controller
->deleteBookmark($request, $response);
203 static::assertSame(302, $result->getStatusCode());
204 static::assertSame(['/subfolder/'], $result->getHeader('location'));
208 * Delete bookmark - Multiple bookmarks with one not found in the data store
210 public function testDeleteMultipleBookmarksOneNotFound(): void
212 $parameters = ['id' => '123 456 789'];
214 $request = $this->createMock(Request
::class);
217 ->willReturnCallback(function (string $key) use ($parameters): ?string {
218 return $parameters[$key] ?? null;
221 $response = new Response();
224 (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'),
225 (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'),
228 $this->container
->bookmarkService
229 ->expects(static::exactly(3))
231 ->withConsecutive([123], [456], [789])
232 ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark
{
234 return $bookmarks[0];
237 return $bookmarks[1];
239 throw new BookmarkNotFoundException();
242 $this->container
->bookmarkService
243 ->expects(static::exactly(2))
245 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
246 return [$bookmark, false];
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')
255 ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter
{
256 $formatter = $this->createMock(BookmarkFormatter
::class);
259 ->expects(static::exactly(2))
261 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
264 ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark
$bookmark): array {
265 return ['formatted' => $bookmark];
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')
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.'])
286 $result = $this->controller
->deleteBookmark($request, $response);
288 static::assertSame(302, $result->getStatusCode());
289 static::assertSame(['/subfolder/'], $result->getHeader('location'));
293 * Delete bookmark - Invalid ID
295 public function testDeleteInvalidId(): void
297 $parameters = ['id' => 'nope not an ID'];
299 $request = $this->createMock(Request
::class);
302 ->willReturnCallback(function (string $key) use ($parameters): ?string {
303 return $parameters[$key] ?? null;
306 $response = new Response();
308 $this->container
->sessionManager
309 ->expects(static::once())
310 ->method('setSessionParameter')
311 ->with(SessionManager
::KEY_ERROR_MESSAGES
, ['Invalid bookmark ID provided.'])
314 $result = $this->controller
->deleteBookmark($request, $response);
316 static::assertSame(302, $result->getStatusCode());
317 static::assertSame(['/subfolder/'], $result->getHeader('location'));
321 * Delete bookmark - Empty ID
323 public function testDeleteEmptyId(): void
325 $request = $this->createMock(Request
::class);
326 $response = new Response();
328 $this->container
->sessionManager
329 ->expects(static::once())
330 ->method('setSessionParameter')
331 ->with(SessionManager
::KEY_ERROR_MESSAGES
, ['Invalid bookmark ID provided.'])
334 $result = $this->controller
->deleteBookmark($request, $response);
336 static::assertSame(302, $result->getStatusCode());
337 static::assertSame(['/subfolder/'], $result->getHeader('location'));
341 * Delete bookmark - from bookmarklet
343 public function testDeleteBookmarkFromBookmarklet(): void
347 'source' => 'bookmarklet',
350 $request = $this->createMock(Request
::class);
353 ->willReturnCallback(function (string $key) use ($parameters): ?string {
354 return $parameters[$key] ?? null;
357 $response = new Response();
359 $this->container
->bookmarkService
->method('get')->with('123')->willReturn(
360 (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')
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']);
375 $result = $this->controller
->deleteBookmark($request, $response);
377 static::assertSame(200, $result->getStatusCode());
378 static::assertSame('<script>self.close();</script>', (string) $result->getBody('location'));