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 $this->container
->environment
['HTTP_REFERER'] = 'http://shaarli/subfolder/shaare/abcdef';
43 $request = $this->createMock(Request
::class);
46 ->willReturnCallback(function (string $key) use ($parameters): ?string {
47 return $parameters[$key] ?? null;
50 $response = new Response();
52 $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123');
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')
62 ->willReturnCallback(function () use ($bookmark): BookmarkFormatter
{
63 $formatter = $this->createMock(BookmarkFormatter
::class);
65 ->expects(static::once())
68 ->willReturn(['formatted' => $bookmark])
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])
82 $result = $this->controller
->deleteBookmark($request, $response);
84 static::assertSame(302, $result->getStatusCode());
85 static::assertSame(['/subfolder/'], $result->getHeader('location'));
89 * Delete bookmark - Multiple bookmarks with valid parameters
91 public function testDeleteMultipleBookmarks(): void
93 $parameters = ['id' => '123 456 789'];
95 $this->container
->environment
['HTTP_REFERER'] = 'http://shaarli/subfolder/?searchtags=abcdef';
97 $request = $this->createMock(Request
::class);
100 ->willReturnCallback(function (string $key) use ($parameters): ?string {
101 return $parameters[$key] ?? null;
104 $response = new Response();
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'),
112 $this->container
->bookmarkService
113 ->expects(static::exactly(3))
115 ->withConsecutive([123], [456], [789])
116 ->willReturnOnConsecutiveCalls(...$bookmarks)
118 $this->container
->bookmarkService
119 ->expects(static::exactly(3))
121 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
122 return [$bookmark, false];
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')
131 ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter
{
132 $formatter = $this->createMock(BookmarkFormatter
::class);
135 ->expects(static::exactly(3))
137 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
140 ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark
$bookmark): array {
141 return ['formatted' => $bookmark];
149 // Make sure that PluginManager hook is triggered
150 $this->container
->pluginManager
151 ->expects(static::exactly(3))
152 ->method('executeHooks')
153 ->with('delete_link')
156 $result = $this->controller
->deleteBookmark($request, $response);
158 static::assertSame(302, $result->getStatusCode());
159 static::assertSame(['/subfolder/?searchtags=abcdef'], $result->getHeader('location'));
163 * Delete bookmark - Single bookmark not found in the data store
165 public function testDeleteSingleBookmarkNotFound(): void
167 $parameters = ['id' => '123'];
169 $request = $this->createMock(Request
::class);
172 ->willReturnCallback(function (string $key) use ($parameters): ?string {
173 return $parameters[$key] ?? null;
176 $response = new Response();
178 $this->container
->bookmarkService
179 ->expects(static::once())
181 ->willThrowException(new BookmarkNotFoundException())
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')
190 ->willReturnCallback(function (): BookmarkFormatter
{
191 $formatter = $this->createMock(BookmarkFormatter
::class);
193 $formatter->expects(static::never())->method('format');
198 // Make sure that PluginManager hook is not triggered
199 $this->container
->pluginManager
200 ->expects(static::never())
201 ->method('executeHooks')
202 ->with('delete_link')
205 $result = $this->controller
->deleteBookmark($request, $response);
207 static::assertSame(302, $result->getStatusCode());
208 static::assertSame(['/subfolder/'], $result->getHeader('location'));
212 * Delete bookmark - Multiple bookmarks with one not found in the data store
214 public function testDeleteMultipleBookmarksOneNotFound(): void
216 $parameters = ['id' => '123 456 789'];
218 $request = $this->createMock(Request
::class);
221 ->willReturnCallback(function (string $key) use ($parameters): ?string {
222 return $parameters[$key] ?? null;
225 $response = new Response();
228 (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'),
229 (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'),
232 $this->container
->bookmarkService
233 ->expects(static::exactly(3))
235 ->withConsecutive([123], [456], [789])
236 ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark
{
238 return $bookmarks[0];
241 return $bookmarks[1];
243 throw new BookmarkNotFoundException();
246 $this->container
->bookmarkService
247 ->expects(static::exactly(2))
249 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
250 return [$bookmark, false];
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')
259 ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter
{
260 $formatter = $this->createMock(BookmarkFormatter
::class);
263 ->expects(static::exactly(2))
265 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
268 ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark
$bookmark): array {
269 return ['formatted' => $bookmark];
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')
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.'])
290 $result = $this->controller
->deleteBookmark($request, $response);
292 static::assertSame(302, $result->getStatusCode());
293 static::assertSame(['/subfolder/'], $result->getHeader('location'));
297 * Delete bookmark - Invalid ID
299 public function testDeleteInvalidId(): void
301 $parameters = ['id' => 'nope not an ID'];
303 $request = $this->createMock(Request
::class);
306 ->willReturnCallback(function (string $key) use ($parameters): ?string {
307 return $parameters[$key] ?? null;
310 $response = new Response();
312 $this->container
->sessionManager
313 ->expects(static::once())
314 ->method('setSessionParameter')
315 ->with(SessionManager
::KEY_ERROR_MESSAGES
, ['Invalid bookmark ID provided.'])
318 $result = $this->controller
->deleteBookmark($request, $response);
320 static::assertSame(302, $result->getStatusCode());
321 static::assertSame(['/subfolder/'], $result->getHeader('location'));
325 * Delete bookmark - Empty ID
327 public function testDeleteEmptyId(): void
329 $request = $this->createMock(Request
::class);
330 $response = new Response();
332 $this->container
->sessionManager
333 ->expects(static::once())
334 ->method('setSessionParameter')
335 ->with(SessionManager
::KEY_ERROR_MESSAGES
, ['Invalid bookmark ID provided.'])
338 $result = $this->controller
->deleteBookmark($request, $response);
340 static::assertSame(302, $result->getStatusCode());
341 static::assertSame(['/subfolder/'], $result->getHeader('location'));
345 * Delete bookmark - from bookmarklet
347 public function testDeleteBookmarkFromBookmarklet(): void
351 'source' => 'bookmarklet',
354 $request = $this->createMock(Request
::class);
357 ->willReturnCallback(function (string $key) use ($parameters): ?string {
358 return $parameters[$key] ?? null;
361 $response = new Response();
363 $this->container
->bookmarkService
->method('get')->with('123')->willReturn(
364 (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')
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']);
379 $result = $this->controller
->deleteBookmark($request, $response);
381 static::assertSame(200, $result->getStatusCode());
382 static::assertSame('<script>self.close();</script>', (string) $result->getBody('location'));