2021-06-07 00:15:28 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace CodeIgniter;
|
2016-03-29 22:30:05 +09:00
|
|
|
|
2018-11-30 18:20:13 -02:00
|
|
|
use \CodeIgniter\Config\Services;
|
2020-04-23 01:27:54 +07:00
|
|
|
use CodeIgniter\Router\RouteCollection;
|
2021-02-28 06:57:05 +07:00
|
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
2020-04-23 01:27:54 +07:00
|
|
|
use CodeIgniter\Test\Mock\MockCodeIgniter;
|
|
|
|
use Config\App;
|
2021-02-28 06:57:05 +07:00
|
|
|
use Config\Modules;
|
2016-03-30 07:30:02 +09:00
|
|
|
|
2017-02-09 19:33:03 +09:00
|
|
|
/**
|
|
|
|
* @backupGlobals enabled
|
2021-06-25 22:27:37 +08:00
|
|
|
*
|
|
|
|
* @internal
|
2017-02-09 19:33:03 +09:00
|
|
|
*/
|
2021-06-25 22:27:37 +08:00
|
|
|
final class CodeIgniterTest extends CIUnitTestCase
|
2016-03-29 22:30:05 +09:00
|
|
|
{
|
2021-06-04 22:51:52 +08:00
|
|
|
/**
|
|
|
|
* @var CodeIgniter
|
|
|
|
*/
|
|
|
|
protected $codeigniter;
|
|
|
|
|
|
|
|
protected $routes;
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
protected function setUp(): void
|
|
|
|
{
|
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
Services::reset();
|
|
|
|
|
|
|
|
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
|
|
|
|
|
|
|
|
$config = new App();
|
|
|
|
$this->codeigniter = new MockCodeIgniter($config);
|
|
|
|
}
|
|
|
|
|
2021-06-24 23:37:45 +08:00
|
|
|
protected function tearDown(): void
|
2021-06-04 22:51:52 +08:00
|
|
|
{
|
|
|
|
parent::tearDown();
|
|
|
|
|
2021-06-07 19:06:26 +08:00
|
|
|
if (count( ob_list_handlers() ) > 1) {
|
2021-06-04 22:51:52 +08:00
|
|
|
ob_end_clean();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
public function testRunEmptyDefaultRoute()
|
|
|
|
{
|
|
|
|
$_SERVER['argv'] = [
|
|
|
|
'index.php',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 1;
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
$output = ob_get_clean();
|
|
|
|
|
|
|
|
$this->assertStringContainsString('Welcome to CodeIgniter', $output);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
public function testRunClosureRoute()
|
|
|
|
{
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argv'] = [
|
2021-06-04 22:51:52 +08:00
|
|
|
'index.php',
|
|
|
|
'pages/about',
|
|
|
|
];
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
|
2021-06-04 22:51:52 +08:00
|
|
|
$_SERVER['REQUEST_URI'] = '/pages/about';
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = Services::routes();
|
2021-06-07 03:44:42 +02:00
|
|
|
$routes->add('pages/(:segment)', static function ($segment) {
|
2021-06-04 22:51:52 +08:00
|
|
|
echo 'You want to see "' . esc($segment) . '" page.';
|
|
|
|
});
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
$output = ob_get_clean();
|
|
|
|
|
|
|
|
$this->assertStringContainsString('You want to see "about" page.', $output);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
public function testRun404Override()
|
|
|
|
{
|
|
|
|
$_SERVER['argv'] = [
|
|
|
|
'index.php',
|
|
|
|
'/',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = Services::routes();
|
|
|
|
$routes->setAutoRoute(false);
|
|
|
|
$routes->set404Override('Home::index');
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
$output = ob_get_clean();
|
|
|
|
|
|
|
|
$this->assertStringContainsString('Welcome to CodeIgniter', $output);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
public function testRun404OverrideByClosure()
|
|
|
|
{
|
|
|
|
$_SERVER['argv'] = [
|
|
|
|
'index.php',
|
|
|
|
'/',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = new RouteCollection(Services::locator(), new Modules());
|
|
|
|
$routes->setAutoRoute(false);
|
2021-06-07 03:44:42 +02:00
|
|
|
$routes->set404Override(static function () {
|
2021-06-04 22:51:52 +08:00
|
|
|
echo '404 Override by Closure.';
|
|
|
|
});
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run($routes);
|
|
|
|
$output = ob_get_clean();
|
|
|
|
|
|
|
|
$this->assertStringContainsString('404 Override by Closure.', $output);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
public function testControllersCanReturnString()
|
|
|
|
{
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argv'] = [
|
2021-06-04 22:51:52 +08:00
|
|
|
'index.php',
|
|
|
|
'pages/about',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
$_SERVER['REQUEST_URI'] = '/pages/about';
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = Services::routes();
|
2021-06-07 03:44:42 +02:00
|
|
|
$routes->add('pages/(:segment)', static function ($segment) {
|
2021-06-04 22:51:52 +08:00
|
|
|
return 'You want to see "' . esc($segment) . '" page.';
|
|
|
|
});
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
$output = ob_get_clean();
|
|
|
|
|
|
|
|
$this->assertStringContainsString('You want to see "about" page.', $output);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
public function testControllersCanReturnResponseObject()
|
|
|
|
{
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argv'] = [
|
2021-06-04 22:51:52 +08:00
|
|
|
'index.php',
|
|
|
|
'pages/about',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
$_SERVER['REQUEST_URI'] = '/pages/about';
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = Services::routes();
|
2021-06-07 03:44:42 +02:00
|
|
|
$routes->add('pages/(:segment)', static function ($segment) {
|
2021-06-04 22:51:52 +08:00
|
|
|
$response = Services::response();
|
2021-06-08 11:17:07 +08:00
|
|
|
$string = "You want to see 'about' page.";
|
2021-06-08 01:26:32 +08:00
|
|
|
|
2021-06-04 22:51:52 +08:00
|
|
|
return $response->setBody($string);
|
|
|
|
});
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
$output = ob_get_clean();
|
|
|
|
|
|
|
|
$this->assertStringContainsString("You want to see 'about' page.", $output);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
public function testResponseConfigEmpty()
|
|
|
|
{
|
|
|
|
$_SERVER['argv'] = [
|
|
|
|
'index.php',
|
|
|
|
'/',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
|
|
|
|
$response = Services::response(null, false);
|
|
|
|
|
|
|
|
$this->assertInstanceOf('\CodeIgniter\HTTP\Response', $response);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
public function testRoutesIsEmpty()
|
|
|
|
{
|
|
|
|
$_SERVER['argv'] = [
|
|
|
|
'index.php',
|
|
|
|
'/',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$router = Services::router(null, Services::request(), false);
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
$output = ob_get_clean();
|
|
|
|
|
|
|
|
$this->assertStringContainsString('Welcome to CodeIgniter', $output);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testTransfersCorrectHTTPVersion()
|
|
|
|
{
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argv'] = [
|
2021-06-04 22:51:52 +08:00
|
|
|
'index.php',
|
|
|
|
'/',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/2.0';
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
2021-06-24 15:43:23 +07:00
|
|
|
ob_get_clean();
|
2021-06-04 22:51:52 +08:00
|
|
|
|
|
|
|
$response = $this->getPrivateProperty($this->codeigniter, 'response');
|
|
|
|
|
|
|
|
$this->assertEquals(2, $response->getProtocolVersion());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testIgnoringErrorSuppressedByAt()
|
|
|
|
{
|
|
|
|
$_SERVER['argv'] = [
|
|
|
|
'index.php',
|
|
|
|
'/',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
@unlink('inexistent-file');
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
$output = ob_get_clean();
|
|
|
|
|
|
|
|
$this->assertStringContainsString('Welcome to CodeIgniter', $output);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
public function testRunForceSecure()
|
|
|
|
{
|
|
|
|
$_SERVER['argv'] = [
|
|
|
|
'index.php',
|
|
|
|
'/',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
|
|
|
|
$config = new App();
|
|
|
|
$config->forceGlobalSecureRequests = true;
|
|
|
|
$codeigniter = new MockCodeIgniter($config);
|
|
|
|
|
|
|
|
$this->getPrivateMethodInvoker($codeigniter, 'getRequestObject')();
|
|
|
|
$this->getPrivateMethodInvoker($codeigniter, 'getResponseObject')();
|
|
|
|
|
|
|
|
$response = $this->getPrivateProperty($codeigniter, 'response');
|
|
|
|
$this->assertNull($response->header('Location'));
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$codeigniter->useSafeOutput(true)->run();
|
2021-06-24 15:43:23 +07:00
|
|
|
ob_get_clean();
|
2021-06-04 22:51:52 +08:00
|
|
|
|
|
|
|
$this->assertEquals('https://example.com/', $response->header('Location')->getValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRunRedirectionWithNamed()
|
|
|
|
{
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argv'] = [
|
2021-06-04 22:51:52 +08:00
|
|
|
'index.php',
|
|
|
|
'example',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
$_SERVER['REQUEST_URI'] = '/example';
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = Services::routes();
|
2021-06-07 03:44:42 +02:00
|
|
|
$routes->add('pages/named', static function () {
|
2021-06-04 22:51:52 +08:00
|
|
|
}, ['as' => 'name']);
|
|
|
|
$routes->addRedirect('example', 'name');
|
|
|
|
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
ob_get_clean();
|
|
|
|
$response = $this->getPrivateProperty($this->codeigniter, 'response');
|
|
|
|
$this->assertEquals('http://example.com/pages/named', $response->header('Location')->getValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRunRedirectionWithURI()
|
|
|
|
{
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argv'] = [
|
2021-06-04 22:51:52 +08:00
|
|
|
'index.php',
|
|
|
|
'example',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
$_SERVER['REQUEST_URI'] = '/example';
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = Services::routes();
|
2021-06-07 03:44:42 +02:00
|
|
|
$routes->add('pages/uri', static function () {
|
2021-06-04 22:51:52 +08:00
|
|
|
});
|
|
|
|
$routes->addRedirect('example', 'pages/uri');
|
|
|
|
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
ob_get_clean();
|
|
|
|
$response = $this->getPrivateProperty($this->codeigniter, 'response');
|
|
|
|
$this->assertEquals('http://example.com/pages/uri', $response->header('Location')->getValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see https://github.com/codeigniter4/CodeIgniter4/issues/3041
|
|
|
|
*/
|
|
|
|
public function testRunRedirectionWithURINotSet()
|
|
|
|
{
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argv'] = [
|
2021-06-04 22:51:52 +08:00
|
|
|
'index.php',
|
|
|
|
'example',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
$_SERVER['REQUEST_URI'] = '/example';
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = Services::routes();
|
|
|
|
$routes->addRedirect('example', 'pages/notset');
|
|
|
|
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
ob_get_clean();
|
|
|
|
$response = $this->getPrivateProperty($this->codeigniter, 'response');
|
|
|
|
$this->assertEquals('http://example.com/pages/notset', $response->header('Location')->getValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRunRedirectionWithHTTPCode303()
|
|
|
|
{
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argv'] = [
|
2021-06-04 22:51:52 +08:00
|
|
|
'index.php',
|
|
|
|
'example',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
$_SERVER['REQUEST_URI'] = '/example';
|
|
|
|
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
|
|
|
|
$_SERVER['REQUEST_METHOD'] = 'POST';
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = Services::routes();
|
|
|
|
$routes->addRedirect('example', 'pages/notset', 301);
|
|
|
|
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
ob_get_clean();
|
|
|
|
$response = $this->getPrivateProperty($this->codeigniter, 'response');
|
|
|
|
$this->assertEquals('303', $response->getStatusCode());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRunRedirectionWithHTTPCode301()
|
|
|
|
{
|
2021-06-08 11:17:07 +08:00
|
|
|
$_SERVER['argv'] = [
|
2021-06-04 22:51:52 +08:00
|
|
|
'index.php',
|
|
|
|
'example',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
$_SERVER['REQUEST_URI'] = '/example';
|
|
|
|
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
|
|
|
|
$_SERVER['REQUEST_METHOD'] = 'GET';
|
|
|
|
|
|
|
|
// Inject mock router.
|
|
|
|
$routes = Services::routes();
|
|
|
|
$routes->addRedirect('example', 'pages/notset', 301);
|
|
|
|
|
|
|
|
$router = Services::router($routes, Services::request());
|
|
|
|
Services::injectMock('router', $router);
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
ob_get_clean();
|
|
|
|
$response = $this->getPrivateProperty($this->codeigniter, 'response');
|
|
|
|
$this->assertEquals('301', $response->getStatusCode());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The method after all test, reset Servces:: config
|
|
|
|
* Can't use static::tearDownAfterClass. This will cause a buffer exception
|
|
|
|
* need improve
|
|
|
|
*/
|
|
|
|
public function testRunDefaultRoute()
|
|
|
|
{
|
|
|
|
$_SERVER['argv'] = [
|
|
|
|
'index.php',
|
|
|
|
'/',
|
|
|
|
];
|
|
|
|
$_SERVER['argc'] = 2;
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
$this->codeigniter->useSafeOutput(true)->run();
|
|
|
|
$output = ob_get_clean();
|
|
|
|
|
|
|
|
$this->assertStringContainsString('Welcome to CodeIgniter', $output);
|
|
|
|
}
|
2016-03-29 22:30:05 +09:00
|
|
|
}
|