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