mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
Merge pull request #1848 from jim-parry/testing28
Test: fix & test Test/ControllerTest, tested
This commit is contained in:
commit
8c0f620118
@ -143,7 +143,7 @@ class ControllerResponse {
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Boils down the possible responses into a bolean valid/not-valid
|
||||
* Boils down the possible responses into a boolean valid/not-valid
|
||||
* response type.
|
||||
*
|
||||
* @return boolean
|
||||
@ -180,6 +180,13 @@ class ControllerResponse {
|
||||
// Utility
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Forward any unrecognized method calls to our DOMParser instance.
|
||||
*
|
||||
* @param string $function Method name
|
||||
* @param mixed $params Any method parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($function, $params)
|
||||
{
|
||||
if (method_exists($this->dom, $function))
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php namespace CodeIgniter\Test;
|
||||
<?php
|
||||
namespace CodeIgniter\Test;
|
||||
|
||||
/**
|
||||
* CodeIgniter
|
||||
@ -41,6 +42,7 @@ use CodeIgniter\HTTP\UserAgent;
|
||||
use CodeIgniter\HTTP\Response;
|
||||
use CodeIgniter\HTTP\URI;
|
||||
use Config\App;
|
||||
use Config\Services;
|
||||
|
||||
/**
|
||||
* ControllerTester Trait
|
||||
@ -58,16 +60,13 @@ use Config\App;
|
||||
*/
|
||||
trait ControllerTester
|
||||
{
|
||||
|
||||
protected $appConfig;
|
||||
|
||||
protected $request;
|
||||
|
||||
protected $response;
|
||||
|
||||
protected $logger;
|
||||
protected $controller;
|
||||
|
||||
protected $uri = 'http://example.com';
|
||||
|
||||
protected $body;
|
||||
|
||||
/**
|
||||
@ -99,7 +98,13 @@ trait ControllerTester
|
||||
$this->response = new Response($this->appConfig);
|
||||
}
|
||||
|
||||
$this->controller = new $name($this->request, $this->response);
|
||||
if (empty($this->logger))
|
||||
{
|
||||
$this->logger = Services::logger();
|
||||
}
|
||||
|
||||
$this->controller = new $name();
|
||||
$this->controller->initController($this->request, $this->response, $this->logger);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -124,9 +129,10 @@ trait ControllerTester
|
||||
helper('url');
|
||||
|
||||
$result = (new ControllerResponse())
|
||||
->setRequest($this->request)
|
||||
->setResponse($this->response);
|
||||
->setRequest($this->request)
|
||||
->setResponse($this->response);
|
||||
|
||||
$response = null;
|
||||
try
|
||||
{
|
||||
ob_start();
|
||||
@ -136,19 +142,24 @@ trait ControllerTester
|
||||
catch (\Throwable $e)
|
||||
{
|
||||
$result->response()
|
||||
->setStatusCode($e->getCode());
|
||||
->setStatusCode($e->getCode());
|
||||
}
|
||||
finally
|
||||
{
|
||||
$output = ob_get_clean();
|
||||
|
||||
// If the controller returned a redirect response
|
||||
// then we need to use that...
|
||||
// If the controller returned a response, use it
|
||||
if (isset($response) && $response instanceof Response)
|
||||
{
|
||||
$result->setResponse($response);
|
||||
}
|
||||
|
||||
// check if controller returned a view rather than echoing it
|
||||
if (is_string($response))
|
||||
{
|
||||
$output = $response;
|
||||
}
|
||||
|
||||
$result->response()->setBody($output);
|
||||
$result->setBody($output);
|
||||
}
|
||||
@ -198,6 +209,18 @@ trait ControllerTester
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $logger
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function withLogger($logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
*
|
||||
|
@ -47,7 +47,10 @@ class DOMParser
|
||||
{
|
||||
if (! extension_loaded('DOM'))
|
||||
{
|
||||
// always there in travis-ci
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new \BadMethodCallException('DOM extension is required, but not currently loaded.');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
$this->dom = new \DOMDocument('1.0', 'utf-8');
|
||||
@ -80,7 +83,11 @@ class DOMParser
|
||||
|
||||
if (! $this->dom->loadHTML($content))
|
||||
{
|
||||
// unclear how we would get here, given that we are trapping libxml errors
|
||||
// @codeCoverageIgnoreStart
|
||||
libxml_clear_errors();
|
||||
throw new \BadMethodCallException('Invalid HTML');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
// ignore the whitespace.
|
||||
@ -248,7 +255,7 @@ class DOMParser
|
||||
{
|
||||
foreach ($selector['attr'] as $key => $value)
|
||||
{
|
||||
$path .= "[{$key}={$value}]";
|
||||
$path .= "[@{$key}=\"{$value}\"]";
|
||||
}
|
||||
}
|
||||
|
||||
|
46
tests/_support/Controllers/Popcorn.php
Normal file
46
tests/_support/Controllers/Popcorn.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace Tests\Support\Controllers;
|
||||
|
||||
use CodeIgniter\API\ResponseTrait;
|
||||
use CodeIgniter\Controller;
|
||||
use CodeIgniter\HTTP\Exceptions\HTTPException;
|
||||
|
||||
/**
|
||||
* This is a testing only controller, intended to blow up in multiple
|
||||
* ways to make sure we catch them.
|
||||
*/
|
||||
class Popcorn extends Controller
|
||||
{
|
||||
|
||||
use ResponseTrait;
|
||||
|
||||
public function index()
|
||||
{
|
||||
return 'Hi there';
|
||||
}
|
||||
|
||||
public function pop()
|
||||
{
|
||||
$this->respond('Oops', 567, 'Surprise');
|
||||
}
|
||||
|
||||
public function popper()
|
||||
{
|
||||
throw new \RuntimeException('Surprise', 500);
|
||||
}
|
||||
|
||||
public function weasel()
|
||||
{
|
||||
$this->respond(['Nothing to see here'], 200);
|
||||
}
|
||||
|
||||
public function oops()
|
||||
{
|
||||
$this->failUnauthorized();
|
||||
}
|
||||
|
||||
public function goaway()
|
||||
{
|
||||
return redirect()->to('/');
|
||||
}
|
||||
}
|
@ -39,6 +39,7 @@ class ContentSecurityPolicyTest extends \CIUnitTestCase
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
@ -52,6 +53,7 @@ class ContentSecurityPolicyTest extends \CIUnitTestCase
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
@ -66,6 +68,7 @@ class ContentSecurityPolicyTest extends \CIUnitTestCase
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
@ -86,6 +89,7 @@ class ContentSecurityPolicyTest extends \CIUnitTestCase
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
@ -306,6 +310,7 @@ class ContentSecurityPolicyTest extends \CIUnitTestCase
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
@ -457,4 +462,32 @@ class ContentSecurityPolicyTest extends \CIUnitTestCase
|
||||
$this->assertContains('nonce-', $result);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testHeaderWrongCaseNotFound()
|
||||
{
|
||||
$this->prepare();
|
||||
$result = $this->work();
|
||||
|
||||
$result = $this->getHeaderEmitted('content-security-policy');
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testHeaderIgnoreCase()
|
||||
{
|
||||
$this->prepare();
|
||||
$result = $this->work();
|
||||
|
||||
$result = $this->getHeaderEmitted('content-security-policy', true);
|
||||
$this->assertContains("base-uri 'self';", $result);
|
||||
}
|
||||
|
||||
}
|
||||
|
203
tests/system/Test/ControllerTesterTest.php
Normal file
203
tests/system/Test/ControllerTesterTest.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
namespace CodeIgniter\Test;
|
||||
|
||||
use CodeIgniter\Log\Logger;
|
||||
use Config\App;
|
||||
use Config\Services;
|
||||
use Tests\Support\Config\MockLogger as LoggerConfig;
|
||||
|
||||
class ControllerTesterTest extends \CIUnitTestCase
|
||||
{
|
||||
|
||||
use ControllerTester;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testBadController()
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\App\Controllers\NeverHeardOfIt::class)
|
||||
->execute('index');
|
||||
}
|
||||
|
||||
public function testBadControllerMethod()
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\App\Controllers\Home::class)
|
||||
->execute('nothere');
|
||||
}
|
||||
|
||||
public function testController()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\App\Controllers\Home::class)
|
||||
->execute('index');
|
||||
|
||||
$body = $result->getBody();
|
||||
$this->assertTrue($result->isOK());
|
||||
}
|
||||
|
||||
public function testControllerWithoutLogger()
|
||||
{
|
||||
$result = $this->withURI('http://example.com')
|
||||
->controller(\App\Controllers\Home::class)
|
||||
->execute('index');
|
||||
|
||||
$body = $result->getBody();
|
||||
$this->assertTrue($result->isOK());
|
||||
}
|
||||
|
||||
public function testPopcornIndex()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('index');
|
||||
|
||||
$body = $result->getBody();
|
||||
$this->assertTrue($result->isOK());
|
||||
}
|
||||
|
||||
public function testPopcornIndex2()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('index');
|
||||
|
||||
$body = $result->getBody();
|
||||
$this->assertEquals('Hi there', $body);
|
||||
}
|
||||
|
||||
public function testPopcornFailure()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('pop');
|
||||
|
||||
$body = $result->getBody();
|
||||
$this->assertEquals(567, $result->response()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testPopcornException()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('popper');
|
||||
|
||||
$body = $result->getBody();
|
||||
$this->assertEquals(500, $result->response()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testPopcornIndexWithSupport()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$config = new App();
|
||||
$body = '';
|
||||
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withConfig($config)
|
||||
->withRequest(Services::request($config))
|
||||
->withResponse(Services::response($config))
|
||||
->withLogger($logger)
|
||||
->withBody($body)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('index');
|
||||
|
||||
$body = $result->getBody();
|
||||
$this->assertEquals('Hi there', $body);
|
||||
}
|
||||
|
||||
public function testRequestPassthrough()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('popper');
|
||||
|
||||
$req = $result->request();
|
||||
$this->assertEquals('get', $req->getMethod());
|
||||
}
|
||||
|
||||
public function testFailureResponse()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('oops');
|
||||
|
||||
$this->assertFalse($result->isOK());
|
||||
$this->assertEquals(401, $result->response()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testEmptyResponse()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('weasel');
|
||||
|
||||
$body = $result->getBody(); // empty
|
||||
$this->assertFalse($result->isOK());
|
||||
}
|
||||
|
||||
public function testRedirect()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('goaway');
|
||||
|
||||
$this->assertTrue($result->isRedirect());
|
||||
}
|
||||
|
||||
public function testDOMParserForward()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('index');
|
||||
|
||||
$this->assertTrue($result->see('Hi'));
|
||||
}
|
||||
|
||||
public function testFailsForward()
|
||||
{
|
||||
$logger = new Logger(new LoggerConfig());
|
||||
$result = $this->withURI('http://example.com')
|
||||
->withLogger($logger)
|
||||
->controller(\Tests\Support\Controllers\Popcorn::class)
|
||||
->execute('index');
|
||||
|
||||
// won't fail, but doesn't do anything
|
||||
$this->assertNull($result->ohno('Hi'));
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
<?php namespace CodeIgniter\Test;
|
||||
<?php
|
||||
namespace CodeIgniter\Test;
|
||||
|
||||
class DOMParserTest extends CIUnitTestCase
|
||||
{
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
@ -18,7 +20,7 @@ class DOMParserTest extends CIUnitTestCase
|
||||
|
||||
$html = '<div><h1>Hello</h1></div>';
|
||||
$expected = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">' . "\n"
|
||||
. '<html><body><div><h1>Hello</h1></div></body></html>';
|
||||
. '<html><body><div><h1>Hello</h1></div></body></html>';
|
||||
|
||||
$this->assertEquals($expected . "\n", $dom->withString($html)->getBody());
|
||||
}
|
||||
@ -333,4 +335,41 @@ class DOMParserTest extends CIUnitTestCase
|
||||
|
||||
$this->assertTrue($dom->seeCheckboxIsChecked('.btn'));
|
||||
}
|
||||
|
||||
public function testWithFile()
|
||||
{
|
||||
$dom = new DOMParser();
|
||||
|
||||
$filename = APPPATH . 'index.html';
|
||||
|
||||
$dom->withFile($filename);
|
||||
$this->assertTrue($dom->see('Directory access is forbidden.'));
|
||||
}
|
||||
|
||||
public function testWithNotFile()
|
||||
{
|
||||
$dom = new DOMParser();
|
||||
|
||||
$filename = APPPATH . 'bogus.html';
|
||||
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$dom->withFile($filename);
|
||||
}
|
||||
|
||||
public function testSeeAttribute()
|
||||
{
|
||||
$dom = new DOMParser();
|
||||
|
||||
$path = '[ name = user ]';
|
||||
$selector = $dom->parseSelector($path);
|
||||
|
||||
$this->assertEquals(['name' => 'user'], $selector['attr']);
|
||||
|
||||
$html = '<html><body><div name="user">George</div></body></html>';
|
||||
$dom->withString($html);
|
||||
|
||||
$this->assertTrue($dom->see(null, '*[ name = user ]'));
|
||||
$this->assertFalse($dom->see(null, '*[ name = notthere ]'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -108,6 +108,20 @@ Allows you to provide a **Response** instance::
|
||||
If you do not provide one, a new Response instance with the default application values will be passed
|
||||
into your controller.
|
||||
|
||||
**withLogger($logger)**
|
||||
|
||||
Allows you to provide a **Logger** instance::
|
||||
|
||||
$logger = new CodeIgniter\Log\Handlers\FileHandler();
|
||||
|
||||
$results = $this->withResponse($response)
|
||||
-> withLogger($logger)
|
||||
->controller(\App\Controllers\ForumController::class)
|
||||
->execute('showCategories');
|
||||
|
||||
If you do not provide one, a new Logger instance with the default configuration values will be passed
|
||||
into your controller.
|
||||
|
||||
**withURI($uri)**
|
||||
|
||||
Allows you to provide a new URI that simulates the URL the client was visiting when this controller was run.
|
||||
|
Loading…
x
Reference in New Issue
Block a user