aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/HttpUtils/ClientIpIdTest.php52
-rw-r--r--tests/SessionManagerTest.php149
-rw-r--r--tests/security/LoginManagerTest.php (renamed from tests/LoginManagerTest.php)183
-rw-r--r--tests/security/SessionManagerTest.php273
-rw-r--r--tests/utils/FakeConfigManager.php12
5 files changed, 516 insertions, 153 deletions
diff --git a/tests/HttpUtils/ClientIpIdTest.php b/tests/HttpUtils/ClientIpIdTest.php
new file mode 100644
index 00000000..c15ac5cc
--- /dev/null
+++ b/tests/HttpUtils/ClientIpIdTest.php
@@ -0,0 +1,52 @@
1<?php
2/**
3 * HttpUtils' tests
4 */
5
6require_once 'application/HttpUtils.php';
7
8/**
9 * Unitary tests for client_ip_id()
10 */
11class ClientIpIdTest extends PHPUnit_Framework_TestCase
12{
13 /**
14 * Get a remote client ID based on its IP
15 */
16 public function testClientIpIdRemote()
17 {
18 $this->assertEquals(
19 '10.1.167.42',
20 client_ip_id(['REMOTE_ADDR' => '10.1.167.42'])
21 );
22 }
23
24 /**
25 * Get a remote client ID based on its IP and proxy information (1)
26 */
27 public function testClientIpIdRemoteForwarded()
28 {
29 $this->assertEquals(
30 '10.1.167.42_127.0.1.47',
31 client_ip_id([
32 'REMOTE_ADDR' => '10.1.167.42',
33 'HTTP_X_FORWARDED_FOR' => '127.0.1.47'
34 ])
35 );
36 }
37
38 /**
39 * Get a remote client ID based on its IP and proxy information (2)
40 */
41 public function testClientIpIdRemoteForwardedClient()
42 {
43 $this->assertEquals(
44 '10.1.167.42_10.1.167.56_127.0.1.47',
45 client_ip_id([
46 'REMOTE_ADDR' => '10.1.167.42',
47 'HTTP_X_FORWARDED_FOR' => '10.1.167.56',
48 'HTTP_CLIENT_IP' => '127.0.1.47'
49 ])
50 );
51 }
52}
diff --git a/tests/SessionManagerTest.php b/tests/SessionManagerTest.php
deleted file mode 100644
index aa75962a..00000000
--- a/tests/SessionManagerTest.php
+++ /dev/null
@@ -1,149 +0,0 @@
1<?php
2require_once 'tests/utils/FakeConfigManager.php';
3
4// Initialize reference data _before_ PHPUnit starts a session
5require_once 'tests/utils/ReferenceSessionIdHashes.php';
6ReferenceSessionIdHashes::genAllHashes();
7
8use \Shaarli\SessionManager;
9use \PHPUnit\Framework\TestCase;
10
11
12/**
13 * Test coverage for SessionManager
14 */
15class SessionManagerTest extends TestCase
16{
17 // Session ID hashes
18 protected static $sidHashes = null;
19
20 // Fake ConfigManager
21 protected static $conf = null;
22
23 /**
24 * Assign reference data
25 */
26 public static function setUpBeforeClass()
27 {
28 self::$sidHashes = ReferenceSessionIdHashes::getHashes();
29 self::$conf = new FakeConfigManager();
30 }
31
32 /**
33 * Generate a session token
34 */
35 public function testGenerateToken()
36 {
37 $session = [];
38 $sessionManager = new SessionManager($session, self::$conf);
39
40 $token = $sessionManager->generateToken();
41
42 $this->assertEquals(1, $session['tokens'][$token]);
43 $this->assertEquals(40, strlen($token));
44 }
45
46 /**
47 * Check a session token
48 */
49 public function testCheckToken()
50 {
51 $token = '4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b';
52 $session = [
53 'tokens' => [
54 $token => 1,
55 ],
56 ];
57 $sessionManager = new SessionManager($session, self::$conf);
58
59 // check and destroy the token
60 $this->assertTrue($sessionManager->checkToken($token));
61 $this->assertFalse(isset($session['tokens'][$token]));
62
63 // ensure the token has been destroyed
64 $this->assertFalse($sessionManager->checkToken($token));
65 }
66
67 /**
68 * Generate and check a session token
69 */
70 public function testGenerateAndCheckToken()
71 {
72 $session = [];
73 $sessionManager = new SessionManager($session, self::$conf);
74
75 $token = $sessionManager->generateToken();
76
77 // ensure a token has been generated
78 $this->assertEquals(1, $session['tokens'][$token]);
79 $this->assertEquals(40, strlen($token));
80
81 // check and destroy the token
82 $this->assertTrue($sessionManager->checkToken($token));
83 $this->assertFalse(isset($session['tokens'][$token]));
84
85 // ensure the token has been destroyed
86 $this->assertFalse($sessionManager->checkToken($token));
87 }
88
89 /**
90 * Check an invalid session token
91 */
92 public function testCheckInvalidToken()
93 {
94 $session = [];
95 $sessionManager = new SessionManager($session, self::$conf);
96
97 $this->assertFalse($sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b'));
98 }
99
100 /**
101 * Test SessionManager::checkId with a valid ID - TEST ALL THE HASHES!
102 *
103 * This tests extensively covers all hash algorithms / bit representations
104 */
105 public function testIsAnyHashSessionIdValid()
106 {
107 foreach (self::$sidHashes as $algo => $bpcs) {
108 foreach ($bpcs as $bpc => $hash) {
109 $this->assertTrue(SessionManager::checkId($hash));
110 }
111 }
112 }
113
114 /**
115 * Test checkId with a valid ID - SHA-1 hashes
116 */
117 public function testIsSha1SessionIdValid()
118 {
119 $this->assertTrue(SessionManager::checkId(sha1('shaarli')));
120 }
121
122 /**
123 * Test checkId with a valid ID - SHA-256 hashes
124 */
125 public function testIsSha256SessionIdValid()
126 {
127 $this->assertTrue(SessionManager::checkId(hash('sha256', 'shaarli')));
128 }
129
130 /**
131 * Test checkId with a valid ID - SHA-512 hashes
132 */
133 public function testIsSha512SessionIdValid()
134 {
135 $this->assertTrue(SessionManager::checkId(hash('sha512', 'shaarli')));
136 }
137
138 /**
139 * Test checkId with invalid IDs.
140 */
141 public function testIsSessionIdInvalid()
142 {
143 $this->assertFalse(SessionManager::checkId(''));
144 $this->assertFalse(SessionManager::checkId([]));
145 $this->assertFalse(
146 SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
147 );
148 }
149}
diff --git a/tests/LoginManagerTest.php b/tests/security/LoginManagerTest.php
index 4159038e..f26cd1eb 100644
--- a/tests/LoginManagerTest.php
+++ b/tests/security/LoginManagerTest.php
@@ -1,5 +1,5 @@
1<?php 1<?php
2namespace Shaarli; 2namespace Shaarli\Security;
3 3
4require_once 'tests/utils/FakeConfigManager.php'; 4require_once 'tests/utils/FakeConfigManager.php';
5use \PHPUnit\Framework\TestCase; 5use \PHPUnit\Framework\TestCase;
@@ -9,15 +9,54 @@ use \PHPUnit\Framework\TestCase;
9 */ 9 */
10class LoginManagerTest extends TestCase 10class LoginManagerTest extends TestCase
11{ 11{
12 /** @var \FakeConfigManager Configuration Manager instance */
12 protected $configManager = null; 13 protected $configManager = null;
14
15 /** @var LoginManager Login Manager instance */
13 protected $loginManager = null; 16 protected $loginManager = null;
17
18 /** @var SessionManager Session Manager instance */
19 protected $sessionManager = null;
20
21 /** @var string Banned IP filename */
14 protected $banFile = 'sandbox/ipbans.php'; 22 protected $banFile = 'sandbox/ipbans.php';
23
24 /** @var string Log filename */
15 protected $logFile = 'sandbox/shaarli.log'; 25 protected $logFile = 'sandbox/shaarli.log';
26
27 /** @var array Simulates the $_COOKIE array */
28 protected $cookie = [];
29
30 /** @var array Simulates the $GLOBALS array */
16 protected $globals = []; 31 protected $globals = [];
17 protected $ipAddr = '127.0.0.1'; 32
33 /** @var array Simulates the $_SERVER array */
18 protected $server = []; 34 protected $server = [];
35
36 /** @var array Simulates the $_SESSION array */
37 protected $session = [];
38
39 /** @var string Advertised client IP address */
40 protected $clientIpAddress = '10.1.47.179';
41
42 /** @var string Local client IP address */
43 protected $ipAddr = '127.0.0.1';
44
45 /** @var string Trusted proxy IP address */
19 protected $trustedProxy = '10.1.1.100'; 46 protected $trustedProxy = '10.1.1.100';
20 47
48 /** @var string User login */
49 protected $login = 'johndoe';
50
51 /** @var string User password */
52 protected $password = 'IC4nHazL0g1n?';
53
54 /** @var string Hash of the salted user password */
55 protected $passwordHash = '';
56
57 /** @var string Salt used by hash functions */
58 protected $salt = '669e24fa9c5a59a613f98e8e38327384504a4af2';
59
21 /** 60 /**
22 * Prepare or reset test resources 61 * Prepare or reset test resources
23 */ 62 */
@@ -27,7 +66,12 @@ class LoginManagerTest extends TestCase
27 unlink($this->banFile); 66 unlink($this->banFile);
28 } 67 }
29 68
69 $this->passwordHash = sha1($this->password . $this->login . $this->salt);
70
30 $this->configManager = new \FakeConfigManager([ 71 $this->configManager = new \FakeConfigManager([
72 'credentials.login' => $this->login,
73 'credentials.hash' => $this->passwordHash,
74 'credentials.salt' => $this->salt,
31 'resource.ban_file' => $this->banFile, 75 'resource.ban_file' => $this->banFile,
32 'resource.log' => $this->logFile, 76 'resource.log' => $this->logFile,
33 'security.ban_after' => 4, 77 'security.ban_after' => 4,
@@ -35,10 +79,15 @@ class LoginManagerTest extends TestCase
35 'security.trusted_proxies' => [$this->trustedProxy], 79 'security.trusted_proxies' => [$this->trustedProxy],
36 ]); 80 ]);
37 81
82 $this->cookie = [];
83
38 $this->globals = &$GLOBALS; 84 $this->globals = &$GLOBALS;
39 unset($this->globals['IPBANS']); 85 unset($this->globals['IPBANS']);
40 86
41 $this->loginManager = new LoginManager($this->globals, $this->configManager); 87 $this->session = [];
88
89 $this->sessionManager = new SessionManager($this->session, $this->configManager);
90 $this->loginManager = new LoginManager($this->globals, $this->configManager, $this->sessionManager);
42 $this->server['REMOTE_ADDR'] = $this->ipAddr; 91 $this->server['REMOTE_ADDR'] = $this->ipAddr;
43 } 92 }
44 93
@@ -59,7 +108,7 @@ class LoginManagerTest extends TestCase
59 $this->banFile, 108 $this->banFile,
60 "<?php\n\$GLOBALS['IPBANS']=array('FAILURES' => array('127.0.0.1' => 99));\n?>" 109 "<?php\n\$GLOBALS['IPBANS']=array('FAILURES' => array('127.0.0.1' => 99));\n?>"
61 ); 110 );
62 new LoginManager($this->globals, $this->configManager); 111 new LoginManager($this->globals, $this->configManager, null);
63 $this->assertEquals(99, $this->globals['IPBANS']['FAILURES']['127.0.0.1']); 112 $this->assertEquals(99, $this->globals['IPBANS']['FAILURES']['127.0.0.1']);
64 } 113 }
65 114
@@ -196,4 +245,130 @@ class LoginManagerTest extends TestCase
196 $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() - 3600; 245 $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() - 3600;
197 $this->assertTrue($this->loginManager->canLogin($this->server)); 246 $this->assertTrue($this->loginManager->canLogin($this->server));
198 } 247 }
248
249 /**
250 * Generate a token depending on the user credentials and client IP
251 */
252 public function testGenerateStaySignedInToken()
253 {
254 $this->loginManager->generateStaySignedInToken($this->clientIpAddress);
255
256 $this->assertEquals(
257 sha1($this->passwordHash . $this->clientIpAddress . $this->salt),
258 $this->loginManager->getStaySignedInToken()
259 );
260 }
261
262 /**
263 * Check user login - Shaarli has not yet been configured
264 */
265 public function testCheckLoginStateNotConfigured()
266 {
267 $configManager = new \FakeConfigManager([
268 'resource.ban_file' => $this->banFile,
269 ]);
270 $loginManager = new LoginManager($this->globals, $configManager, null);
271 $loginManager->checkLoginState([], '');
272
273 $this->assertFalse($loginManager->isLoggedIn());
274 }
275
276 /**
277 * Check user login - the client cookie does not match the server token
278 */
279 public function testCheckLoginStateStaySignedInWithInvalidToken()
280 {
281 // simulate a previous login
282 $this->session = [
283 'ip' => $this->clientIpAddress,
284 'expires_on' => time() + 100,
285 ];
286 $this->loginManager->generateStaySignedInToken($this->clientIpAddress);
287 $this->cookie[LoginManager::$STAY_SIGNED_IN_COOKIE] = 'nope';
288
289 $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress);
290
291 $this->assertTrue($this->loginManager->isLoggedIn());
292 $this->assertTrue(empty($this->session['username']));
293 }
294
295 /**
296 * Check user login - the client cookie matches the server token
297 */
298 public function testCheckLoginStateStaySignedInWithValidToken()
299 {
300 $this->loginManager->generateStaySignedInToken($this->clientIpAddress);
301 $this->cookie[LoginManager::$STAY_SIGNED_IN_COOKIE] = $this->loginManager->getStaySignedInToken();
302
303 $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress);
304
305 $this->assertTrue($this->loginManager->isLoggedIn());
306 $this->assertEquals($this->login, $this->session['username']);
307 $this->assertEquals($this->clientIpAddress, $this->session['ip']);
308 }
309
310 /**
311 * Check user login - the session has expired
312 */
313 public function testCheckLoginStateSessionExpired()
314 {
315 $this->loginManager->generateStaySignedInToken($this->clientIpAddress);
316 $this->session['expires_on'] = time() - 100;
317
318 $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress);
319
320 $this->assertFalse($this->loginManager->isLoggedIn());
321 }
322
323 /**
324 * Check user login - the remote client IP has changed
325 */
326 public function testCheckLoginStateClientIpChanged()
327 {
328 $this->loginManager->generateStaySignedInToken($this->clientIpAddress);
329
330 $this->loginManager->checkLoginState($this->cookie, '10.7.157.98');
331
332 $this->assertFalse($this->loginManager->isLoggedIn());
333 }
334
335 /**
336 * Check user credentials - wrong login supplied
337 */
338 public function testCheckCredentialsWrongLogin()
339 {
340 $this->assertFalse(
341 $this->loginManager->checkCredentials('', '', 'b4dl0g1n', $this->password)
342 );
343 }
344
345 /**
346 * Check user credentials - wrong password supplied
347 */
348 public function testCheckCredentialsWrongPassword()
349 {
350 $this->assertFalse(
351 $this->loginManager->checkCredentials('', '', $this->login, 'b4dp455wd')
352 );
353 }
354
355 /**
356 * Check user credentials - wrong login and password supplied
357 */
358 public function testCheckCredentialsWrongLoginAndPassword()
359 {
360 $this->assertFalse(
361 $this->loginManager->checkCredentials('', '', 'b4dl0g1n', 'b4dp455wd')
362 );
363 }
364
365 /**
366 * Check user credentials - correct login and password supplied
367 */
368 public function testCheckCredentialsGoodLoginAndPassword()
369 {
370 $this->assertTrue(
371 $this->loginManager->checkCredentials('', '', $this->login, $this->password)
372 );
373 }
199} 374}
diff --git a/tests/security/SessionManagerTest.php b/tests/security/SessionManagerTest.php
new file mode 100644
index 00000000..9bd868f8
--- /dev/null
+++ b/tests/security/SessionManagerTest.php
@@ -0,0 +1,273 @@
1<?php
2require_once 'tests/utils/FakeConfigManager.php';
3
4// Initialize reference data _before_ PHPUnit starts a session
5require_once 'tests/utils/ReferenceSessionIdHashes.php';
6ReferenceSessionIdHashes::genAllHashes();
7
8use \Shaarli\Security\SessionManager;
9use \PHPUnit\Framework\TestCase;
10
11
12/**
13 * Test coverage for SessionManager
14 */
15class SessionManagerTest extends TestCase
16{
17 /** @var array Session ID hashes */
18 protected static $sidHashes = null;
19
20 /** @var \FakeConfigManager ConfigManager substitute for testing */
21 protected $conf = null;
22
23 /** @var array $_SESSION array for testing */
24 protected $session = [];
25
26 /** @var SessionManager Server-side session management abstraction */
27 protected $sessionManager = null;
28
29 /**
30 * Assign reference data
31 */
32 public static function setUpBeforeClass()
33 {
34 self::$sidHashes = ReferenceSessionIdHashes::getHashes();
35 }
36
37 /**
38 * Initialize or reset test resources
39 */
40 public function setUp()
41 {
42 $this->conf = new FakeConfigManager([
43 'credentials.login' => 'johndoe',
44 'credentials.salt' => 'salt',
45 'security.session_protection_disabled' => false,
46 ]);
47 $this->session = [];
48 $this->sessionManager = new SessionManager($this->session, $this->conf);
49 }
50
51 /**
52 * Generate a session token
53 */
54 public function testGenerateToken()
55 {
56 $token = $this->sessionManager->generateToken();
57
58 $this->assertEquals(1, $this->session['tokens'][$token]);
59 $this->assertEquals(40, strlen($token));
60 }
61
62 /**
63 * Check a session token
64 */
65 public function testCheckToken()
66 {
67 $token = '4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b';
68 $session = [
69 'tokens' => [
70 $token => 1,
71 ],
72 ];
73 $sessionManager = new SessionManager($session, $this->conf);
74
75 // check and destroy the token
76 $this->assertTrue($sessionManager->checkToken($token));
77 $this->assertFalse(isset($session['tokens'][$token]));
78
79 // ensure the token has been destroyed
80 $this->assertFalse($sessionManager->checkToken($token));
81 }
82
83 /**
84 * Generate and check a session token
85 */
86 public function testGenerateAndCheckToken()
87 {
88 $token = $this->sessionManager->generateToken();
89
90 // ensure a token has been generated
91 $this->assertEquals(1, $this->session['tokens'][$token]);
92 $this->assertEquals(40, strlen($token));
93
94 // check and destroy the token
95 $this->assertTrue($this->sessionManager->checkToken($token));
96 $this->assertFalse(isset($this->session['tokens'][$token]));
97
98 // ensure the token has been destroyed
99 $this->assertFalse($this->sessionManager->checkToken($token));
100 }
101
102 /**
103 * Check an invalid session token
104 */
105 public function testCheckInvalidToken()
106 {
107 $this->assertFalse($this->sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b'));
108 }
109
110 /**
111 * Test SessionManager::checkId with a valid ID - TEST ALL THE HASHES!
112 *
113 * This tests extensively covers all hash algorithms / bit representations
114 */
115 public function testIsAnyHashSessionIdValid()
116 {
117 foreach (self::$sidHashes as $algo => $bpcs) {
118 foreach ($bpcs as $bpc => $hash) {
119 $this->assertTrue(SessionManager::checkId($hash));
120 }
121 }
122 }
123
124 /**
125 * Test checkId with a valid ID - SHA-1 hashes
126 */
127 public function testIsSha1SessionIdValid()
128 {
129 $this->assertTrue(SessionManager::checkId(sha1('shaarli')));
130 }
131
132 /**
133 * Test checkId with a valid ID - SHA-256 hashes
134 */
135 public function testIsSha256SessionIdValid()
136 {
137 $this->assertTrue(SessionManager::checkId(hash('sha256', 'shaarli')));
138 }
139
140 /**
141 * Test checkId with a valid ID - SHA-512 hashes
142 */
143 public function testIsSha512SessionIdValid()
144 {
145 $this->assertTrue(SessionManager::checkId(hash('sha512', 'shaarli')));
146 }
147
148 /**
149 * Test checkId with invalid IDs.
150 */
151 public function testIsSessionIdInvalid()
152 {
153 $this->assertFalse(SessionManager::checkId(''));
154 $this->assertFalse(SessionManager::checkId([]));
155 $this->assertFalse(
156 SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
157 );
158 }
159
160 /**
161 * Store login information after a successful login
162 */
163 public function testStoreLoginInfo()
164 {
165 $this->sessionManager->storeLoginInfo('ip_id');
166
167 $this->assertGreaterThan(time(), $this->session['expires_on']);
168 $this->assertEquals('ip_id', $this->session['ip']);
169 $this->assertEquals('johndoe', $this->session['username']);
170 }
171
172 /**
173 * Extend a server-side session by SessionManager::$SHORT_TIMEOUT
174 */
175 public function testExtendSession()
176 {
177 $this->sessionManager->extendSession();
178
179 $this->assertGreaterThan(time(), $this->session['expires_on']);
180 $this->assertLessThanOrEqual(
181 time() + SessionManager::$SHORT_TIMEOUT,
182 $this->session['expires_on']
183 );
184 }
185
186 /**
187 * Extend a server-side session by SessionManager::$LONG_TIMEOUT
188 */
189 public function testExtendSessionStaySignedIn()
190 {
191 $this->sessionManager->setStaySignedIn(true);
192 $this->sessionManager->extendSession();
193
194 $this->assertGreaterThan(time(), $this->session['expires_on']);
195 $this->assertGreaterThan(
196 time() + SessionManager::$LONG_TIMEOUT - 10,
197 $this->session['expires_on']
198 );
199 $this->assertLessThanOrEqual(
200 time() + SessionManager::$LONG_TIMEOUT,
201 $this->session['expires_on']
202 );
203 }
204
205 /**
206 * Unset session variables after logging out
207 */
208 public function testLogout()
209 {
210 $this->session = [
211 'ip' => 'ip_id',
212 'expires_on' => time() + 1000,
213 'username' => 'johndoe',
214 'visibility' => 'public',
215 'untaggedonly' => false,
216 ];
217 $this->sessionManager->logout();
218
219 $this->assertFalse(isset($this->session['ip']));
220 $this->assertFalse(isset($this->session['expires_on']));
221 $this->assertFalse(isset($this->session['username']));
222 $this->assertFalse(isset($this->session['visibility']));
223 $this->assertFalse(isset($this->session['untaggedonly']));
224 }
225
226 /**
227 * The session is active and expiration time has been reached
228 */
229 public function testHasExpiredTimeElapsed()
230 {
231 $this->session['expires_on'] = time() - 10;
232
233 $this->assertTrue($this->sessionManager->hasSessionExpired());
234 }
235
236 /**
237 * The session is active and expiration time has not been reached
238 */
239 public function testHasNotExpired()
240 {
241 $this->session['expires_on'] = time() + 1000;
242
243 $this->assertFalse($this->sessionManager->hasSessionExpired());
244 }
245
246 /**
247 * Session hijacking protection is disabled, we assume the IP has not changed
248 */
249 public function testHasClientIpChangedNoSessionProtection()
250 {
251 $this->conf->set('security.session_protection_disabled', true);
252
253 $this->assertFalse($this->sessionManager->hasClientIpChanged(''));
254 }
255
256 /**
257 * The client IP identifier has not changed
258 */
259 public function testHasClientIpChangedNope()
260 {
261 $this->session['ip'] = 'ip_id';
262 $this->assertFalse($this->sessionManager->hasClientIpChanged('ip_id'));
263 }
264
265 /**
266 * The client IP identifier has changed
267 */
268 public function testHasClientIpChanged()
269 {
270 $this->session['ip'] = 'ip_id_one';
271 $this->assertTrue($this->sessionManager->hasClientIpChanged('ip_id_two'));
272 }
273}
diff --git a/tests/utils/FakeConfigManager.php b/tests/utils/FakeConfigManager.php
index 85434de7..360b34a9 100644
--- a/tests/utils/FakeConfigManager.php
+++ b/tests/utils/FakeConfigManager.php
@@ -42,4 +42,16 @@ class FakeConfigManager
42 } 42 }
43 return $key; 43 return $key;
44 } 44 }
45
46 /**
47 * Check if a setting exists
48 *
49 * @param string $setting Asked setting, keys separated with dots
50 *
51 * @return bool true if the setting exists, false otherwise
52 */
53 public function exists($setting)
54 {
55 return array_key_exists($setting, $this->values);
56 }
45} 57}