3 declare(strict_types
=1);
5 namespace Shaarli\Front\Controller\Admin\ManageShaareControllerTest
;
7 use PHPUnit\Framework\TestCase
;
8 use Shaarli\Bookmark\Bookmark
;
9 use Shaarli\Bookmark\Exception\BookmarkNotFoundException
;
10 use Shaarli\Formatter\BookmarkFormatter
;
11 use Shaarli\Formatter\FormatterFactory
;
12 use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper
;
13 use Shaarli\Front\Controller\Admin\ManageShaareController
;
14 use Shaarli\Http\HttpAccess
;
15 use Shaarli\Security\SessionManager
;
16 use Slim\Http\Request
;
17 use Slim\Http\Response
;
19 class DeleteBookmarkTest
extends TestCase
21 use FrontAdminControllerMockHelper
;
23 /** @var ManageShaareController */
24 protected $controller;
26 public function setUp(): void
28 $this->createContainer();
30 $this->container
->httpAccess
= $this->createMock(HttpAccess
::class);
31 $this->controller
= new ManageShaareController($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 $formatter->expects(static::once())->method('format')->with($bookmark);
69 // Make sure that PluginManager hook is triggered
70 $this->container
->pluginManager
71 ->expects(static::once())
72 ->method('executeHooks')
76 $result = $this->controller
->deleteBookmark($request, $response);
78 static::assertSame(302, $result->getStatusCode());
79 static::assertSame(['/subfolder/'], $result->getHeader('location'));
83 * Delete bookmark - Multiple bookmarks with valid parameters
85 public function testDeleteMultipleBookmarks(): void
87 $parameters = ['id' => '123 456 789'];
89 $request = $this->createMock(Request
::class);
92 ->willReturnCallback(function (string $key) use ($parameters): ?string {
93 return $parameters[$key] ?? null;
96 $response = new Response();
99 (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'),
100 (new Bookmark())->setId(456)->setUrl('http://domain.tld')->setTitle('Title 456'),
101 (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'),
104 $this->container
->bookmarkService
105 ->expects(static::exactly(3))
107 ->withConsecutive([123], [456], [789])
108 ->willReturnOnConsecutiveCalls(...$bookmarks)
110 $this->container
->bookmarkService
111 ->expects(static::exactly(3))
113 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
114 return [$bookmark, false];
117 $this->container
->bookmarkService
->expects(static::once())->method('save');
118 $this->container
->formatterFactory
= $this->createMock(FormatterFactory
::class);
119 $this->container
->formatterFactory
120 ->expects(static::once())
121 ->method('getFormatter')
123 ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter
{
124 $formatter = $this->createMock(BookmarkFormatter
::class);
127 ->expects(static::exactly(3))
129 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
138 // Make sure that PluginManager hook is triggered
139 $this->container
->pluginManager
140 ->expects(static::exactly(3))
141 ->method('executeHooks')
142 ->with('delete_link')
145 $result = $this->controller
->deleteBookmark($request, $response);
147 static::assertSame(302, $result->getStatusCode());
148 static::assertSame(['/subfolder/'], $result->getHeader('location'));
152 * Delete bookmark - Single bookmark not found in the data store
154 public function testDeleteSingleBookmarkNotFound(): void
156 $parameters = ['id' => '123'];
158 $request = $this->createMock(Request
::class);
161 ->willReturnCallback(function (string $key) use ($parameters): ?string {
162 return $parameters[$key] ?? null;
165 $response = new Response();
167 $this->container
->bookmarkService
168 ->expects(static::once())
170 ->willThrowException(new BookmarkNotFoundException())
172 $this->container
->bookmarkService
->expects(static::never())->method('remove');
173 $this->container
->bookmarkService
->expects(static::never())->method('save');
174 $this->container
->formatterFactory
= $this->createMock(FormatterFactory
::class);
175 $this->container
->formatterFactory
176 ->expects(static::once())
177 ->method('getFormatter')
179 ->willReturnCallback(function (): BookmarkFormatter
{
180 $formatter = $this->createMock(BookmarkFormatter
::class);
182 $formatter->expects(static::never())->method('format');
187 // Make sure that PluginManager hook is not triggered
188 $this->container
->pluginManager
189 ->expects(static::never())
190 ->method('executeHooks')
191 ->with('delete_link')
194 $result = $this->controller
->deleteBookmark($request, $response);
196 static::assertSame(302, $result->getStatusCode());
197 static::assertSame(['/subfolder/'], $result->getHeader('location'));
201 * Delete bookmark - Multiple bookmarks with one not found in the data store
203 public function testDeleteMultipleBookmarksOneNotFound(): void
205 $parameters = ['id' => '123 456 789'];
207 $request = $this->createMock(Request
::class);
210 ->willReturnCallback(function (string $key) use ($parameters): ?string {
211 return $parameters[$key] ?? null;
214 $response = new Response();
217 (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'),
218 (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'),
221 $this->container
->bookmarkService
222 ->expects(static::exactly(3))
224 ->withConsecutive([123], [456], [789])
225 ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark
{
227 return $bookmarks[0];
230 return $bookmarks[1];
232 throw new BookmarkNotFoundException();
235 $this->container
->bookmarkService
236 ->expects(static::exactly(2))
238 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
239 return [$bookmark, false];
242 $this->container
->bookmarkService
->expects(static::once())->method('save');
243 $this->container
->formatterFactory
= $this->createMock(FormatterFactory
::class);
244 $this->container
->formatterFactory
245 ->expects(static::once())
246 ->method('getFormatter')
248 ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter
{
249 $formatter = $this->createMock(BookmarkFormatter
::class);
252 ->expects(static::exactly(2))
254 ->withConsecutive(...array_map(function (Bookmark
$bookmark): array {
263 // Make sure that PluginManager hook is not triggered
264 $this->container
->pluginManager
265 ->expects(static::exactly(2))
266 ->method('executeHooks')
267 ->with('delete_link')
270 $this->container
->sessionManager
271 ->expects(static::once())
272 ->method('setSessionParameter')
273 ->with(SessionManager
::KEY_ERROR_MESSAGES
, ['Bookmark with identifier 456 could not be found.'])
276 $result = $this->controller
->deleteBookmark($request, $response);
278 static::assertSame(302, $result->getStatusCode());
279 static::assertSame(['/subfolder/'], $result->getHeader('location'));
283 * Delete bookmark - Invalid ID
285 public function testDeleteInvalidId(): void
287 $parameters = ['id' => 'nope not an ID'];
289 $request = $this->createMock(Request
::class);
292 ->willReturnCallback(function (string $key) use ($parameters): ?string {
293 return $parameters[$key] ?? null;
296 $response = new Response();
298 $this->container
->sessionManager
299 ->expects(static::once())
300 ->method('setSessionParameter')
301 ->with(SessionManager
::KEY_ERROR_MESSAGES
, ['Invalid bookmark ID provided.'])
304 $result = $this->controller
->deleteBookmark($request, $response);
306 static::assertSame(302, $result->getStatusCode());
307 static::assertSame(['/subfolder/'], $result->getHeader('location'));
311 * Delete bookmark - Empty ID
313 public function testDeleteEmptyId(): void
315 $request = $this->createMock(Request
::class);
316 $response = new Response();
318 $this->container
->sessionManager
319 ->expects(static::once())
320 ->method('setSessionParameter')
321 ->with(SessionManager
::KEY_ERROR_MESSAGES
, ['Invalid bookmark ID provided.'])
324 $result = $this->controller
->deleteBookmark($request, $response);
326 static::assertSame(302, $result->getStatusCode());
327 static::assertSame(['/subfolder/'], $result->getHeader('location'));
331 * Delete bookmark - from bookmarklet
333 public function testDeleteBookmarkFromBookmarklet(): void
337 'source' => 'bookmarklet',
340 $request = $this->createMock(Request
::class);
343 ->willReturnCallback(function (string $key) use ($parameters): ?string {
344 return $parameters[$key] ?? null;
347 $response = new Response();
349 $this->container
->formatterFactory
= $this->createMock(FormatterFactory
::class);
350 $this->container
->formatterFactory
351 ->expects(static::once())
352 ->method('getFormatter')
353 ->willReturn($this->createMock(BookmarkFormatter
::class))
356 $result = $this->controller
->deleteBookmark($request, $response);
358 static::assertSame(200, $result->getStatusCode());
359 static::assertSame('<script>self.close();</script>', (string) $result->getBody('location'));