xref: /dokuwiki/_test/core/TestRequest.php (revision 572dc222f8ab503392a593483bcc14fb9104f557)
1f8369d7dSTobias Sarnowski<?php
2f8369d7dSTobias Sarnowski/**
3f8369d7dSTobias Sarnowski * Simulates a full DokuWiki HTTP Request and allows
4f8369d7dSTobias Sarnowski * runtime inspection.
5f8369d7dSTobias Sarnowski */
6f8369d7dSTobias Sarnowski
7f8369d7dSTobias Sarnowski// output buffering
8f8369d7dSTobias Sarnowski$output_buffer = '';
9f8369d7dSTobias Sarnowski
10*572dc222SLarsDW223$currentTestRequest = null;
11*572dc222SLarsDW223
12f8369d7dSTobias Sarnowskifunction ob_start_callback($buffer) {
13f8369d7dSTobias Sarnowski    global $output_buffer;
14f8369d7dSTobias Sarnowski    $output_buffer .= $buffer;
15f8369d7dSTobias Sarnowski}
16f8369d7dSTobias Sarnowski
17f8369d7dSTobias Sarnowski
18f8369d7dSTobias Sarnowski/**
19f8369d7dSTobias Sarnowski * Helper class to execute a fake request
20f8369d7dSTobias Sarnowski */
21f8369d7dSTobias Sarnowskiclass TestRequest {
22f8369d7dSTobias Sarnowski
239894e7afSChristopher Smith    private $valid_scripts = array('/doku.php', '/lib/exe/fetch.php', '/lib/exe/detail.php');
249894e7afSChristopher Smith    private $script;
259894e7afSChristopher Smith
26f8369d7dSTobias Sarnowski    private $server = array();
27f8369d7dSTobias Sarnowski    private $session = array();
28f8369d7dSTobias Sarnowski    private $get = array();
29f8369d7dSTobias Sarnowski    private $post = array();
30*572dc222SLarsDW223    private $notifications = array();
31f8369d7dSTobias Sarnowski
32f8369d7dSTobias Sarnowski    public function getServer($key) { return $this->server[$key]; }
33f8369d7dSTobias Sarnowski    public function getSession($key) { return $this->session[$key]; }
34f8369d7dSTobias Sarnowski    public function getGet($key) { return $this->get[$key]; }
35f8369d7dSTobias Sarnowski    public function getPost($key) { return $this->post[$key]; }
369894e7afSChristopher Smith    public function getScript() { return $this->script; }
37f8369d7dSTobias Sarnowski
38f8369d7dSTobias Sarnowski    public function setServer($key, $value) { $this->server[$key] = $value; }
39f8369d7dSTobias Sarnowski    public function setSession($key, $value) { $this->session[$key] = $value; }
40f8369d7dSTobias Sarnowski    public function setGet($key, $value) { $this->get[$key] = $value; }
41f8369d7dSTobias Sarnowski    public function setPost($key, $value) { $this->post[$key] = $value; }
42f8369d7dSTobias Sarnowski
43f8369d7dSTobias Sarnowski    /**
44f8369d7dSTobias Sarnowski     * Executes the request
45f8369d7dSTobias Sarnowski     *
464d053d04SAndreas Gohr     * @param string $url  end URL to simulate, needs to start with /doku.php currently
47f8369d7dSTobias Sarnowski     * @return TestResponse the resulting output of the request
48f8369d7dSTobias Sarnowski     */
494d053d04SAndreas Gohr    public function execute($uri='/doku.php') {
50fe717f57Slisps        global $INPUT;
51*572dc222SLarsDW223        global $currentTestRequest;
52*572dc222SLarsDW223
53*572dc222SLarsDW223        $currentTestRequest = $this;
54fe717f57Slisps
55f8369d7dSTobias Sarnowski        // save old environment
56f8369d7dSTobias Sarnowski        $server = $_SERVER;
57f8369d7dSTobias Sarnowski        $session = $_SESSION;
58f8369d7dSTobias Sarnowski        $get = $_GET;
59f8369d7dSTobias Sarnowski        $post = $_POST;
60f8369d7dSTobias Sarnowski        $request = $_REQUEST;
61fe717f57Slisps        $input = $INPUT;
62f8369d7dSTobias Sarnowski
634d053d04SAndreas Gohr        // prepare the right URI
644d053d04SAndreas Gohr        $this->setUri($uri);
654d053d04SAndreas Gohr
660189bd86SAndreas Gohr        // import all defined globals into the function scope
670189bd86SAndreas Gohr        foreach(array_keys($GLOBALS) as $glb){
680189bd86SAndreas Gohr            global $$glb;
690189bd86SAndreas Gohr        }
700189bd86SAndreas Gohr
71f8369d7dSTobias Sarnowski        // fake environment
72f8369d7dSTobias Sarnowski        global $default_server_vars;
73f8369d7dSTobias Sarnowski        $_SERVER = array_merge($default_server_vars, $this->server);
74f8369d7dSTobias Sarnowski        $_SESSION = $this->session;
75f8369d7dSTobias Sarnowski        $_GET = $this->get;
76f8369d7dSTobias Sarnowski        $_POST = $this->post;
77f8369d7dSTobias Sarnowski        $_REQUEST = array_merge($_GET, $_POST);
78f8369d7dSTobias Sarnowski
79f8369d7dSTobias Sarnowski        // reset output buffer
80f8369d7dSTobias Sarnowski        global $output_buffer;
81f8369d7dSTobias Sarnowski        $output_buffer = '';
82f8369d7dSTobias Sarnowski
83f8369d7dSTobias Sarnowski        // now execute dokuwiki and grep the output
84f8369d7dSTobias Sarnowski        header_remove();
85f8369d7dSTobias Sarnowski        ob_start('ob_start_callback');
86fe717f57Slisps        $INPUT = new Input();
879894e7afSChristopher Smith        include(DOKU_INC.$this->script);
88f8369d7dSTobias Sarnowski        ob_end_flush();
89f8369d7dSTobias Sarnowski
90f8369d7dSTobias Sarnowski        // create the response object
91f8369d7dSTobias Sarnowski        $response = new TestResponse(
92f8369d7dSTobias Sarnowski            $output_buffer,
939894e7afSChristopher Smith            (function_exists('xdebug_get_headers') ? xdebug_get_headers() : headers_list())   // cli sapi doesn't do headers, prefer xdebug_get_headers() which works under cli
94f8369d7dSTobias Sarnowski        );
95*572dc222SLarsDW223        if ($this->notifications != null) {
96*572dc222SLarsDW223            $response->setNotifications($this->notifications);
97*572dc222SLarsDW223        }
98f8369d7dSTobias Sarnowski
99f8369d7dSTobias Sarnowski        // reset environment
100f8369d7dSTobias Sarnowski        $_SERVER = $server;
101f8369d7dSTobias Sarnowski        $_SESSION = $session;
102f8369d7dSTobias Sarnowski        $_GET = $get;
103f8369d7dSTobias Sarnowski        $_POST = $post;
104f8369d7dSTobias Sarnowski        $_REQUEST = $request;
105fe717f57Slisps        $INPUT = $input;
106f8369d7dSTobias Sarnowski
107*572dc222SLarsDW223        $currentTestRequest = null;
108*572dc222SLarsDW223
109f8369d7dSTobias Sarnowski        return $response;
110f8369d7dSTobias Sarnowski    }
1119e777ceeSAndreas Gohr
1129e777ceeSAndreas Gohr    /**
1139e777ceeSAndreas Gohr     * Set the virtual URI the request works against
1149e777ceeSAndreas Gohr     *
1159e777ceeSAndreas Gohr     * This parses the given URI and sets any contained GET variables
1169e777ceeSAndreas Gohr     * but will not overwrite any previously set ones (eg. set via setGet()).
1179e777ceeSAndreas Gohr     *
1189e777ceeSAndreas Gohr     * It initializes the $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING']
1199e777ceeSAndreas Gohr     * with all set GET variables.
1209e777ceeSAndreas Gohr     *
1219e777ceeSAndreas Gohr     * @param string $url  end URL to simulate, needs to start with /doku.php currently
1224d053d04SAndreas Gohr     * @todo make this work with other end points
1239e777ceeSAndreas Gohr     */
1244d053d04SAndreas Gohr    protected function setUri($uri){
1259894e7afSChristopher Smith        if(!preg_match('#^('.join('|',$this->valid_scripts).')#',$uri)){
1269894e7afSChristopher Smith            throw new Exception("$uri \n--- only ".join(', ',$this->valid_scripts)." are supported currently");
1279e777ceeSAndreas Gohr        }
1289e777ceeSAndreas Gohr
1299e777ceeSAndreas Gohr        $params = array();
1309e777ceeSAndreas Gohr        list($uri, $query) = explode('?',$uri,2);
1319e777ceeSAndreas Gohr        if($query) parse_str($query, $params);
1329e777ceeSAndreas Gohr
1339894e7afSChristopher Smith        $this->script = substr($uri,1);
1349e777ceeSAndreas Gohr        $this->get  = array_merge($params, $this->get);
1359e777ceeSAndreas Gohr        if(count($this->get)){
1369e777ceeSAndreas Gohr            $query = '?'.http_build_query($this->get, '', '&');
1379e777ceeSAndreas Gohr            $query = str_replace(
1389e777ceeSAndreas Gohr                array('%3A', '%5B', '%5D'),
1399e777ceeSAndreas Gohr                array(':', '[', ']'),
1409e777ceeSAndreas Gohr                $query
1419e777ceeSAndreas Gohr            );
1429e777ceeSAndreas Gohr            $uri = $uri.$query;
1439e777ceeSAndreas Gohr        }
1449e777ceeSAndreas Gohr
1459e777ceeSAndreas Gohr        $this->setServer('QUERY_STRING', $query);
1469e777ceeSAndreas Gohr        $this->setServer('REQUEST_URI', $uri);
1479e777ceeSAndreas Gohr    }
1489e777ceeSAndreas Gohr
1499e777ceeSAndreas Gohr    /**
1509e777ceeSAndreas Gohr     * Simulate a POST request with the given variables
1519e777ceeSAndreas Gohr     *
1529e777ceeSAndreas Gohr     * @param array $post  all the POST parameters to use
1539894e7afSChristopher Smith     * @param string $url  end URL to simulate, needs to start with /doku.php, /lib/exe/fetch.php or /lib/exe/detail.php currently
1549e777ceeSAndreas Gohr     * @param return TestResponse
1559e777ceeSAndreas Gohr     */
1569e777ceeSAndreas Gohr    public function post($post=array(), $uri='/doku.php') {
1579e777ceeSAndreas Gohr        $this->post = array_merge($this->post, $post);
1589e777ceeSAndreas Gohr        $this->setServer('REQUEST_METHOD', 'POST');
1594d053d04SAndreas Gohr        return $this->execute($uri);
1609e777ceeSAndreas Gohr    }
1619e777ceeSAndreas Gohr
1629e777ceeSAndreas Gohr    /**
1639e777ceeSAndreas Gohr     * Simulate a GET request with the given variables
1649e777ceeSAndreas Gohr     *
1659894e7afSChristopher Smith     * @param array $GET   all the GET parameters to use
1669894e7afSChristopher Smith     * @param string $url  end URL to simulate, needs to start with /doku.php, /lib/exe/fetch.php or /lib/exe/detail.php currently
1679e777ceeSAndreas Gohr     * @param return TestResponse
1689e777ceeSAndreas Gohr     */
1699e777ceeSAndreas Gohr    public function get($get=array(), $uri='/doku.php') {
1709e777ceeSAndreas Gohr        $this->get  = array_merge($this->get, $get);
1719e777ceeSAndreas Gohr        $this->setServer('REQUEST_METHOD', 'GET');
1724d053d04SAndreas Gohr        return $this->execute($uri);
1739e777ceeSAndreas Gohr    }
1749e777ceeSAndreas Gohr
175*572dc222SLarsDW223    /**
176*572dc222SLarsDW223     * Add a notification to later store it in the test respone.
177*572dc222SLarsDW223     */
178*572dc222SLarsDW223    public function addNotification(array $new) {
179*572dc222SLarsDW223        $this->notifications[] = $new;
180*572dc222SLarsDW223    }
181f8369d7dSTobias Sarnowski}
182