Merge pull request #1848 from jim-parry/testing28

Test: fix & test Test/ControllerTest, tested
This commit is contained in:
Lonnie Ezell 2019-03-21 23:06:21 -05:00 committed by GitHub
commit 8c0f620118
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 388 additions and 16 deletions

View File

@ -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))

View File

@ -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
*

View File

@ -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}\"]";
}
}

View 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('/');
}
}

View File

@ -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);
}
}

View 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'));
}
}

View File

@ -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 ]'));
}
}

View File

@ -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.