session = new Session([]); parent::setUp(); } /** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testInitDoesNotStartSessionWithoutIdentifier() { $req = new HTTPRequest('GET', '/'); $session = new Session(null); // unstarted session $session->init($req); $this->assertFalse($session->isStarted()); } /** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testInitStartsSessionWithIdentifier() { $req = new HTTPRequest('GET', '/'); Cookie::set(session_name(), '1234'); $session = new Session(null); // unstarted session $session->init($req); $this->assertTrue($session->isStarted()); } /** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testInitStartsSessionWithData() { $req = new HTTPRequest('GET', '/'); $session = new Session([]); $session->init($req); $this->assertTrue($session->isStarted()); } /** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testStartUsesDefaultCookieNameWithHttp() { $req = (new HTTPRequest('GET', '/')) ->setScheme('http'); Cookie::set(session_name(), '1234'); $session = new Session(null); // unstarted session $session->start($req); $this->assertNotEquals(session_name(), $session->config()->get('cookie_name_secure')); } /** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testStartUsesDefaultCookieNameWithHttpsAndCookieSecureOff() { $req = (new HTTPRequest('GET', '/')) ->setScheme('https'); Cookie::set(session_name(), '1234'); $session = new Session(null); // unstarted session $session->start($req); $this->assertNotEquals(session_name(), $session->config()->get('cookie_name_secure')); } /** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testStartUsesSecureCookieNameWithHttpsAndCookieSecureOn() { $req = (new HTTPRequest('GET', '/')) ->setScheme('https'); Cookie::set(session_name(), '1234'); $session = new Session(null); // unstarted session $session->config()->update('cookie_secure', true); $session->start($req); $this->assertEquals(session_name(), $session->config()->get('cookie_name_secure')); } /** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testStartErrorsWhenStartingTwice() { $this->expectException(\BadMethodCallException::class); $this->expectExceptionMessage('Session has already started'); $req = new HTTPRequest('GET', '/'); $session = new Session(null); // unstarted session $session->start($req); $session->start($req); } /** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testStartRetainsInMemoryData() { $this->markTestIncomplete('Test'); // TODO Figure out how to simulate session vars without a session_start() resetting them // $_SESSION['existing'] = true; // $_SESSION['merge'] = 1; $req = new HTTPRequest('GET', '/'); $session = new Session(null); // unstarted session $session->set('new', true); $session->set('merge', 2); $session->start($req); // simulate lazy start $this->assertEquals( [ // 'existing' => true, 'new' => true, 'merge' => 2, ], $session->getAll() ); unset($_SESSION); } public function testGetSetBasics() { $this->session->set('Test', 'Test'); $this->assertEquals($this->session->get('Test'), 'Test'); } public function testClearElement() { $this->session->set('Test', 'Test'); $this->session->clear('Test'); $this->assertEquals($this->session->get('Test'), ''); } public function testClearAllElements() { $this->session->set('Test', 'Test'); $this->session->set('Test-1', 'Test-1'); $this->session->clearAll(); // should session get return null? The array key should probably be // unset from the data array $this->assertEquals($this->session->get('Test'), ''); $this->assertEquals($this->session->get('Test-1'), ''); } public function testGetAllElements() { $this->session->clearAll(); // Remove all session that might've been set by the test harness $this->session->set('Test', 'Test'); $this->session->set('Test-2', 'Test-2'); $session = $this->session->getAll(); unset($session['HTTP_USER_AGENT']); $this->assertEquals($session, ['Test' => 'Test', 'Test-2' => 'Test-2']); } public function testSettingExistingDoesntClear() { $s = new Session(['something' => ['does' => 'exist']]); $s->set('something.does', 'exist'); $result = $s->changedData(); unset($result['HTTP_USER_AGENT']); $this->assertEmpty($result); } /** * Check that changedData isn't populated with junk when clearing non-existent entries. */ public function testClearElementThatDoesntExist() { $s = new Session(['something' => ['does' => 'exist']]); $s->clear('something.doesnt.exist'); // Clear without existing data $data = $s->get('something.doesnt.exist'); $this->assertEmpty($s->changedData()); $this->assertNull($data); // Clear with existing change $s->set('something-else', 'val'); $s->clear('something-new'); $data = $s->get('something-else'); $this->assertEquals(['something-else' => true], $s->changedData()); $this->assertEquals('val', $data); } /** * Check that changedData is populated with clearing data. */ public function testClearElementThatDoesExist() { $s = new Session(['something' => ['does' => 'exist']]); // Ensure keys are properly removed and not simply nullified $s->clear('something.does'); $this->assertEquals( ['something' => ['does' => true]], $s->changedData() ); $this->assertEquals( [], // 'does' removed $s->get('something') ); // Clear at more specific level should also clear other changes $s->clear('something'); $this->assertEquals( ['something' => true], $s->changedData() ); $this->assertEquals( null, // Should be removed not just empty array $s->get('something') ); } public function testRequestContainsSessionId() { $req = new HTTPRequest('GET', '/'); $session = new Session(null); // unstarted session $this->assertFalse($session->requestContainsSessionId($req)); Cookie::set(session_name(), '1234'); $this->assertTrue($session->requestContainsSessionId($req)); } public function testRequestContainsSessionIdRespectsCookieNameSecure() { $req = (new HTTPRequest('GET', '/')) ->setScheme('https'); $session = new Session(null); // unstarted session Cookie::set($session->config()->get('cookie_name_secure'), '1234'); $session->config()->update('cookie_secure', true); $this->assertTrue($session->requestContainsSessionId($req)); } public function testUserAgentLockout() { // Set a user agent $req1 = new HTTPRequest('GET', '/'); $req1->addHeader('User-Agent', 'Test Agent'); // Generate our session $s = new Session([]); $s->init($req1); $s->set('val', 123); $s->finalize($req1); // Change our UA $req2 = new HTTPRequest('GET', '/'); $req2->addHeader('User-Agent', 'Fake Agent'); // Verify the new session reset our values $s2 = new Session($s); $s2->init($req2); $this->assertEmpty($s2->get('val')); } public function testDisabledUserAgentLockout() { Session::config()->set('strict_user_agent_check', false); // Set a user agent $req1 = new HTTPRequest('GET', '/'); $req1->addHeader('User-Agent', 'Test Agent'); // Generate our session $s = new Session([]); $s->init($req1); $s->set('val', 123); $s->finalize($req1); // Change our UA $req2 = new HTTPRequest('GET', '/'); $req2->addHeader('User-Agent', 'Fake Agent'); // Verify the new session reset our values $s2 = new Session($s); $s2->init($req2); $this->assertEquals($s2->get('val'), 123); } public function testSave() { $request = new HTTPRequest('GET', '/'); // Test change of nested array type $s = new Session($_SESSION = ['something' => ['some' => 'value', 'another' => 'item']]); $s->set('something', 'string'); $s->save($request); $this->assertEquals( ['something' => 'string'], $_SESSION ); // Test multiple changes combine safely $s = new Session($_SESSION = ['something' => ['some' => 'value', 'another' => 'item']]); $s->set('something.another', 'newanother'); $s->clear('something.some'); $s->set('something.newkey', 'new value'); $s->save($request); $this->assertEquals( [ 'something' => [ 'another' => 'newanother', 'newkey' => 'new value', ], ], $_SESSION ); // Test cleared keys are restorable $s = new Session($_SESSION = ['bookmarks' => [1 => 1, 2 => 2]]); $s->clear('bookmarks'); $s->set('bookmarks', [ 1 => 1, 3 => 3, ]); $s->save($request); $this->assertEquals( [ 'bookmarks' => [ 1 => 1, 3 => 3, ], ], $_SESSION ); } }