xref: /dokuwiki/_test/core/TestRequest.php (revision 1ada9e0af1c0660c512bf5aa0e313746a5d95a26)
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
10572dc222SLarsDW223$currentTestRequest = null;
11572dc222SLarsDW223
12f8369d7dSTobias Sarnowskifunction ob_start_callback($buffer) {
13f8369d7dSTobias Sarnowski    global $output_buffer;
14f8369d7dSTobias Sarnowski    $output_buffer .= $buffer;
15f8369d7dSTobias Sarnowski}
16f8369d7dSTobias Sarnowski
17f8369d7dSTobias Sarnowski/**
18f8369d7dSTobias Sarnowski * Helper class to execute a fake request
19f8369d7dSTobias Sarnowski */
20f8369d7dSTobias Sarnowskiclass TestRequest {
21f8369d7dSTobias Sarnowski
22*1ada9e0aSAndreas Gohr    protected $valid_scripts = array('/doku.php', '/lib/exe/fetch.php', '/lib/exe/detail.php', '/lib/exe/ajax.php');
23*1ada9e0aSAndreas Gohr    protected $script;
249894e7afSChristopher Smith
25*1ada9e0aSAndreas Gohr    protected $server = array();
26*1ada9e0aSAndreas Gohr    protected $session = array();
27*1ada9e0aSAndreas Gohr    protected $get = array();
28*1ada9e0aSAndreas Gohr    protected $post = array();
29*1ada9e0aSAndreas Gohr    protected $notifications = array();
30f8369d7dSTobias Sarnowski
31*1ada9e0aSAndreas Gohr    /**
32*1ada9e0aSAndreas Gohr     * Get a $_SERVER var
33*1ada9e0aSAndreas Gohr     *
34*1ada9e0aSAndreas Gohr     * @param string $key
35*1ada9e0aSAndreas Gohr     * @return mixed
36*1ada9e0aSAndreas Gohr     */
37*1ada9e0aSAndreas Gohr    public function getServer($key) {
38*1ada9e0aSAndreas Gohr        return $this->server[$key];
39*1ada9e0aSAndreas Gohr    }
40f8369d7dSTobias Sarnowski
41*1ada9e0aSAndreas Gohr    /**
42*1ada9e0aSAndreas Gohr     * Get a $_SESSION var
43*1ada9e0aSAndreas Gohr     *
44*1ada9e0aSAndreas Gohr     * @param string $key
45*1ada9e0aSAndreas Gohr     * @return mixed
46*1ada9e0aSAndreas Gohr     */
47*1ada9e0aSAndreas Gohr    public function getSession($key) {
48*1ada9e0aSAndreas Gohr        return $this->session[$key];
49*1ada9e0aSAndreas Gohr    }
50*1ada9e0aSAndreas Gohr
51*1ada9e0aSAndreas Gohr    /**
52*1ada9e0aSAndreas Gohr     * Get a $_GET var
53*1ada9e0aSAndreas Gohr     *
54*1ada9e0aSAndreas Gohr     * @param string $key
55*1ada9e0aSAndreas Gohr     * @return mixed
56*1ada9e0aSAndreas Gohr     */
57*1ada9e0aSAndreas Gohr    public function getGet($key) {
58*1ada9e0aSAndreas Gohr        return $this->get[$key];
59*1ada9e0aSAndreas Gohr    }
60*1ada9e0aSAndreas Gohr
61*1ada9e0aSAndreas Gohr    /**
62*1ada9e0aSAndreas Gohr     * Get a $_POST var
63*1ada9e0aSAndreas Gohr     *
64*1ada9e0aSAndreas Gohr     * @param string $key
65*1ada9e0aSAndreas Gohr     * @return mixed
66*1ada9e0aSAndreas Gohr     */
67*1ada9e0aSAndreas Gohr    public function getPost($key) {
68*1ada9e0aSAndreas Gohr        return $this->post[$key];
69*1ada9e0aSAndreas Gohr    }
70*1ada9e0aSAndreas Gohr
71*1ada9e0aSAndreas Gohr    /**
72*1ada9e0aSAndreas Gohr     * Get the script that will execute the request
73*1ada9e0aSAndreas Gohr     *
74*1ada9e0aSAndreas Gohr     * @return string
75*1ada9e0aSAndreas Gohr     */
76*1ada9e0aSAndreas Gohr    public function getScript() {
77*1ada9e0aSAndreas Gohr        return $this->script;
78*1ada9e0aSAndreas Gohr    }
79*1ada9e0aSAndreas Gohr
80*1ada9e0aSAndreas Gohr    /**
81*1ada9e0aSAndreas Gohr     * Set a $_SERVER var
82*1ada9e0aSAndreas Gohr     *
83*1ada9e0aSAndreas Gohr     * @param string $key
84*1ada9e0aSAndreas Gohr     * @param mixed $value
85*1ada9e0aSAndreas Gohr     */
86*1ada9e0aSAndreas Gohr    public function setServer($key, $value) {
87*1ada9e0aSAndreas Gohr        $this->server[$key] = $value;
88*1ada9e0aSAndreas Gohr    }
89*1ada9e0aSAndreas Gohr
90*1ada9e0aSAndreas Gohr    /**
91*1ada9e0aSAndreas Gohr     * Set a $_SESSION var
92*1ada9e0aSAndreas Gohr     *
93*1ada9e0aSAndreas Gohr     * @param string $key
94*1ada9e0aSAndreas Gohr     * @param mixed $value
95*1ada9e0aSAndreas Gohr     */
96*1ada9e0aSAndreas Gohr    public function setSession($key, $value) {
97*1ada9e0aSAndreas Gohr        $this->session[$key] = $value;
98*1ada9e0aSAndreas Gohr    }
99*1ada9e0aSAndreas Gohr
100*1ada9e0aSAndreas Gohr    /**
101*1ada9e0aSAndreas Gohr     * Set a $_GET var
102*1ada9e0aSAndreas Gohr     *
103*1ada9e0aSAndreas Gohr     * @param string $key
104*1ada9e0aSAndreas Gohr     * @param mixed $value
105*1ada9e0aSAndreas Gohr     */
106*1ada9e0aSAndreas Gohr    public function setGet($key, $value) {
107*1ada9e0aSAndreas Gohr        $this->get[$key] = $value;
108*1ada9e0aSAndreas Gohr    }
109*1ada9e0aSAndreas Gohr
110*1ada9e0aSAndreas Gohr    /**
111*1ada9e0aSAndreas Gohr     * Set a $_POST var
112*1ada9e0aSAndreas Gohr     *
113*1ada9e0aSAndreas Gohr     * @param string $key
114*1ada9e0aSAndreas Gohr     * @param mixed $value
115*1ada9e0aSAndreas Gohr     */
116*1ada9e0aSAndreas Gohr    public function setPost($key, $value) {
117*1ada9e0aSAndreas Gohr        $this->post[$key] = $value;
118*1ada9e0aSAndreas Gohr    }
119f8369d7dSTobias Sarnowski
120f8369d7dSTobias Sarnowski    /**
121f8369d7dSTobias Sarnowski     * Executes the request
122f8369d7dSTobias Sarnowski     *
123*1ada9e0aSAndreas Gohr     * @param string $uri end URL to simulate, needs to be one of the testable scripts
124f8369d7dSTobias Sarnowski     * @return TestResponse the resulting output of the request
125f8369d7dSTobias Sarnowski     */
1264d053d04SAndreas Gohr    public function execute($uri = '/doku.php') {
127fe717f57Slisps        global $INPUT;
128572dc222SLarsDW223        global $currentTestRequest;
129572dc222SLarsDW223
130572dc222SLarsDW223        $currentTestRequest = $this;
131fe717f57Slisps
132f8369d7dSTobias Sarnowski        // save old environment
133f8369d7dSTobias Sarnowski        $server = $_SERVER;
134f8369d7dSTobias Sarnowski        $session = $_SESSION;
135f8369d7dSTobias Sarnowski        $get = $_GET;
136f8369d7dSTobias Sarnowski        $post = $_POST;
137f8369d7dSTobias Sarnowski        $request = $_REQUEST;
138fe717f57Slisps        $input = $INPUT;
139f8369d7dSTobias Sarnowski
1404d053d04SAndreas Gohr        // prepare the right URI
1414d053d04SAndreas Gohr        $this->setUri($uri);
1424d053d04SAndreas Gohr
1430189bd86SAndreas Gohr        // import all defined globals into the function scope
1440189bd86SAndreas Gohr        foreach(array_keys($GLOBALS) as $glb) {
1450189bd86SAndreas Gohr            global $$glb;
1460189bd86SAndreas Gohr        }
1470189bd86SAndreas Gohr
148f8369d7dSTobias Sarnowski        // fake environment
149f8369d7dSTobias Sarnowski        global $default_server_vars;
150f8369d7dSTobias Sarnowski        $_SERVER = array_merge($default_server_vars, $this->server);
151f8369d7dSTobias Sarnowski        $_SESSION = $this->session;
152f8369d7dSTobias Sarnowski        $_GET = $this->get;
153f8369d7dSTobias Sarnowski        $_POST = $this->post;
154f8369d7dSTobias Sarnowski        $_REQUEST = array_merge($_GET, $_POST);
155f8369d7dSTobias Sarnowski
156f8369d7dSTobias Sarnowski        // reset output buffer
157f8369d7dSTobias Sarnowski        global $output_buffer;
158f8369d7dSTobias Sarnowski        $output_buffer = '';
159f8369d7dSTobias Sarnowski
160f8369d7dSTobias Sarnowski        // now execute dokuwiki and grep the output
161f8369d7dSTobias Sarnowski        header_remove();
162f8369d7dSTobias Sarnowski        ob_start('ob_start_callback');
163fe717f57Slisps        $INPUT = new Input();
1649894e7afSChristopher Smith        include(DOKU_INC . $this->script);
165f8369d7dSTobias Sarnowski        ob_end_flush();
166f8369d7dSTobias Sarnowski
167f8369d7dSTobias Sarnowski        // create the response object
168f8369d7dSTobias Sarnowski        $response = new TestResponse(
169f8369d7dSTobias Sarnowski            $output_buffer,
1709894e7afSChristopher 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
171f8369d7dSTobias Sarnowski        );
172572dc222SLarsDW223        if($this->notifications != null) {
173572dc222SLarsDW223            $response->setNotifications($this->notifications);
174572dc222SLarsDW223        }
175f8369d7dSTobias Sarnowski
176f8369d7dSTobias Sarnowski        // reset environment
177f8369d7dSTobias Sarnowski        $_SERVER = $server;
178f8369d7dSTobias Sarnowski        $_SESSION = $session;
179f8369d7dSTobias Sarnowski        $_GET = $get;
180f8369d7dSTobias Sarnowski        $_POST = $post;
181f8369d7dSTobias Sarnowski        $_REQUEST = $request;
182fe717f57Slisps        $INPUT = $input;
183f8369d7dSTobias Sarnowski
184572dc222SLarsDW223        $currentTestRequest = null;
185572dc222SLarsDW223
186f8369d7dSTobias Sarnowski        return $response;
187f8369d7dSTobias Sarnowski    }
1889e777ceeSAndreas Gohr
1899e777ceeSAndreas Gohr    /**
1909e777ceeSAndreas Gohr     * Set the virtual URI the request works against
1919e777ceeSAndreas Gohr     *
1929e777ceeSAndreas Gohr     * This parses the given URI and sets any contained GET variables
1939e777ceeSAndreas Gohr     * but will not overwrite any previously set ones (eg. set via setGet()).
1949e777ceeSAndreas Gohr     *
1959e777ceeSAndreas Gohr     * It initializes the $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING']
1969e777ceeSAndreas Gohr     * with all set GET variables.
1979e777ceeSAndreas Gohr     *
198*1ada9e0aSAndreas Gohr     * @param string $uri end URL to simulate
199*1ada9e0aSAndreas Gohr     * @throws Exception when an invalid script is passed
2009e777ceeSAndreas Gohr     */
2014d053d04SAndreas Gohr    protected function setUri($uri) {
2029894e7afSChristopher Smith        if(!preg_match('#^(' . join('|', $this->valid_scripts) . ')#', $uri)) {
2039894e7afSChristopher Smith            throw new Exception("$uri \n--- only " . join(', ', $this->valid_scripts) . " are supported currently");
2049e777ceeSAndreas Gohr        }
2059e777ceeSAndreas Gohr
2069e777ceeSAndreas Gohr        $params = array();
2079e777ceeSAndreas Gohr        list($uri, $query) = explode('?', $uri, 2);
2089e777ceeSAndreas Gohr        if($query) parse_str($query, $params);
2099e777ceeSAndreas Gohr
2109894e7afSChristopher Smith        $this->script = substr($uri, 1);
2119e777ceeSAndreas Gohr        $this->get = array_merge($params, $this->get);
2129e777ceeSAndreas Gohr        if(count($this->get)) {
2139e777ceeSAndreas Gohr            $query = '?' . http_build_query($this->get, '', '&');
2149e777ceeSAndreas Gohr            $query = str_replace(
2159e777ceeSAndreas Gohr                array('%3A', '%5B', '%5D'),
2169e777ceeSAndreas Gohr                array(':', '[', ']'),
2179e777ceeSAndreas Gohr                $query
2189e777ceeSAndreas Gohr            );
2199e777ceeSAndreas Gohr            $uri = $uri . $query;
2209e777ceeSAndreas Gohr        }
2219e777ceeSAndreas Gohr
2229e777ceeSAndreas Gohr        $this->setServer('QUERY_STRING', $query);
2239e777ceeSAndreas Gohr        $this->setServer('REQUEST_URI', $uri);
2249e777ceeSAndreas Gohr    }
2259e777ceeSAndreas Gohr
2269e777ceeSAndreas Gohr    /**
2279e777ceeSAndreas Gohr     * Simulate a POST request with the given variables
2289e777ceeSAndreas Gohr     *
2299e777ceeSAndreas Gohr     * @param array $post all the POST parameters to use
230*1ada9e0aSAndreas Gohr     * @param string $uri end URL to simulate
231*1ada9e0aSAndreas Gohr     * @return TestResponse
2329e777ceeSAndreas Gohr     */
2339e777ceeSAndreas Gohr    public function post($post = array(), $uri = '/doku.php') {
2349e777ceeSAndreas Gohr        $this->post = array_merge($this->post, $post);
2359e777ceeSAndreas Gohr        $this->setServer('REQUEST_METHOD', 'POST');
2364d053d04SAndreas Gohr        return $this->execute($uri);
2379e777ceeSAndreas Gohr    }
2389e777ceeSAndreas Gohr
2399e777ceeSAndreas Gohr    /**
2409e777ceeSAndreas Gohr     * Simulate a GET request with the given variables
2419e777ceeSAndreas Gohr     *
242*1ada9e0aSAndreas Gohr     * @param array $get all the GET parameters to use
243*1ada9e0aSAndreas Gohr     * @param string $uri end URL to simulate
244*1ada9e0aSAndreas Gohr     * @return TestResponse
2459e777ceeSAndreas Gohr     */
2469e777ceeSAndreas Gohr    public function get($get = array(), $uri = '/doku.php') {
2479e777ceeSAndreas Gohr        $this->get = array_merge($this->get, $get);
2489e777ceeSAndreas Gohr        $this->setServer('REQUEST_METHOD', 'GET');
2494d053d04SAndreas Gohr        return $this->execute($uri);
2509e777ceeSAndreas Gohr    }
2519e777ceeSAndreas Gohr
252572dc222SLarsDW223    /**
253572dc222SLarsDW223     * Add a notification to later store it in the test respone.
254572dc222SLarsDW223     */
255572dc222SLarsDW223    public function addNotification(array $new) {
256572dc222SLarsDW223        $this->notifications[] = $new;
257572dc222SLarsDW223    }
258f8369d7dSTobias Sarnowski}
259