2021-06-07 00:15:28 +08:00
< ? php
2021-07-19 21:32:33 +08:00
/**
* This file is part of CodeIgniter 4 framework .
*
* ( c ) CodeIgniter Foundation < admin @ codeigniter . com >
*
* For the full copyright and license information , please view
* the LICENSE file that was distributed with this source code .
*/
2021-06-07 00:15:28 +08:00
namespace CodeIgniter ;
2016-03-29 22:30:05 +09:00
2021-07-03 00:56:44 +08:00
use CodeIgniter\Config\Services ;
2022-03-19 22:52:14 +07:00
use CodeIgniter\HTTP\Response ;
2020-04-23 01:27:54 +07:00
use CodeIgniter\Router\RouteCollection ;
2021-02-28 06:57:05 +07:00
use CodeIgniter\Test\CIUnitTestCase ;
2022-07-20 11:54:12 +09:00
use CodeIgniter\Test\Filters\CITestStreamFilter ;
2020-04-23 01:27:54 +07:00
use CodeIgniter\Test\Mock\MockCodeIgniter ;
use Config\App ;
2022-09-02 15:24:54 +03:00
use Config\Cache ;
2022-07-20 11:54:12 +09:00
use Config\Filters ;
2021-02-28 06:57:05 +07:00
use Config\Modules ;
2021-09-24 17:31:19 +09:00
use Tests\Support\Filters\Customfilter ;
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
2022-11-04 18:27:05 +08:00
*
* @ group Others
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
{
2022-04-29 01:32:05 +07:00
private CodeIgniter $codeigniter ;
2021-06-04 22:51:52 +08:00
protected $routes ;
protected function setUp () : void
{
parent :: setUp ();
2021-10-29 19:35:37 +08:00
$this -> resetServices ();
2021-06-04 22:51:52 +08:00
$_SERVER [ 'SERVER_PROTOCOL' ] = 'HTTP/1.1' ;
2021-06-25 23:35:25 +08:00
$this -> codeigniter = new MockCodeIgniter ( new App ());
2022-09-20 17:12:18 +09:00
$response = Services :: response ();
$response -> pretend ();
2021-06-04 22:51:52 +08:00
}
2021-06-24 23:37:45 +08:00
protected function tearDown () : void
2021-06-04 22:51:52 +08:00
{
parent :: tearDown ();
2021-06-25 23:35:25 +08:00
if ( count ( ob_list_handlers ()) > 1 ) {
2021-06-04 22:51:52 +08:00
ob_end_clean ();
}
2022-03-01 11:09:11 +09:00
$this -> resetServices ();
2021-06-04 22:51:52 +08:00
}
public function testRunEmptyDefaultRoute ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' ];
2021-06-04 22:51:52 +08:00
$_SERVER [ 'argc' ] = 1 ;
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'Welcome to CodeIgniter' , $output );
}
2022-10-22 19:28:24 +09:00
public function testRunEmptyDefaultRouteReturnResponse ()
{
$_SERVER [ 'argv' ] = [ 'index.php' ];
$_SERVER [ 'argc' ] = 1 ;
$response = $this -> codeigniter -> useSafeOutput ( true ) -> run ( null , true );
$this -> assertStringContainsString ( 'Welcome to CodeIgniter' , $response -> getBody ());
}
2021-06-04 22:51:52 +08:00
public function testRunClosureRoute ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ '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.' ;
});
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'You want to see "about" page.' , $output );
}
public function testRun404Override ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
2021-06-04 22:51:52 +08:00
$_SERVER [ 'argc' ] = 2 ;
// Inject mock router.
$routes = Services :: routes ();
$routes -> setAutoRoute ( false );
2022-02-17 09:17:54 +09:00
$routes -> set404Override ( 'Tests\Support\Controllers\Hello::index' );
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ( $routes );
2021-06-04 22:51:52 +08:00
$output = ob_get_clean ();
2022-02-17 09:17:54 +09:00
$this -> assertStringContainsString ( 'Hello' , $output );
2021-06-04 22:51:52 +08:00
}
2022-02-17 09:11:04 +09:00
public function testRun404OverrideControllerReturnsResponse ()
{
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
$_SERVER [ 'argc' ] = 2 ;
// Inject mock router.
$routes = Services :: routes ();
$routes -> setAutoRoute ( false );
$routes -> set404Override ( 'Tests\Support\Controllers\Popcorn::pop' );
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2022-02-17 09:11:04 +09:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ( $routes );
2022-02-17 09:11:04 +09:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'Oops' , $output );
}
2022-10-22 19:28:24 +09:00
public function testRun404OverrideReturnResponse ()
{
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
$_SERVER [ 'argc' ] = 2 ;
// Inject mock router.
$routes = Services :: routes ();
$routes -> setAutoRoute ( false );
$routes -> set404Override ( 'Tests\Support\Controllers\Popcorn::pop' );
$router = Services :: router ( $routes , Services :: incomingrequest ());
Services :: injectMock ( 'router' , $router );
$response = $this -> codeigniter -> useSafeOutput ( true ) -> run ( $routes , true );
$this -> assertStringContainsString ( 'Oops' , $response -> getBody ());
}
2021-06-04 22:51:52 +08:00
public function testRun404OverrideByClosure ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
2021-06-04 22:51:52 +08:00
$_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.' ;
});
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ( $routes );
2021-06-04 22:51:52 +08:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( '404 Override by Closure.' , $output );
}
public function testControllersCanReturnString ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , 'pages/about' ];
$_SERVER [ 'argc' ] = 2 ;
2021-06-04 22:51:52 +08:00
$_SERVER [ 'REQUEST_URI' ] = '/pages/about' ;
// Inject mock router.
$routes = Services :: routes ();
2021-12-14 11:19:51 +07:00
$routes -> add ( 'pages/(:segment)' , static fn ( $segment ) => 'You want to see "' . esc ( $segment ) . '" page.' );
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'You want to see "about" page.' , $output );
}
public function testControllersCanReturnResponseObject ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , 'pages/about' ];
$_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
$response = Services :: response ();
2022-09-02 09:32:01 +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 );
});
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( " You want to see 'about' page. " , $output );
}
2022-08-13 10:04:35 +09:00
/**
* @ see https :// github . com / codeigniter4 / CodeIgniter4 / issues / 6358
*/
public function testControllersCanReturnDownloadResponseObject ()
{
$_SERVER [ 'argv' ] = [ 'index.php' , 'pages/about' ];
$_SERVER [ 'argc' ] = 2 ;
$_SERVER [ 'REQUEST_URI' ] = '/pages/about' ;
// Inject mock router.
$routes = Services :: routes ();
$routes -> add ( 'pages/(:segment)' , static function ( $segment ) {
$response = Services :: response ();
return $response -> download ( 'some.txt' , 'some text' , true );
});
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2022-08-13 10:04:35 +09:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2022-08-13 10:04:35 +09:00
$output = ob_get_clean ();
$this -> assertSame ( 'some text' , $output );
}
2021-09-24 17:31:19 +09:00
public function testControllersRunFilterByClassName ()
{
$_SERVER [ 'argv' ] = [ 'index.php' , 'pages/about' ];
$_SERVER [ 'argc' ] = 2 ;
$_SERVER [ 'REQUEST_URI' ] = '/pages/about' ;
// Inject mock router.
$routes = Services :: routes ();
2022-10-22 18:11:04 +09:00
$routes -> add ( 'pages/about' , static fn () => Services :: incomingrequest () -> getBody (), [ 'filter' => Customfilter :: class ]);
2021-09-24 17:31:19 +09:00
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-09-24 17:31:19 +09:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-09-24 17:31:19 +09:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'http://hellowworld.com' , $output );
2022-08-13 09:12:32 +09:00
$this -> resetServices ();
2021-09-24 17:31:19 +09:00
}
2022-10-10 07:02:32 +09:00
public function testDisableControllerFilters ()
{
$_SERVER [ 'argv' ] = [ 'index.php' , 'pages/about' ];
$_SERVER [ 'argc' ] = 2 ;
$_SERVER [ 'REQUEST_URI' ] = '/pages/about' ;
// Inject mock router.
$routes = Services :: routes ();
$routes -> add (
'pages/about' ,
static fn () => Services :: incomingrequest () -> getBody (),
[ 'filter' => Customfilter :: class ]
);
$router = Services :: router ( $routes , Services :: incomingrequest ());
Services :: injectMock ( 'router' , $router );
ob_start ();
$this -> codeigniter -> disableFilters ();
$this -> codeigniter -> run ();
$output = ob_get_clean ();
$this -> assertStringContainsString ( '' , $output );
$this -> resetServices ();
}
2021-06-04 22:51:52 +08:00
public function testResponseConfigEmpty ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
2021-06-04 22:51:52 +08:00
$_SERVER [ 'argc' ] = 2 ;
$response = Services :: response ( null , false );
2022-03-19 22:52:14 +07:00
$this -> assertInstanceOf ( Response :: class , $response );
2021-06-04 22:51:52 +08:00
}
public function testRoutesIsEmpty ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
2021-06-04 22:51:52 +08:00
$_SERVER [ 'argc' ] = 2 ;
// Inject mock router.
2022-10-22 18:11:04 +09:00
$router = Services :: router ( null , Services :: incomingrequest (), false );
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'Welcome to CodeIgniter' , $output );
}
public function testTransfersCorrectHTTPVersion ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
$_SERVER [ 'argc' ] = 2 ;
2021-06-04 22:51:52 +08:00
$_SERVER [ 'SERVER_PROTOCOL' ] = 'HTTP/2.0' ;
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> 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' );
2021-06-25 23:35:25 +08:00
$this -> assertSame ( '2.0' , $response -> getProtocolVersion ());
2021-06-04 22:51:52 +08:00
}
2022-09-26 22:16:41 -05:00
public function testSupportsHttp3 ()
{
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
$_SERVER [ 'argc' ] = 2 ;
$_SERVER [ 'SERVER_PROTOCOL' ] = 'HTTP/3.0' ;
ob_start ();
$this -> codeigniter -> run ();
ob_get_clean ();
$response = $this -> getPrivateProperty ( $this -> codeigniter , 'response' );
$this -> assertSame ( '3.0' , $response -> getProtocolVersion ());
}
2021-06-04 22:51:52 +08:00
public function testIgnoringErrorSuppressedByAt ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
2021-06-04 22:51:52 +08:00
$_SERVER [ 'argc' ] = 2 ;
ob_start ();
@ unlink ( 'inexistent-file' );
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'Welcome to CodeIgniter' , $output );
}
public function testRunForceSecure ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
2021-06-04 22:51:52 +08:00
$_SERVER [ 'argc' ] = 2 ;
2021-06-25 23:35:25 +08:00
$config = new App ();
2021-06-04 22:51:52 +08:00
$config -> forceGlobalSecureRequests = true ;
2021-06-25 23:35:25 +08:00
$codeigniter = new MockCodeIgniter ( $config );
2022-02-03 17:02:19 +09:00
$codeigniter -> setContext ( 'web' );
2021-06-04 22:51:52 +08:00
$this -> getPrivateMethodInvoker ( $codeigniter , 'getRequestObject' )();
$this -> getPrivateMethodInvoker ( $codeigniter , 'getResponseObject' )();
$response = $this -> getPrivateProperty ( $codeigniter , 'response' );
$this -> assertNull ( $response -> header ( 'Location' ));
ob_start ();
2022-09-20 17:12:18 +09:00
$codeigniter -> run ();
2021-06-24 15:43:23 +07:00
ob_get_clean ();
2021-06-04 22:51:52 +08:00
2021-06-25 23:35:25 +08:00
$this -> assertSame ( 'https://example.com/' , $response -> header ( 'Location' ) -> getValue ());
2021-06-04 22:51:52 +08:00
}
public function testRunRedirectionWithNamed ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , 'example' ];
$_SERVER [ 'argc' ] = 2 ;
2021-06-04 22:51:52 +08:00
$_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' );
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
ob_get_clean ();
$response = $this -> getPrivateProperty ( $this -> codeigniter , 'response' );
2021-06-25 23:35:25 +08:00
$this -> assertSame ( 'http://example.com/pages/named' , $response -> header ( 'Location' ) -> getValue ());
2021-06-04 22:51:52 +08:00
}
public function testRunRedirectionWithURI ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , 'example' ];
$_SERVER [ 'argc' ] = 2 ;
2021-06-04 22:51:52 +08:00
$_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' );
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
ob_get_clean ();
$response = $this -> getPrivateProperty ( $this -> codeigniter , 'response' );
2021-06-25 23:35:25 +08:00
$this -> assertSame ( 'http://example.com/pages/uri' , $response -> header ( 'Location' ) -> getValue ());
2021-06-04 22:51:52 +08:00
}
/**
* @ see https :// github . com / codeigniter4 / CodeIgniter4 / issues / 3041
*/
2023-04-20 21:26:20 +09:00
public function testRunRedirectionWithGET ()
2021-06-04 22:51:52 +08:00
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , 'example' ];
$_SERVER [ 'argc' ] = 2 ;
2023-04-20 21:26:20 +09:00
$_SERVER [ 'REQUEST_URI' ] = '/example' ;
$_SERVER [ 'SERVER_PROTOCOL' ] = 'HTTP/1.1' ;
$_SERVER [ 'REQUEST_METHOD' ] = 'GET' ;
2021-06-04 22:51:52 +08:00
// Inject mock router.
$routes = Services :: routes ();
2023-04-20 21:59:55 +09:00
// addRedirect() sets status code 302 by default.
2021-06-04 22:51:52 +08:00
$routes -> addRedirect ( 'example' , 'pages/notset' );
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
ob_get_clean ();
2023-04-20 21:26:20 +09:00
2021-06-04 22:51:52 +08:00
$response = $this -> getPrivateProperty ( $this -> codeigniter , 'response' );
2021-06-25 23:35:25 +08:00
$this -> assertSame ( 'http://example.com/pages/notset' , $response -> header ( 'Location' ) -> getValue ());
2023-04-20 21:59:55 +09:00
$this -> assertSame ( 302 , $response -> getStatusCode ());
2023-04-20 21:26:20 +09:00
}
public function testRunRedirectionWithGETAndHTTPCode301 ()
{
$_SERVER [ 'argv' ] = [ '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 :: incomingrequest ());
Services :: injectMock ( 'router' , $router );
ob_start ();
$this -> codeigniter -> run ();
ob_get_clean ();
$response = $this -> getPrivateProperty ( $this -> codeigniter , 'response' );
$this -> assertSame ( 301 , $response -> getStatusCode ());
2021-06-04 22:51:52 +08:00
}
2023-04-20 21:26:20 +09:00
public function testRunRedirectionWithPOSTAndHTTPCode301 ()
2021-06-04 22:51:52 +08:00
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , 'example' ];
$_SERVER [ 'argc' ] = 2 ;
2021-06-04 22:51:52 +08:00
$_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 );
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
ob_get_clean ();
2021-06-25 23:35:25 +08:00
2021-06-04 22:51:52 +08:00
$response = $this -> getPrivateProperty ( $this -> codeigniter , 'response' );
2023-04-20 21:59:55 +09:00
$this -> assertSame ( 301 , $response -> getStatusCode ());
2021-06-04 22:51:52 +08:00
}
2021-09-15 01:47:19 +00:00
public function testStoresPreviousURL ()
{
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
$_SERVER [ 'argc' ] = 2 ;
// Inject mock router.
2022-10-22 18:11:04 +09:00
$router = Services :: router ( null , Services :: incomingrequest (), false );
2021-09-15 01:47:19 +00:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-09-15 01:47:19 +00:00
ob_get_clean ();
$this -> assertArrayHasKey ( '_ci_previous_url' , $_SESSION );
$this -> assertSame ( 'http://example.com/index.php' , $_SESSION [ '_ci_previous_url' ]);
}
public function testNotStoresPreviousURL ()
2021-06-04 22:51:52 +08:00
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , 'example' ];
$_SERVER [ 'argc' ] = 2 ;
2021-06-04 22:51:52 +08:00
$_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 );
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2021-06-04 22:51:52 +08:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
ob_get_clean ();
2021-09-15 01:47:19 +00:00
$this -> assertArrayNotHasKey ( '_ci_previous_url' , $_SESSION );
2021-06-04 22:51:52 +08:00
}
2022-05-30 11:08:37 +09:00
public function testNotStoresPreviousURLByCheckingContentType ()
{
$_SERVER [ 'argv' ] = [ 'index.php' , 'image' ];
$_SERVER [ 'argc' ] = 2 ;
$_SERVER [ 'REQUEST_URI' ] = '/image' ;
// Inject mock router.
$routes = Services :: routes ();
$routes -> add ( 'image' , static function () {
$response = Services :: response ();
return $response -> setContentType ( 'image/jpeg' , '' );
});
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2022-05-30 11:08:37 +09:00
Services :: injectMock ( 'router' , $router );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2022-05-30 11:08:37 +09:00
ob_get_clean ();
$this -> assertArrayNotHasKey ( '_ci_previous_url' , $_SESSION );
}
2021-06-04 22:51:52 +08:00
/**
* The method after all test , reset Servces :: config
* Can ' t use static :: tearDownAfterClass . This will cause a buffer exception
* need improve
*/
public function testRunDefaultRoute ()
{
2021-06-25 23:35:25 +08:00
$_SERVER [ 'argv' ] = [ 'index.php' , '/' ];
2021-06-04 22:51:52 +08:00
$_SERVER [ 'argc' ] = 2 ;
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2021-06-04 22:51:52 +08:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'Welcome to CodeIgniter' , $output );
}
2022-02-02 16:18:14 +09:00
public function testRunCLIRoute ()
{
$_SERVER [ 'argv' ] = [ 'index.php' , 'cli' ];
$_SERVER [ 'argc' ] = 2 ;
$_SERVER [ 'REQUEST_URI' ] = '/cli' ;
$_SERVER [ 'SERVER_PROTOCOL' ] = 'HTTP/1.1' ;
$_SERVER [ 'REQUEST_METHOD' ] = 'CLI' ;
$routes = Services :: routes ();
$routes -> cli ( 'cli' , '\Tests\Support\Controllers\Popcorn::index' );
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2022-02-02 16:18:14 +09:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'Method Not Allowed' , $output );
}
2022-02-09 11:40:48 +09:00
public function testSpoofRequestMethodCanUsePUT ()
{
$_SERVER [ 'argv' ] = [ 'index.php' ];
$_SERVER [ 'argc' ] = 1 ;
$_SERVER [ 'REQUEST_URI' ] = '/' ;
$_SERVER [ 'SERVER_PROTOCOL' ] = 'HTTP/1.1' ;
$_SERVER [ 'REQUEST_METHOD' ] = 'POST' ;
$_POST [ '_method' ] = 'PUT' ;
2022-03-01 11:09:11 +09:00
$routes = \Config\Services :: routes ();
$routes -> setDefaultNamespace ( 'App\Controllers' );
$routes -> resetRoutes ();
$routes -> post ( '/' , 'Home::index' );
$routes -> put ( '/' , 'Home::index' );
2022-02-09 11:40:48 +09:00
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2022-02-09 11:40:48 +09:00
ob_get_clean ();
2022-10-22 18:11:04 +09:00
$this -> assertSame ( 'put' , Services :: incomingrequest () -> getMethod ());
2022-02-09 11:40:48 +09:00
}
public function testSpoofRequestMethodCannotUseGET ()
{
$_SERVER [ 'argv' ] = [ 'index.php' ];
$_SERVER [ 'argc' ] = 1 ;
$_SERVER [ 'REQUEST_URI' ] = '/' ;
$_SERVER [ 'SERVER_PROTOCOL' ] = 'HTTP/1.1' ;
$_SERVER [ 'REQUEST_METHOD' ] = 'POST' ;
$_POST [ '_method' ] = 'GET' ;
2022-03-01 11:09:11 +09:00
$routes = \Config\Services :: routes ();
$routes -> setDefaultNamespace ( 'App\Controllers' );
$routes -> resetRoutes ();
$routes -> post ( '/' , 'Home::index' );
$routes -> get ( '/' , 'Home::index' );
2022-02-09 11:40:48 +09:00
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2022-02-09 11:40:48 +09:00
ob_get_clean ();
2022-10-22 18:11:04 +09:00
$this -> assertSame ( 'post' , Services :: incomingrequest () -> getMethod ());
2022-02-09 11:40:48 +09:00
}
2022-07-20 11:54:12 +09:00
/**
* @ see https :// github . com / codeigniter4 / CodeIgniter4 / issues / 6281
*/
public function testPageCacheSendSecureHeaders ()
{
// Suppress command() output
2022-08-29 16:33:35 +08:00
CITestStreamFilter :: registration ();
CITestStreamFilter :: addErrorFilter ();
CITestStreamFilter :: addOutputFilter ();
2022-07-20 11:54:12 +09:00
// Clear Page cache
command ( 'cache:clear' );
$_SERVER [ 'REQUEST_URI' ] = '/test' ;
$routes = Services :: routes ();
$routes -> add ( 'test' , static function () {
CodeIgniter :: cache ( 3600 );
$response = Services :: response ();
2022-09-02 09:32:01 +08:00
$string = 'This is a test page. Elapsed time: {elapsed_time}' ;
2022-07-20 11:54:12 +09:00
return $response -> setBody ( $string );
});
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ());
2022-07-20 11:54:12 +09:00
Services :: injectMock ( 'router' , $router );
/** @var Filters $filterConfig */
$filterConfig = config ( 'Filters' );
$filterConfig -> globals [ 'after' ] = [ 'secureheaders' ];
Services :: filters ( $filterConfig );
// The first response to be cached.
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2022-07-20 11:54:12 +09:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'This is a test page' , $output );
$response = Services :: response ();
$headers = $response -> headers ();
$this -> assertArrayHasKey ( 'X-Frame-Options' , $headers );
// The second response from the Page cache.
ob_start ();
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2022-07-20 11:54:12 +09:00
$output = ob_get_clean ();
$this -> assertStringContainsString ( 'This is a test page' , $output );
$response = Services :: response ();
$headers = $response -> headers ();
$this -> assertArrayHasKey ( 'X-Frame-Options' , $headers );
// Clear Page cache
command ( 'cache:clear' );
2022-08-29 16:33:35 +08:00
// Remove stream filters
CITestStreamFilter :: removeErrorFilter ();
CITestStreamFilter :: removeOutputFilter ();
2022-07-20 11:54:12 +09:00
}
2022-09-02 15:24:54 +03:00
/**
* @ param array | bool $cacheQueryStringValue
2022-09-04 19:44:31 +08:00
*
2022-09-02 15:24:54 +03:00
* @ dataProvider cacheQueryStringProvider
*
* @ see https :// github . com / codeigniter4 / CodeIgniter4 / pull / 6410
*/
public function testPageCacheWithCacheQueryString ( $cacheQueryStringValue , int $expectedPagesInCache , array $testingUrls )
{
// Suppress command() output
2023-02-21 16:40:08 +09:00
CITestStreamFilter :: registration ();
CITestStreamFilter :: addOutputFilter ();
CITestStreamFilter :: addErrorFilter ();
2022-09-02 15:24:54 +03:00
// Create cache config with cacheQueryString value from the dataProvider
$cacheConfig = new Cache ();
$cacheConfig -> cacheQueryString = $cacheQueryStringValue ;
// Clear cache before starting the test
command ( 'cache:clear' );
// Calculate amount of items in the cache before the test
$cache = \Config\Services :: cache ();
$cacheStartCounter = count ( $cache -> getCacheInfo ());
// Generate request to each URL from the testing array
foreach ( $testingUrls as $testingUrl ) {
$_SERVER [ 'REQUEST_URI' ] = '/' . $testingUrl ;
$routes = Services :: routes ( true );
$routes -> add ( $testingUrl , static function () {
2022-10-22 18:12:01 +09:00
CodeIgniter :: cache ( 0 ); // Don't cache the page in the run() function because CodeIgniter class will create default $cacheConfig and overwrite settings from the dataProvider
2022-09-02 15:24:54 +03:00
$response = Services :: response ();
2022-09-04 19:44:31 +08:00
$string = 'This is a test page, to check cache configuration' ;
2022-09-02 15:24:54 +03:00
return $response -> setBody ( $string );
});
// Inject router
2022-10-22 18:11:04 +09:00
$router = Services :: router ( $routes , Services :: incomingrequest ( null , false ));
2022-09-02 15:24:54 +03:00
Services :: injectMock ( 'router' , $router );
// Cache the page output using default caching function and $cacheConfig with value from the data provider
2022-09-20 17:12:18 +09:00
$this -> codeigniter -> run ();
2022-09-02 15:24:54 +03:00
$this -> codeigniter -> cachePage ( $cacheConfig ); // Cache the page using our own $cacheConfig confugration
}
// Calculate how much cached items exist in the cache after the test requests
$cacheEndCounter = count ( $cache -> getCacheInfo ());
$newPagesCached = $cacheEndCounter - $cacheStartCounter ;
// Clear cache after the test
command ( 'cache:clear' );
// Check that amount of new items created in the cache matching expected value from the data provider
$this -> assertSame ( $expectedPagesInCache , $newPagesCached );
// Remove stream filters
2023-02-21 16:40:08 +09:00
CITestStreamFilter :: removeOutputFilter ();
CITestStreamFilter :: removeErrorFilter ();
2022-09-02 15:24:54 +03:00
}
2023-07-17 16:30:13 +08:00
public function cacheQueryStringProvider () : iterable
2022-09-02 15:24:54 +03:00
{
$testingUrls = [
'test' , // URL #1
'test?important_parameter=1' , // URL #2
'test?important_parameter=2' , // URL #3
'test?important_parameter=1¬_important_parameter=2' , // URL #4
'test?important_parameter=1¬_important_parameter=2&another_not_important_parameter=3' , // URL #5
];
return [
'$cacheQueryString=false' => [ false , 1 , $testingUrls ], // We expect only 1 page in the cache, because when cacheQueryString is set to false, all GET parameter should be ignored, and page URI will be absolutely same "/test" string for all 5 requests
'$cacheQueryString=true' => [ true , 5 , $testingUrls ], // We expect all 5 pages in the cache, because when cacheQueryString is set to true, all GET parameter should be processed as unique requests
'$cacheQueryString=array' => [[ 'important_parameter' ], 3 , $testingUrls ], // We expect only 3 pages in the cache, because when cacheQueryString is set to array with important parameters, we should ignore all parameters thats not in the array. Only URL #1, URL #2 and URL #3 should be cached. URL #4 and URL #5 is duplication of URL #2 (with value ?important_parameter=1), so they should not be processed as new unique requests and application should return already cached page for URL #2
];
}
2016-03-29 22:30:05 +09:00
}