]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - tests/front/controller/admin/ManageTagControllerTest.php
af6f273f899db98758c420efcd2d9a9922e83373
[github/shaarli/Shaarli.git] / tests / front / controller / admin / ManageTagControllerTest.php
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Shaarli\Front\Controller\Admin;
6
7 use Shaarli\Bookmark\Bookmark;
8 use Shaarli\Bookmark\BookmarkFilter;
9 use Shaarli\Config\ConfigManager;
10 use Shaarli\Front\Exception\WrongTokenException;
11 use Shaarli\Security\SessionManager;
12 use Shaarli\TestCase;
13 use Slim\Http\Request;
14 use Slim\Http\Response;
15
16 class ManageTagControllerTest extends TestCase
17 {
18 use FrontAdminControllerMockHelper;
19
20 /** @var ManageTagController */
21 protected $controller;
22
23 public function setUp(): void
24 {
25 $this->createContainer();
26
27 $this->controller = new ManageTagController($this->container);
28 }
29
30 /**
31 * Test displaying manage tag page
32 */
33 public function testIndex(): void
34 {
35 $assignedVariables = [];
36 $this->assignTemplateVars($assignedVariables);
37
38 $request = $this->createMock(Request::class);
39 $request->method('getParam')->with('fromtag')->willReturn('fromtag');
40 $response = new Response();
41
42 $result = $this->controller->index($request, $response);
43
44 static::assertSame(200, $result->getStatusCode());
45 static::assertSame('changetag', (string) $result->getBody());
46
47 static::assertSame('fromtag', $assignedVariables['fromtag']);
48 static::assertSame('@', $assignedVariables['tags_separator']);
49 static::assertSame('Manage tags - Shaarli', $assignedVariables['pagetitle']);
50 }
51
52 /**
53 * Test displaying manage tag page
54 */
55 public function testIndexWhitespaceSeparator(): void
56 {
57 $assignedVariables = [];
58 $this->assignTemplateVars($assignedVariables);
59
60 $this->container->conf = $this->createMock(ConfigManager::class);
61 $this->container->conf->method('get')->willReturnCallback(function (string $key) {
62 return $key === 'general.tags_separator' ? ' ' : $key;
63 });
64
65 $request = $this->createMock(Request::class);
66 $response = new Response();
67
68 $this->controller->index($request, $response);
69
70 static::assertSame('&nbsp;', $assignedVariables['tags_separator']);
71 static::assertSame('whitespace', $assignedVariables['tags_separator_desc']);
72 }
73
74 /**
75 * Test posting a tag update - rename tag - valid info provided.
76 */
77 public function testSaveRenameTagValid(): void
78 {
79 $session = [];
80 $this->assignSessionVars($session);
81
82 $requestParameters = [
83 'renametag' => 'rename',
84 'fromtag' => 'old-tag',
85 'totag' => 'new-tag',
86 ];
87 $request = $this->createMock(Request::class);
88 $request
89 ->expects(static::atLeastOnce())
90 ->method('getParam')
91 ->willReturnCallback(function (string $key) use ($requestParameters): ?string {
92 return $requestParameters[$key] ?? null;
93 })
94 ;
95 $response = new Response();
96
97 $bookmark1 = $this->createMock(Bookmark::class);
98 $bookmark2 = $this->createMock(Bookmark::class);
99 $this->container->bookmarkService
100 ->expects(static::once())
101 ->method('search')
102 ->with(['searchtags' => 'old-tag'], BookmarkFilter::$ALL, true)
103 ->willReturnCallback(function () use ($bookmark1, $bookmark2): array {
104 $bookmark1->expects(static::once())->method('renameTag')->with('old-tag', 'new-tag');
105 $bookmark2->expects(static::once())->method('renameTag')->with('old-tag', 'new-tag');
106
107 return [$bookmark1, $bookmark2];
108 })
109 ;
110 $this->container->bookmarkService
111 ->expects(static::exactly(2))
112 ->method('set')
113 ->withConsecutive([$bookmark1, false], [$bookmark2, false])
114 ;
115 $this->container->bookmarkService->expects(static::once())->method('save');
116
117 $result = $this->controller->save($request, $response);
118
119 static::assertSame(302, $result->getStatusCode());
120 static::assertSame(['/subfolder/?searchtags=new-tag'], $result->getHeader('location'));
121
122 static::assertArrayNotHasKey(SessionManager::KEY_ERROR_MESSAGES, $session);
123 static::assertArrayNotHasKey(SessionManager::KEY_WARNING_MESSAGES, $session);
124 static::assertArrayHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session);
125 static::assertSame(['The tag was renamed in 2 bookmarks.'], $session[SessionManager::KEY_SUCCESS_MESSAGES]);
126 }
127
128 /**
129 * Test posting a tag update - delete tag - valid info provided.
130 */
131 public function testSaveDeleteTagValid(): void
132 {
133 $session = [];
134 $this->assignSessionVars($session);
135
136 $requestParameters = [
137 'deletetag' => 'delete',
138 'fromtag' => 'old-tag',
139 ];
140 $request = $this->createMock(Request::class);
141 $request
142 ->expects(static::atLeastOnce())
143 ->method('getParam')
144 ->willReturnCallback(function (string $key) use ($requestParameters): ?string {
145 return $requestParameters[$key] ?? null;
146 })
147 ;
148 $response = new Response();
149
150 $bookmark1 = $this->createMock(Bookmark::class);
151 $bookmark2 = $this->createMock(Bookmark::class);
152 $this->container->bookmarkService
153 ->expects(static::once())
154 ->method('search')
155 ->with(['searchtags' => 'old-tag'], BookmarkFilter::$ALL, true)
156 ->willReturnCallback(function () use ($bookmark1, $bookmark2): array {
157 $bookmark1->expects(static::once())->method('deleteTag')->with('old-tag');
158 $bookmark2->expects(static::once())->method('deleteTag')->with('old-tag');
159
160 return [$bookmark1, $bookmark2];
161 })
162 ;
163 $this->container->bookmarkService
164 ->expects(static::exactly(2))
165 ->method('set')
166 ->withConsecutive([$bookmark1, false], [$bookmark2, false])
167 ;
168 $this->container->bookmarkService->expects(static::once())->method('save');
169
170 $result = $this->controller->save($request, $response);
171
172 static::assertSame(302, $result->getStatusCode());
173 static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location'));
174
175 static::assertArrayNotHasKey(SessionManager::KEY_ERROR_MESSAGES, $session);
176 static::assertArrayNotHasKey(SessionManager::KEY_WARNING_MESSAGES, $session);
177 static::assertArrayHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session);
178 static::assertSame(['The tag was removed from 2 bookmarks.'], $session[SessionManager::KEY_SUCCESS_MESSAGES]);
179 }
180
181 /**
182 * Test posting a tag update - wrong token.
183 */
184 public function testSaveWrongToken(): void
185 {
186 $this->container->sessionManager = $this->createMock(SessionManager::class);
187 $this->container->sessionManager->method('checkToken')->willReturn(false);
188
189 $this->container->conf->expects(static::never())->method('set');
190 $this->container->conf->expects(static::never())->method('write');
191
192 $request = $this->createMock(Request::class);
193 $response = new Response();
194
195 $this->expectException(WrongTokenException::class);
196
197 $this->controller->save($request, $response);
198 }
199
200 /**
201 * Test posting a tag update - rename tag - missing "FROM" tag.
202 */
203 public function testSaveRenameTagMissingFrom(): void
204 {
205 $session = [];
206 $this->assignSessionVars($session);
207
208 $requestParameters = [
209 'renametag' => 'rename',
210 ];
211 $request = $this->createMock(Request::class);
212 $request
213 ->expects(static::atLeastOnce())
214 ->method('getParam')
215 ->willReturnCallback(function (string $key) use ($requestParameters): ?string {
216 return $requestParameters[$key] ?? null;
217 })
218 ;
219 $response = new Response();
220
221 $result = $this->controller->save($request, $response);
222
223 static::assertSame(302, $result->getStatusCode());
224 static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location'));
225
226 static::assertArrayNotHasKey(SessionManager::KEY_ERROR_MESSAGES, $session);
227 static::assertArrayHasKey(SessionManager::KEY_WARNING_MESSAGES, $session);
228 static::assertArrayNotHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session);
229 static::assertSame(['Invalid tags provided.'], $session[SessionManager::KEY_WARNING_MESSAGES]);
230 }
231
232 /**
233 * Test posting a tag update - delete tag - missing "FROM" tag.
234 */
235 public function testSaveDeleteTagMissingFrom(): void
236 {
237 $session = [];
238 $this->assignSessionVars($session);
239
240 $requestParameters = [
241 'deletetag' => 'delete',
242 ];
243 $request = $this->createMock(Request::class);
244 $request
245 ->expects(static::atLeastOnce())
246 ->method('getParam')
247 ->willReturnCallback(function (string $key) use ($requestParameters): ?string {
248 return $requestParameters[$key] ?? null;
249 })
250 ;
251 $response = new Response();
252
253 $result = $this->controller->save($request, $response);
254
255 static::assertSame(302, $result->getStatusCode());
256 static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location'));
257
258 static::assertArrayNotHasKey(SessionManager::KEY_ERROR_MESSAGES, $session);
259 static::assertArrayHasKey(SessionManager::KEY_WARNING_MESSAGES, $session);
260 static::assertArrayNotHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session);
261 static::assertSame(['Invalid tags provided.'], $session[SessionManager::KEY_WARNING_MESSAGES]);
262 }
263
264 /**
265 * Test posting a tag update - rename tag - missing "TO" tag.
266 */
267 public function testSaveRenameTagMissingTo(): void
268 {
269 $session = [];
270 $this->assignSessionVars($session);
271
272 $requestParameters = [
273 'renametag' => 'rename',
274 'fromtag' => 'old-tag'
275 ];
276 $request = $this->createMock(Request::class);
277 $request
278 ->expects(static::atLeastOnce())
279 ->method('getParam')
280 ->willReturnCallback(function (string $key) use ($requestParameters): ?string {
281 return $requestParameters[$key] ?? null;
282 })
283 ;
284 $response = new Response();
285
286 $result = $this->controller->save($request, $response);
287
288 static::assertSame(302, $result->getStatusCode());
289 static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location'));
290
291 static::assertArrayNotHasKey(SessionManager::KEY_ERROR_MESSAGES, $session);
292 static::assertArrayHasKey(SessionManager::KEY_WARNING_MESSAGES, $session);
293 static::assertArrayNotHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session);
294 static::assertSame(['Invalid tags provided.'], $session[SessionManager::KEY_WARNING_MESSAGES]);
295 }
296
297 /**
298 * Test changeSeparator to '#': redirection + success message.
299 */
300 public function testChangeSeparatorValid(): void
301 {
302 $toSeparator = '#';
303
304 $session = [];
305 $this->assignSessionVars($session);
306
307 $request = $this->createMock(Request::class);
308 $request
309 ->expects(static::atLeastOnce())
310 ->method('getParam')
311 ->willReturnCallback(function (string $key) use ($toSeparator): ?string {
312 return $key === 'separator' ? $toSeparator : $key;
313 })
314 ;
315 $response = new Response();
316
317 $this->container->conf
318 ->expects(static::once())
319 ->method('set')
320 ->with('general.tags_separator', $toSeparator, true, true)
321 ;
322
323 $result = $this->controller->changeSeparator($request, $response);
324
325 static::assertSame(302, $result->getStatusCode());
326 static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location'));
327
328 static::assertArrayNotHasKey(SessionManager::KEY_ERROR_MESSAGES, $session);
329 static::assertArrayNotHasKey(SessionManager::KEY_WARNING_MESSAGES, $session);
330 static::assertArrayHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session);
331 static::assertSame(
332 ['Your tags separator setting has been updated!'],
333 $session[SessionManager::KEY_SUCCESS_MESSAGES]
334 );
335 }
336
337 /**
338 * Test changeSeparator to '#@' (too long): redirection + error message.
339 */
340 public function testChangeSeparatorInvalidTooLong(): void
341 {
342 $toSeparator = '#@';
343
344 $session = [];
345 $this->assignSessionVars($session);
346
347 $request = $this->createMock(Request::class);
348 $request
349 ->expects(static::atLeastOnce())
350 ->method('getParam')
351 ->willReturnCallback(function (string $key) use ($toSeparator): ?string {
352 return $key === 'separator' ? $toSeparator : $key;
353 })
354 ;
355 $response = new Response();
356
357 $this->container->conf->expects(static::never())->method('set');
358
359 $result = $this->controller->changeSeparator($request, $response);
360
361 static::assertSame(302, $result->getStatusCode());
362 static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location'));
363
364 static::assertArrayNotHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session);
365 static::assertArrayNotHasKey(SessionManager::KEY_WARNING_MESSAGES, $session);
366 static::assertArrayHasKey(SessionManager::KEY_ERROR_MESSAGES, $session);
367 static::assertSame(
368 ['Tags separator must be a single character.'],
369 $session[SessionManager::KEY_ERROR_MESSAGES]
370 );
371 }
372
373 /**
374 * Test changeSeparator to '#@' (too long): redirection + error message.
375 */
376 public function testChangeSeparatorInvalidReservedCharacter(): void
377 {
378 $toSeparator = '*';
379
380 $session = [];
381 $this->assignSessionVars($session);
382
383 $request = $this->createMock(Request::class);
384 $request
385 ->expects(static::atLeastOnce())
386 ->method('getParam')
387 ->willReturnCallback(function (string $key) use ($toSeparator): ?string {
388 return $key === 'separator' ? $toSeparator : $key;
389 })
390 ;
391 $response = new Response();
392
393 $this->container->conf->expects(static::never())->method('set');
394
395 $result = $this->controller->changeSeparator($request, $response);
396
397 static::assertSame(302, $result->getStatusCode());
398 static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location'));
399
400 static::assertArrayNotHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session);
401 static::assertArrayNotHasKey(SessionManager::KEY_WARNING_MESSAGES, $session);
402 static::assertArrayHasKey(SessionManager::KEY_ERROR_MESSAGES, $session);
403 static::assertStringStartsWith(
404 'These characters are reserved and can\'t be used as tags separator',
405 $session[SessionManager::KEY_ERROR_MESSAGES][0]
406 );
407 }
408 }