reworked notifications to the test system

No globals required anymore, somewhat more general approach to sending
data to the test system. Clean access through keys.
This commit is contained in:
Andreas Gohr 2017-09-02 15:44:48 +02:00
parent 444d58a817
commit 27c0c399d7
4 changed files with 82 additions and 82 deletions

View File

@ -4,9 +4,6 @@
* runtime inspection.
*/
$currentTestRequest = null;
/**
* Helper class to execute a fake request
*/
@ -19,7 +16,7 @@ class TestRequest {
protected $session = array();
protected $get = array();
protected $post = array();
protected $notifications = array();
protected $data = array();
/** @var string stores the output buffer, even when it's flushed */
protected $output_buffer = '';
@ -124,9 +121,6 @@ class TestRequest {
*/
public function execute($uri = '/doku.php') {
global $INPUT;
global $currentTestRequest;
$currentTestRequest = $this;
// save old environment
$server = $_SERVER;
@ -167,11 +161,10 @@ class TestRequest {
// create the response object
$response = new TestResponse(
$this->output_buffer,
(function_exists('xdebug_get_headers') ? xdebug_get_headers() : headers_list()) // cli sapi doesn't do headers, prefer xdebug_get_headers() which works under cli
// cli sapi doesn't do headers, prefer xdebug_get_headers() which works under cli
(function_exists('xdebug_get_headers') ? xdebug_get_headers() : headers_list()),
$this->data
);
if($this->notifications != null) {
$response->setNotifications($this->notifications);
}
// reset environment
$_SERVER = $server;
@ -181,8 +174,6 @@ class TestRequest {
$_REQUEST = $request;
$INPUT = $input;
$currentTestRequest = null;
return $response;
}
@ -262,9 +253,28 @@ class TestRequest {
}
/**
* Add a notification to later store it in the test respone.
* Access the TestRequest from the executed code
*
* This allows certain functions to access the TestRequest that is accessing them
* to add additional info.
*
* @return null|TestRequest the currently executed request if any
*/
public function addNotification(array $new) {
$this->notifications[] = $new;
public static function getRunning() {
return self::$running;
}
/**
* Store data to be read in the response later
*
* When called multiple times with the same key, the data is appended to this
* key's array
*
* @param string $key the identifier for this information
* @param mixed $value arbitrary data to store
*/
public function addData($key, $value) {
if(!isset($this->data[$key])) $this->data[$key] = array();
$this->data[$key][] = $value;
}
}

View File

@ -1,38 +1,37 @@
<?php
/**
* holds a copy of all produced outputs of a TestRequest
*/
class TestResponse {
/**
* @var string
*/
private $content;
/** @var string */
protected $content;
/** @var array */
protected $headers;
/** @var phpQueryObject */
protected $pq = null;
/** @var array */
protected $data = array();
/**
* @var array
* Constructor
*
* @param $content string the response body
* @param $headers array the headers sent in the response
* @param array $data any optional data passed back to the test system
*/
private $headers;
/**
* @var phpQueryObject
*/
private $pq = null;
/**
* @var notifications
*/
private $notifications = null;
/**
* @param $content string
* @param $headers array
*/
function __construct($content, $headers) {
function __construct($content, $headers, $data = array()) {
$this->content = $content;
$this->headers = $headers;
$this->data = $data;
}
/**
* Returns the response body
*
* @return string
*/
public function getContent() {
@ -40,6 +39,8 @@ class TestResponse {
}
/**
* Returns the headers set in the response
*
* @return array
*/
public function getHeaders() {
@ -47,13 +48,15 @@ class TestResponse {
}
/**
* Return a single header
*
* @param $name string, the name of the header without the ':', e.g. 'Content-Type', 'Pragma'
* @return mixed if exactly one header, the header (string); otherwise an array of headers, empty when no headers
*/
public function getHeader($name) {
$result = array();
foreach ($this->headers as $header) {
if (substr($header,0,strlen($name)+1) == $name.':') {
foreach($this->headers as $header) {
if(substr($header, 0, strlen($name) + 1) == $name . ':') {
$result[] = $header;
}
}
@ -62,26 +65,28 @@ class TestResponse {
}
/**
* @return int http status code
* Access the http status code
*
* in the test environment, only status codes explicitly set by dokuwiki are likely to be returned
* this means succcessful status codes (e.g. 200 OK) will not be present, but error codes will be
*
* @return int http status code
*/
public function getStatusCode() {
$headers = $this->getHeader('Status');
$code = null;
if ($headers) {
if($headers) {
// if there is more than one status header, use the last one
$status = is_array($headers) ? array_pop($headers) : $headers;
$matches = array();
preg_match('/^Status: ?(\d+)/',$status,$matches);
if ($matches){
preg_match('/^Status: ?(\d+)/', $status, $matches);
if($matches) {
$code = $matches[1];
}
}
}
return $code;
return $code;
}
/**
@ -91,22 +96,19 @@ class TestResponse {
* @param $selector string
* @return phpQueryObject
*/
public function queryHTML($selector){
public function queryHTML($selector) {
if(is_null($this->pq)) $this->pq = phpQuery::newDocument($this->content);
return $this->pq->find($selector);
}
/**
* Returns all collected data for the given key
*
* @param string $key
* @return array
*/
public function getNotifications() {
return $this->notifications;
}
/**
* Set notifications
*/
public function setNotifications(array $new) {
$this->notifications = $new;
public function getData($key) {
if(!isset($this->data[$key])) return array();
return $this->data[$key];
}
}

View File

@ -81,16 +81,10 @@ class EditAndSaveTest extends DokuWikiTest {
// The response should carry a notification that a redirect
// was executed to our header ID
$found = null;
$notifications = $response->getNotifications();
foreach ($notifications as $notification) {
if ($notification['name'] == 'send_redirect') {
$found = &$notification;
}
}
$this->assertTrue($found !== null);
$hash = strpos($found['url'], '#');
$headerID = substr($found['url'], $hash);
$found = $response->getData('send_redirect');
$this->assertCount(1, $found);
$hash = strpos($found[0], '#');
$headerID = substr($found[0], $hash);
$this->assertEquals($headerID, '#'.$idA[1]);
}
@ -170,16 +164,10 @@ class EditAndSaveTest extends DokuWikiTest {
// The response should carry a notification that a redirect
// was executed to our header ID
$found = null;
$notifications = $response->getNotifications();
foreach ($notifications as $notification) {
if ($notification['name'] == 'send_redirect') {
$found = &$notification;
}
}
$this->assertTrue($found !== null);
$hash = strpos($found['url'], '#');
$headerID = substr($found['url'], $hash);
$found = $response->getData('send_redirect');
$this->assertCount(1, $found);
$hash = strpos($found[0], '#');
$headerID = substr($found[0], $hash);
$this->assertEquals($headerID, '#'.$idB[1]);
}
}

View File

@ -1924,16 +1924,16 @@ function send_redirect($url) {
header('Location: '.$url);
}
// no exits during unit tests
if(defined('DOKU_UNITTEST')) {
global $currentTestRequest;
if ($currentTestRequest != null) {
// Create a notification which later can we queried from the TestResponse by
// calling 'getNotifications()'.
$currentTestRequest->addNotification (array('name' => 'send_redirect', 'url' => $url));
// pass info about the redirect back to the test suite
$testRequest = TestRequest::getRunning();
if($testRequest !== null) {
$testRequest->addData('send_redirect', $url);
}
// no exits during unit tests
return;
}
exit;
}