diff --git a/system/HTTP/CLIRequest.php b/system/HTTP/CLIRequest.php index 34cc40fed060..18844a3c68b0 100644 --- a/system/HTTP/CLIRequest.php +++ b/system/HTTP/CLIRequest.php @@ -124,6 +124,18 @@ public function getOptions(): array //-------------------------------------------------------------------- + /** + * Returns the path segments. + * + * @return array + */ + public function getSegments(): array + { + return $this->segments; + } + + //-------------------------------------------------------------------- + /** * Returns the value for a single CLI option that was passed in. * @@ -178,7 +190,7 @@ public function getOptionString(): string $out .= "-{$name} $value "; } - return $out; + return trim($out); } //-------------------------------------------------------------------- diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php index 3eb725c69dfe..ce7baaa33954 100644 --- a/system/HTTP/CURLRequest.php +++ b/system/HTTP/CURLRequest.php @@ -1,4 +1,6 @@ - 0.0, - 'connect_timeout' => 150, - 'debug' => false, - 'verify' => true + 'timeout' => 0.0, + 'connect_timeout' => 150, + 'debug' => false, + 'verify' => true ]; /** @@ -84,9 +86,9 @@ class CURLRequest extends Request * @var array */ protected $redirectDefaults = [ - 'max' => 5, - 'strict' => true, - 'protocols' => ['http', 'https'], + 'max' => 5, + 'strict' => true, + 'protocols' => ['http', 'https'], ]; /** @@ -114,7 +116,10 @@ public function __construct(App $config, URI $uri, ResponseInterface $response = { if ( ! function_exists('curl_version')) { + // we won't see this during travis-CI + // @codeCoverageIgnoreStart throw HTTPException::forMissingCurl(); + // @codeCoverageIgnoreEnd } parent::__construct($config); @@ -571,7 +576,7 @@ protected function setCURLOptions(array $curl_options = [], array $config = []) $cert = $cert[0]; } - if (! file_exists($cert)) + if ( ! file_exists($cert)) { throw HTTPException::forSSLCertNotFound($cert); } @@ -586,7 +591,7 @@ protected function setCURLOptions(array $curl_options = [], array $config = []) { $file = realpath($config['ssl_key']); - if (! $file) + if ( ! $file) { throw HTTPException::forInvalidSSLKey($config['ssl_key']); } @@ -723,6 +728,8 @@ protected function setCURLOptions(array $curl_options = [], array $config = []) * Does the actual work of initializing cURL, setting the options, * and grabbing the output. * + * @codeCoverageIgnore + * * @param array $curl_options * * @return string diff --git a/system/HTTP/Exceptions/HTTPException.php b/system/HTTP/Exceptions/HTTPException.php index 9b9cf56730aa..39c4ae81492d 100644 --- a/system/HTTP/Exceptions/HTTPException.php +++ b/system/HTTP/Exceptions/HTTPException.php @@ -11,6 +11,9 @@ class HTTPException extends FrameworkException implements ExceptionInterface * For CurlRequest * * @return \CodeIgniter\HTTP\Exceptions\HTTPException + * + * Not testable with travis-ci + * @codeCoverageIgnore */ public static function forMissingCurl() { @@ -48,6 +51,9 @@ public static function forInvalidSSLKey(string $key) * @param string $error * * @return \CodeIgniter\HTTP\Exceptions\HTTPException + * + * Not testable with travis-ci; we over-ride the method which triggers it + * @codeCoverageIgnore */ public static function forCurlError(string $errorNum, string $error) { diff --git a/tests/_support/HTTP/Files/CookiesHolder.txt b/tests/_support/HTTP/Files/CookiesHolder.txt new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/tests/_support/HTTP/Files/CookiesHolder.txt @@ -0,0 +1 @@ + diff --git a/tests/_support/HTTP/MockCURLRequest.php b/tests/_support/HTTP/MockCURLRequest.php index 0f650847cf37..2cd73b54de37 100644 --- a/tests/_support/HTTP/MockCURLRequest.php +++ b/tests/_support/HTTP/MockCURLRequest.php @@ -1,4 +1,6 @@ -baseURI; + } + + // for testing purposes only + public function getDelay() + { + return $this->delay; + } } diff --git a/tests/system/HTTP/CLIRequestTest.php b/tests/system/HTTP/CLIRequestTest.php new file mode 100644 index 000000000000..801b781ad99d --- /dev/null +++ b/tests/system/HTTP/CLIRequestTest.php @@ -0,0 +1,520 @@ +request = new CLIRequest(new App()); + $_POST = []; + $_GET = []; + } + + //-------------------------------------------------------------------- + + public function testParsingSegments() { + $_SERVER['argv'] = ['index.php','users','21','profile','-foo','bar']; + $_SERVER['argc'] = 6; + + // reinstantiate it to force parsing + $this->request = new CLIRequest(new App()); + + $segments = ['users','21','profile']; + $this->assertEquals($segments,$this->request->getSegments()); + } + + public function testParsingOptions() { + $_SERVER['argv'] = ['index.php','users','21','profile','-foo','bar']; + $_SERVER['argc'] = 6; + + // reinstantiate it to force parsing + $this->request = new CLIRequest(new App()); + + $options = ['foo'=>'bar']; + $this->assertEquals($options,$this->request->getOptions()); + } + + public function testParsingOptionDetails() { + $_SERVER['argv'] = ['index.php','users','21','profile','-foo','bar']; + $_SERVER['argc'] = 6; + + // reinstantiate it to force parsing + $this->request = new CLIRequest(new App()); + + $this->assertEquals('bar',$this->request->getOption('foo')); + $this->assertNull($this->request->getOption('notthere')); + } + + public function testParsingOptionString() { + $_SERVER['argv'] = ['index.php','users','21','profile','-foo','bar', '-baz', 'queue some stuff']; + $_SERVER['argc'] = 8; + + // reinstantiate it to force parsing + $this->request = new CLIRequest(new App()); + + $expected = '-foo bar -baz "queue some stuff"'; + $this->assertEquals($expected,$this->request->getOptionString()); + } + + public function testParsingNoOptions() { + $_SERVER['argv'] = ['index.php','users','21','profile']; + $_SERVER['argc'] = 4; + + // reinstantiate it to force parsing + $this->request = new CLIRequest(new App()); + + $expected = ''; + $this->assertEquals($expected,$this->request->getOptionString()); + } + + public function testParsingPath() { + $_SERVER['argv'] = ['index.php','users','21','profile','-foo','bar']; + $_SERVER['argc'] = 6; + + // reinstantiate it to force parsing + $this->request = new CLIRequest(new App()); + + $expected = "users/21/profile"; + $this->assertEquals($expected,$this->request->getPath()); + } + + public function testParsingMalformed() { + $_SERVER['argv'] = ['index.php','users','21','pro-file','-foo','bar', '-baz', 'queue some stuff']; + $_SERVER['argc'] = 8; + + // reinstantiate it to force parsing + $this->request = new CLIRequest(new App()); + + $expectedOptions = '-foo bar -baz "queue some stuff"'; + $expectedPath = "users/21"; + $this->assertEquals($expectedOptions,$this->request->getOptionString()); + $this->assertEquals($expectedPath,$this->request->getPath()); + } + + public function testParsingMalformed2() { + $_SERVER['argv'] = ['index.php','users','21','profile','-foo','oops-bar', '-baz', 'queue some stuff']; + $_SERVER['argc'] = 8; + + // reinstantiate it to force parsing + $this->request = new CLIRequest(new App()); + + $expectedOptions = '-foo oops-bar -baz "queue some stuff"'; + $expectedPath = "users/21/profile"; + $this->assertEquals($expectedOptions,$this->request->getOptionString()); + $this->assertEquals($expectedPath,$this->request->getPath()); + } + + public function testParsingMalformed3() { + $_SERVER['argv'] = ['index.php','users','21','profile','-foo','oops', 'bar', '-baz', 'queue some stuff']; + $_SERVER['argc'] = 9; + + // reinstantiate it to force parsing + $this->request = new CLIRequest(new App()); + + $expectedOptions = '-foo oops -baz "queue some stuff"'; + $expectedPath = "users/21/profile"; + $this->assertEquals($expectedOptions,$this->request->getOptionString()); + $this->assertEquals($expectedPath,$this->request->getPath()); + } + + //-------------------------------------------------------------------- + + public function testFetchGlobalsSingleValue() + { + $_POST['foo'] = 'bar'; + $_GET['bar'] = 'baz'; + + $this->assertEquals('bar', $this->request->fetchGlobal('post', 'foo')); + $this->assertEquals('baz', $this->request->fetchGlobal('get', 'bar')); + } + + public function testFetchGlobalsReturnsNullWhenNotFound() + { + $this->assertNull($this->request->fetchGlobal('post', 'foo')); + } + + public function testFetchGlobalsFiltersValues() + { + $this->request->setGlobal('post', [ + 'foo' => 'bar