101 lines
3.4 KiB
PHP
101 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace Tests\App\Controllers\Api;
|
|
|
|
use App\Controllers\View\SessionTimeoutController;
|
|
use CodeIgniter\HTTP\IncomingRequest;
|
|
use CodeIgniter\HTTP\URI;
|
|
use CodeIgniter\HTTP\UserAgent;
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
|
use Config\App;
|
|
use Config\Services;
|
|
|
|
class SessionTimeoutControllerTest extends CIUnitTestCase
|
|
{
|
|
protected function tearDown(): void
|
|
{
|
|
parent::tearDown();
|
|
session()->destroy();
|
|
Services::resetSingle('response');
|
|
}
|
|
|
|
public function testGetTimeoutConfigIncludesThirtyMinuteSettings(): void
|
|
{
|
|
$this->expectOutputRegex('/^\s*$/');
|
|
|
|
$response = $this->controller()->getTimeoutConfig();
|
|
$body = json_decode((string) $response->getBody(), true);
|
|
|
|
$this->assertTrue($body['success']);
|
|
$this->assertSame(1800, $body['timeout']);
|
|
$this->assertSame(30, $body['warning_time']);
|
|
$this->assertSame(30000, $body['check_interval']);
|
|
$this->assertSame(60000, $body['ping_interval']);
|
|
$this->assertStringContainsString('session/check-timeout', $body['check_url']);
|
|
$this->assertStringContainsString('session/ping-activity', $body['keep_alive_url']);
|
|
}
|
|
|
|
public function testCheckTimeoutReturnsActiveWhenFresh(): void
|
|
{
|
|
session()->set('last_activity', time());
|
|
|
|
$response = $this->controller()->checkTimeout();
|
|
$body = json_decode((string) $response->getBody(), true);
|
|
|
|
$this->assertSame('active', $body['status']);
|
|
$this->assertGreaterThan(0, $body['time_remaining']);
|
|
}
|
|
|
|
public function testCheckTimeoutExpiresAfterThirtyMinutesOfInactivity(): void
|
|
{
|
|
session()->set('last_activity', time() - 1800);
|
|
|
|
$response = $this->controller()->checkTimeout();
|
|
$body = json_decode((string) $response->getBody(), true);
|
|
|
|
$this->assertSame('expired', $body['status']);
|
|
$this->assertStringContainsString('login', $body['redirect']);
|
|
}
|
|
|
|
public function testPingActivityRefreshesSession(): void
|
|
{
|
|
session()->set('last_activity', time() - 60);
|
|
|
|
$response = $this->controller()->pingActivity();
|
|
$body = json_decode((string) $response->getBody(), true);
|
|
|
|
$this->assertSame('active', $body['status']);
|
|
$this->assertSame(1800, $body['time_remaining']);
|
|
$this->assertGreaterThanOrEqual(time() - 1, session()->get('last_activity'));
|
|
}
|
|
|
|
public function testHeartbeatRoutesAreNotRateLimited(): void
|
|
{
|
|
$routes = file_get_contents(ROOTPATH . 'app/Config/Routes.php') ?: '';
|
|
|
|
$this->assertStringContainsString(
|
|
"\$routes->post('session/ping-activity', 'View\\SessionTimeoutController::pingActivity');",
|
|
$routes
|
|
);
|
|
$this->assertStringContainsString(
|
|
"\$routes->post('session/ping', 'View\\SessionTimeoutController::pingActivity');",
|
|
$routes
|
|
);
|
|
$this->assertDoesNotMatchRegularExpression(
|
|
"/session\\/(?:ping-activity|ping).*apiratelimit/",
|
|
$routes
|
|
);
|
|
}
|
|
|
|
private function controller(): SessionTimeoutController
|
|
{
|
|
Services::resetSingle('response');
|
|
|
|
$controller = new SessionTimeoutController();
|
|
$request = new IncomingRequest(config(App::class), new URI('https://example.test/session/check-timeout'), 'php://input', new UserAgent());
|
|
$controller->initController($request, Services::response(), Services::logger());
|
|
|
|
return $controller;
|
|
}
|
|
}
|