Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.72% covered (success)
98.72%
77 / 78
90.00% covered (success)
90.00%
9 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
Base
98.72% covered (success)
98.72%
77 / 78
90.00% covered (success)
90.00%
9 / 10
29
0.00% covered (danger)
0.00%
0 / 1
 getSessionData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRequest
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 createBasicRequest
93.33% covered (success)
93.33%
14 / 15
0.00% covered (danger)
0.00%
0 / 1
4.00
 getResponse
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 testRendering
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getControllerIdentifier
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 render
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 setRequestParameters
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
10
 setValidatorInstance
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 assertRedirect
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
5 **/
6
7namespace BO\Slim\PhpUnit;
8
9use App;
10use BO\Slim\Middleware\Validator;
11use Helmich\Psr7Assert\Psr7Assertions;
12use PHPUnit\Framework\TestCase;
13use BO\Slim\Middleware\SessionMiddleware;
14use BO\Slim\Middleware\Session\SessionHuman;
15use BO\Slim\Middleware\Session\SessionData;
16use Psr\Http\Message\ServerRequestInterface;
17use Psr\Http\Message\ResponseInterface;
18use Slim\Psr7\Environment;
19use Slim\Psr7\Factory\UriFactory;
20use Slim\Psr7\Headers;
21use BO\Slim\Request;
22use BO\Slim\Response;
23use Slim\Psr7\Factory\StreamFactory;
24
25/**
26 * @SuppressWarnings(PHPMD)
27 */
28abstract class Base extends TestCase
29{
30    use Psr7Assertions;
31
32    /**
33      * Arguments for callback render
34      *
35      * @var array $arguments
36      */
37    protected $arguments = [];
38
39    /**
40      * Parameters for the request
41      *
42      * @var array $parameters
43      */
44    protected $parameters = [];
45
46    /**
47      * Data for the session
48      *
49      * @var array $sessionData
50      */
51    protected $sessionData = [];
52
53    /**
54     * Use this object instance for session getEntity()
55     *
56     * @var Object $sessionClass
57     */
58    protected $sessionClass = null;
59
60    /**
61     * Namespace for tested classes
62     */
63    protected $namespace = '';
64
65    /**
66     * A class name if not detected automatically
67     *
68     */
69    protected $classname = null;
70
71    /**
72     * Overwrite this function if session data needs function calls
73     *
74     */
75    protected function getSessionData(): array
76    {
77        return $this->sessionData;
78    }
79
80    /**
81     *
82     * @param string $method
83     * @param string $uri
84     * @param array|null $sessionData
85     *
86     * @return ServerRequestInterface
87     */
88    protected function getRequest(
89        string $method = 'GET',
90        string $uri = '',
91        ?array $sessionData = null
92    ): ServerRequestInterface {
93        if (null === $sessionData) {
94            $sessionData = $this->getSessionData();
95        }
96        if (array_key_exists('human', $sessionData) && array_key_exists('ts', $sessionData['human'])) {
97            // prevent isOveraged error-Handling
98            $sessionData['human']['ts'] = time() - 10;
99        }
100        $request = self::createBasicRequest($method, $uri, ['Accept' => \BO\Slim\Headers::MEDIA_TYPE_TEXT_HTML]);
101        $sessionContainer = SessionHuman::fromContainer(function () use ($sessionData) {
102            $session = new SessionData($sessionData);
103            $session->setEntityClass($this->sessionClass);
104            return $session;
105        });
106
107        return $request->withAttribute(SessionMiddleware::SESSION_ATTRIBUTE, $sessionContainer);
108    }
109
110    /**
111     * Create a simple basic request
112     *
113     * @param string $method
114     * @param string $uri
115     * @return ServerRequestInterface
116     */
117    public static function createBasicRequest(
118        string $method = "GET",
119        string $uri = '',
120        array $addHeaders = []
121    ): ServerRequestInterface {
122        $env = Environment::mock([
123            'REQUEST_METHOD'       => $method,
124            'REQUEST_URI'          => $uri,
125            'REMOTE_ADDR'          => '127.0.0.1'
126        ]);
127
128        $uri = (new UriFactory())->createFromGlobals($env);
129        $headers = Headers::createFromGlobals();
130        foreach ($addHeaders as $key => $value) {
131            $headers->addHeader($key, $value);
132        }
133
134        $body = (new StreamFactory())->createStream();
135
136        $request = new Request($method, $uri, $headers, [], $env, $body, []);
137
138        if (
139            $method === 'POST' &&
140            in_array($headers->getHeader('Content-Type'), ['application/x-www-form-urlencoded', 'multipart/form-data'])
141        ) {
142            // parsed body must be $_POST
143            $request = $request->withParsedBody($_POST);
144        }
145
146        return $request->withAttribute('ip_address', '127.0.0.1');
147    }
148
149    /**
150     *
151     * @return ResponseInterface
152     */
153    protected function getResponse($content = '', $status = 200, array $headers = [])
154    {
155        $body = (new StreamFactory())->createStream();
156        $headers = new Headers($headers);
157        $response = new Response($status, $headers, $body);
158        $body->write($content);
159        return $response;
160    }
161
162    public function testRendering()
163    {
164        $response = $this->render($this->arguments, $this->parameters);
165        $this->assertEquals(200, $response->getStatuscode());
166        return $response;
167    }
168
169    protected function getControllerIdentifier(): string
170    {
171        $classname = (null === $this->classname) ?
172            preg_replace('#^.*?(\w+)Test$#', '$1', get_class($this)) :
173            $this->classname;
174
175        return (false !== strpos($classname, '\\')) ? $classname : $this->namespace . $classname;
176    }
177
178    protected function render(
179        array $arguments = [],
180        $parameters = [],
181        $sessionData = null,
182        $method = 'GET'
183    ) {
184        $renderClass = $this->getControllerIdentifier();
185        /** @var \BO\Slim\Controller $controller */
186        $controller = new $renderClass(App::$slim->getContainer());
187
188        //add uri to test multi languages
189        $uri = (array_key_exists('__uri', $parameters)) ? $parameters['__uri'] : '';
190        $request = $this->getRequest($method, $uri, $sessionData);
191        $request = $this->setRequestParameters($request, $parameters, $method);
192        $this->setValidatorInstance($parameters);
193        $request = Validator::withValidator($request);
194
195        return $controller->__invoke($request, $this->getResponse(), $arguments);
196    }
197
198    protected function setRequestParameters(
199        ServerRequestInterface $request,
200        array $parameters,
201        string $method
202    ): ServerRequestInterface {
203        if ('GET' === $method) {
204            $request = $request->withQueryParams($parameters);
205        } elseif ('POST' === $method) {
206            $request = $request->withParsedBody($parameters);
207        }
208        if (array_key_exists('__body', $parameters)) {
209            $body = (new StreamFactory())->createStream();
210            $body->write($parameters['__body']);
211            $request = $request->withBody($body);
212        }
213        if (array_key_exists('__cookie', $parameters)) {
214            $request = $request->withCookieParams($parameters['__cookie']);
215        }
216        if (array_key_exists('__file', $parameters)) {
217            $request = $request->withUploadedFiles($parameters['__file']);
218        }
219        if (array_key_exists('__header', $parameters)) {
220            foreach ($parameters['__header'] as $key => $value) {
221                $request = $request->withAddedHeader($key, $value);
222            }
223        }
224        if (array_key_exists('__userinfo', $parameters)) {
225            $request = $request->withUri($request->getUri()->withUserInfo(
226                $parameters['__userinfo']['username'],
227                $parameters['__userinfo']['password']
228            ));
229        }
230        if (array_key_exists('__route', $parameters)) {
231            $request = $request->withAttribute('route', $parameters['__route']);
232        }
233
234        return $request;
235    }
236
237    protected function setValidatorInstance($parameters)
238    {
239        $validator = new \BO\Mellon\Validator($parameters);
240        if (array_key_exists('__body', $parameters)) {
241            $validator->setInput($parameters['__body']);
242        }
243        $validator->makeInstance();
244    }
245
246    public function assertRedirect($response, $uri, $status = 302)
247    {
248        $this->assertResponseHasStatus($response, $status);
249        $this->assertMessageHasHeaders($response, [
250            'Location' => $uri,
251        ]);
252    }
253}