aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/front/ShaarliMiddlewareTest.php7
-rw-r--r--tests/front/controller/visitor/FrontControllerMockHelper.php1
-rw-r--r--tests/front/controller/visitor/LoginControllerTest.php278
3 files changed, 281 insertions, 5 deletions
diff --git a/tests/front/ShaarliMiddlewareTest.php b/tests/front/ShaarliMiddlewareTest.php
index 20090d8b..09bebd04 100644
--- a/tests/front/ShaarliMiddlewareTest.php
+++ b/tests/front/ShaarliMiddlewareTest.php
@@ -38,6 +38,8 @@ class ShaarliMiddlewareTest extends TestCase
38 38
39 $this->container->loginManager = $this->createMock(LoginManager::class); 39 $this->container->loginManager = $this->createMock(LoginManager::class);
40 40
41 $this->container->environment = ['REQUEST_URI' => 'http://shaarli/subfolder/path'];
42
41 $this->middleware = new ShaarliMiddleware($this->container); 43 $this->middleware = new ShaarliMiddleware($this->container);
42 } 44 }
43 45
@@ -127,7 +129,10 @@ class ShaarliMiddlewareTest extends TestCase
127 $result = $this->middleware->__invoke($request, $response, $controller); 129 $result = $this->middleware->__invoke($request, $response, $controller);
128 130
129 static::assertSame(302, $result->getStatusCode()); 131 static::assertSame(302, $result->getStatusCode());
130 static::assertSame('/subfolder/login', $result->getHeader('location')[0]); 132 static::assertSame(
133 '/subfolder/login?returnurl=' . urlencode('http://shaarli/subfolder/path'),
134 $result->getHeader('location')[0]
135 );
131 } 136 }
132 137
133 /** 138 /**
diff --git a/tests/front/controller/visitor/FrontControllerMockHelper.php b/tests/front/controller/visitor/FrontControllerMockHelper.php
index 7f560662..e0bd4ecf 100644
--- a/tests/front/controller/visitor/FrontControllerMockHelper.php
+++ b/tests/front/controller/visitor/FrontControllerMockHelper.php
@@ -80,6 +80,7 @@ trait FrontControllerMockHelper
80 'SERVER_NAME' => 'shaarli', 80 'SERVER_NAME' => 'shaarli',
81 'SERVER_PORT' => '80', 81 'SERVER_PORT' => '80',
82 'REQUEST_URI' => '/daily-rss', 82 'REQUEST_URI' => '/daily-rss',
83 'REMOTE_ADDR' => '1.2.3.4',
83 ]; 84 ];
84 85
85 $this->container->basePath = '/subfolder'; 86 $this->container->basePath = '/subfolder';
diff --git a/tests/front/controller/visitor/LoginControllerTest.php b/tests/front/controller/visitor/LoginControllerTest.php
index e57f44b9..0a21f938 100644
--- a/tests/front/controller/visitor/LoginControllerTest.php
+++ b/tests/front/controller/visitor/LoginControllerTest.php
@@ -7,6 +7,10 @@ namespace Shaarli\Front\Controller\Visitor;
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Shaarli\Config\ConfigManager; 8use Shaarli\Config\ConfigManager;
9use Shaarli\Front\Exception\LoginBannedException; 9use Shaarli\Front\Exception\LoginBannedException;
10use Shaarli\Front\Exception\WrongTokenException;
11use Shaarli\Render\TemplatePage;
12use Shaarli\Security\CookieManager;
13use Shaarli\Security\SessionManager;
10use Slim\Http\Request; 14use Slim\Http\Request;
11use Slim\Http\Response; 15use Slim\Http\Response;
12 16
@@ -21,13 +25,25 @@ class LoginControllerTest extends TestCase
21 { 25 {
22 $this->createContainer(); 26 $this->createContainer();
23 27
28 $this->container->cookieManager = $this->createMock(CookieManager::class);
29 $this->container->sessionManager->method('checkToken')->willReturn(true);
30
24 $this->controller = new LoginController($this->container); 31 $this->controller = new LoginController($this->container);
25 } 32 }
26 33
34 /**
35 * Test displaying login form with valid parameters.
36 */
27 public function testValidControllerInvoke(): void 37 public function testValidControllerInvoke(): void
28 { 38 {
29 $request = $this->createMock(Request::class); 39 $request = $this->createMock(Request::class);
30 $request->expects(static::once())->method('getServerParam')->willReturn('> referer'); 40 $request
41 ->expects(static::atLeastOnce())
42 ->method('getParam')
43 ->willReturnCallback(function (string $key) {
44 return 'returnurl' === $key ? '> referer' : null;
45 })
46 ;
31 $response = new Response(); 47 $response = new Response();
32 48
33 $assignedVariables = []; 49 $assignedVariables = [];
@@ -46,18 +62,32 @@ class LoginControllerTest extends TestCase
46 62
47 static::assertInstanceOf(Response::class, $result); 63 static::assertInstanceOf(Response::class, $result);
48 static::assertSame(200, $result->getStatusCode()); 64 static::assertSame(200, $result->getStatusCode());
49 static::assertSame('loginform', (string) $result->getBody()); 65 static::assertSame(TemplatePage::LOGIN, (string) $result->getBody());
50 66
51 static::assertSame('> referer', $assignedVariables['returnurl']); 67 static::assertSame('> referer', $assignedVariables['returnurl']);
52 static::assertSame(true, $assignedVariables['remember_user_default']); 68 static::assertSame(true, $assignedVariables['remember_user_default']);
53 static::assertSame('Login - Shaarli', $assignedVariables['pagetitle']); 69 static::assertSame('Login - Shaarli', $assignedVariables['pagetitle']);
54 } 70 }
55 71
72 /**
73 * Test displaying login form with username defined in the request.
74 */
56 public function testValidControllerInvokeWithUserName(): void 75 public function testValidControllerInvokeWithUserName(): void
57 { 76 {
77 $this->container->environment = ['HTTP_REFERER' => '> referer'];
78
58 $request = $this->createMock(Request::class); 79 $request = $this->createMock(Request::class);
59 $request->expects(static::once())->method('getServerParam')->willReturn('> referer'); 80 $request
60 $request->expects(static::exactly(2))->method('getParam')->willReturn('myUser>'); 81 ->expects(static::atLeastOnce())
82 ->method('getParam')
83 ->willReturnCallback(function (string $key, $default) {
84 if ('login' === $key) {
85 return 'myUser>';
86 }
87
88 return $default;
89 })
90 ;
61 $response = new Response(); 91 $response = new Response();
62 92
63 $assignedVariables = []; 93 $assignedVariables = [];
@@ -84,6 +114,9 @@ class LoginControllerTest extends TestCase
84 static::assertSame('Login - Shaarli', $assignedVariables['pagetitle']); 114 static::assertSame('Login - Shaarli', $assignedVariables['pagetitle']);
85 } 115 }
86 116
117 /**
118 * Test displaying login page while being logged in.
119 */
87 public function testLoginControllerWhileLoggedIn(): void 120 public function testLoginControllerWhileLoggedIn(): void
88 { 121 {
89 $request = $this->createMock(Request::class); 122 $request = $this->createMock(Request::class);
@@ -98,6 +131,9 @@ class LoginControllerTest extends TestCase
98 static::assertSame(['/subfolder/'], $result->getHeader('Location')); 131 static::assertSame(['/subfolder/'], $result->getHeader('Location'));
99 } 132 }
100 133
134 /**
135 * Test displaying login page with open shaarli configured: redirect to homepage.
136 */
101 public function testLoginControllerOpenShaarli(): void 137 public function testLoginControllerOpenShaarli(): void
102 { 138 {
103 $request = $this->createMock(Request::class); 139 $request = $this->createMock(Request::class);
@@ -119,6 +155,9 @@ class LoginControllerTest extends TestCase
119 static::assertSame(['/subfolder/'], $result->getHeader('Location')); 155 static::assertSame(['/subfolder/'], $result->getHeader('Location'));
120 } 156 }
121 157
158 /**
159 * Test displaying login page while being banned.
160 */
122 public function testLoginControllerWhileBanned(): void 161 public function testLoginControllerWhileBanned(): void
123 { 162 {
124 $request = $this->createMock(Request::class); 163 $request = $this->createMock(Request::class);
@@ -131,4 +170,235 @@ class LoginControllerTest extends TestCase
131 170
132 $this->controller->index($request, $response); 171 $this->controller->index($request, $response);
133 } 172 }
173
174 /**
175 * Test processing login with valid parameters.
176 */
177 public function testProcessLoginWithValidParameters(): void
178 {
179 $parameters = [
180 'login' => 'bob',
181 'password' => 'pass',
182 ];
183 $request = $this->createMock(Request::class);
184 $request
185 ->expects(static::atLeastOnce())
186 ->method('getParam')
187 ->willReturnCallback(function (string $key) use ($parameters) {
188 return $parameters[$key] ?? null;
189 })
190 ;
191 $response = new Response();
192
193 $this->container->loginManager->method('canLogin')->willReturn(true);
194 $this->container->loginManager->expects(static::once())->method('handleSuccessfulLogin');
195 $this->container->loginManager
196 ->expects(static::once())
197 ->method('checkCredentials')
198 ->with('1.2.3.4', '1.2.3.4', 'bob', 'pass')
199 ->willReturn(true)
200 ;
201 $this->container->loginManager->method('getStaySignedInToken')->willReturn(bin2hex(random_bytes(8)));
202
203 $this->container->sessionManager->expects(static::never())->method('extendSession');
204 $this->container->sessionManager->expects(static::once())->method('destroy');
205 $this->container->sessionManager
206 ->expects(static::once())
207 ->method('cookieParameters')
208 ->with(0, '/subfolder/', 'shaarli')
209 ;
210 $this->container->sessionManager->expects(static::once())->method('start');
211 $this->container->sessionManager->expects(static::once())->method('regenerateId')->with(true);
212
213 $result = $this->controller->login($request, $response);
214
215 static::assertSame(302, $result->getStatusCode());
216 static::assertSame('/subfolder/', $result->getHeader('location')[0]);
217 }
218
219 /**
220 * Test processing login with return URL.
221 */
222 public function testProcessLoginWithReturnUrl(): void
223 {
224 $parameters = [
225 'returnurl' => 'http://shaarli/subfolder/admin/shaare',
226 ];
227 $request = $this->createMock(Request::class);
228 $request
229 ->expects(static::atLeastOnce())
230 ->method('getParam')
231 ->willReturnCallback(function (string $key) use ($parameters) {
232 return $parameters[$key] ?? null;
233 })
234 ;
235 $response = new Response();
236
237 $this->container->loginManager->method('canLogin')->willReturn(true);
238 $this->container->loginManager->expects(static::once())->method('handleSuccessfulLogin');
239 $this->container->loginManager->expects(static::once())->method('checkCredentials')->willReturn(true);
240 $this->container->loginManager->method('getStaySignedInToken')->willReturn(bin2hex(random_bytes(8)));
241
242 $result = $this->controller->login($request, $response);
243
244 static::assertSame(302, $result->getStatusCode());
245 static::assertSame('/subfolder/admin/shaare', $result->getHeader('location')[0]);
246 }
247
248 /**
249 * Test processing login with remember me session enabled.
250 */
251 public function testProcessLoginLongLastingSession(): void
252 {
253 $parameters = [
254 'longlastingsession' => true,
255 ];
256 $request = $this->createMock(Request::class);
257 $request
258 ->expects(static::atLeastOnce())
259 ->method('getParam')
260 ->willReturnCallback(function (string $key) use ($parameters) {
261 return $parameters[$key] ?? null;
262 })
263 ;
264 $response = new Response();
265
266 $this->container->loginManager->method('canLogin')->willReturn(true);
267 $this->container->loginManager->expects(static::once())->method('handleSuccessfulLogin');
268 $this->container->loginManager->expects(static::once())->method('checkCredentials')->willReturn(true);
269 $this->container->loginManager->method('getStaySignedInToken')->willReturn(bin2hex(random_bytes(8)));
270
271 $this->container->sessionManager->expects(static::once())->method('destroy');
272 $this->container->sessionManager
273 ->expects(static::once())
274 ->method('cookieParameters')
275 ->with(42, '/subfolder/', 'shaarli')
276 ;
277 $this->container->sessionManager->expects(static::once())->method('start');
278 $this->container->sessionManager->expects(static::once())->method('regenerateId')->with(true);
279 $this->container->sessionManager->expects(static::once())->method('extendSession')->willReturn(42);
280
281 $this->container->cookieManager = $this->createMock(CookieManager::class);
282 $this->container->cookieManager
283 ->expects(static::once())
284 ->method('setCookieParameter')
285 ->willReturnCallback(function (string $name): CookieManager {
286 static::assertSame(CookieManager::STAY_SIGNED_IN, $name);
287
288 return $this->container->cookieManager;
289 })
290 ;
291
292 $result = $this->controller->login($request, $response);
293
294 static::assertSame(302, $result->getStatusCode());
295 static::assertSame('/subfolder/', $result->getHeader('location')[0]);
296 }
297
298 /**
299 * Test processing login with invalid credentials
300 */
301 public function testProcessLoginWrongCredentials(): void
302 {
303 $parameters = [
304 'returnurl' => 'http://shaarli/subfolder/admin/shaare',
305 ];
306 $request = $this->createMock(Request::class);
307 $request
308 ->expects(static::atLeastOnce())
309 ->method('getParam')
310 ->willReturnCallback(function (string $key) use ($parameters) {
311 return $parameters[$key] ?? null;
312 })
313 ;
314 $response = new Response();
315
316 $this->container->loginManager->method('canLogin')->willReturn(true);
317 $this->container->loginManager->expects(static::once())->method('handleFailedLogin');
318 $this->container->loginManager->expects(static::once())->method('checkCredentials')->willReturn(false);
319
320 $this->container->sessionManager
321 ->expects(static::once())
322 ->method('setSessionParameter')
323 ->with(SessionManager::KEY_ERROR_MESSAGES, ['Wrong login/password.'])
324 ;
325
326 $result = $this->controller->login($request, $response);
327
328 static::assertSame(200, $result->getStatusCode());
329 static::assertSame(TemplatePage::LOGIN, (string) $result->getBody());
330 }
331
332 /**
333 * Test processing login with wrong token
334 */
335 public function testProcessLoginWrongToken(): void
336 {
337 $request = $this->createMock(Request::class);
338 $response = new Response();
339
340 $this->container->sessionManager = $this->createMock(SessionManager::class);
341 $this->container->sessionManager->method('checkToken')->willReturn(false);
342
343 $this->expectException(WrongTokenException::class);
344
345 $this->controller->login($request, $response);
346 }
347
348 /**
349 * Test processing login with wrong token
350 */
351 public function testProcessLoginAlreadyLoggedIn(): void
352 {
353 $request = $this->createMock(Request::class);
354 $response = new Response();
355
356 $this->container->loginManager->method('isLoggedIn')->willReturn(true);
357 $this->container->loginManager->expects(static::never())->method('handleSuccessfulLogin');
358 $this->container->loginManager->expects(static::never())->method('handleFailedLogin');
359
360 $result = $this->controller->login($request, $response);
361
362 static::assertSame(302, $result->getStatusCode());
363 static::assertSame('/subfolder/', $result->getHeader('location')[0]);
364 }
365
366 /**
367 * Test processing login with wrong token
368 */
369 public function testProcessLoginInOpenShaarli(): void
370 {
371 $request = $this->createMock(Request::class);
372 $response = new Response();
373
374 $this->container->conf = $this->createMock(ConfigManager::class);
375 $this->container->conf->method('get')->willReturnCallback(function (string $key, $value) {
376 return 'security.open_shaarli' === $key ? true : $value;
377 });
378
379 $this->container->loginManager->expects(static::never())->method('handleSuccessfulLogin');
380 $this->container->loginManager->expects(static::never())->method('handleFailedLogin');
381
382 $result = $this->controller->login($request, $response);
383
384 static::assertSame(302, $result->getStatusCode());
385 static::assertSame('/subfolder/', $result->getHeader('location')[0]);
386 }
387
388 /**
389 * Test processing login while being banned
390 */
391 public function testProcessLoginWhileBanned(): void
392 {
393 $request = $this->createMock(Request::class);
394 $response = new Response();
395
396 $this->container->loginManager->method('canLogin')->willReturn(false);
397 $this->container->loginManager->expects(static::never())->method('handleSuccessfulLogin');
398 $this->container->loginManager->expects(static::never())->method('handleFailedLogin');
399
400 $this->expectException(LoginBannedException::class);
401
402 $this->controller->login($request, $response);
403 }
134} 404}