1<?php
2
3/**
4 * This file is part of the Phalcon Framework.
5 *
6 * (c) Phalcon Team <team@phalcon.io>
7 *
8 * For the full copyright and license information, please view the
9 * LICENSE.txt file that was distributed with this source code.
10 */
11
12namespace Phalcon\Test\Unit\Flash;
13
14use Codeception\Example;
15use Phalcon\Flash\Session;
16use Phalcon\Storage\Exception;
17use Phalcon\Test\Fixtures\Traits\DiTrait;
18use UnitTester;
19
20class SessionCest
21{
22    use DiTrait;
23
24    /**
25     * @var array
26     */
27    protected $classes = [
28        'success' => 'successMessage',
29        'notice'  => 'noticeMessage',
30        'warning' => 'warningMessage',
31        'error'   => 'errorMessage',
32    ];
33
34    /**
35     * Executed before each test
36     *
37     * @param  UnitTester $I
38     * @return void
39     */
40    public function _before(UnitTester $I): void
41    {
42        $this->newDi();
43
44        try {
45            $this->setDiService('escaper');
46            $this->setDiService('sessionStream');
47        } catch (Exception $e) {
48            $I->fail($e->getMessage());
49        }
50
51        if (PHP_SESSION_ACTIVE !== session_status()) {
52            session_start();
53        }
54
55        if (!isset($_SESSION)) {
56            $_SESSION = [];
57        }
58    }
59
60    /**
61     * Executed after each test
62     *
63     * @param  UnitTester $I
64     * @return void
65     */
66    public function _after(UnitTester $I): void
67    {
68        session_destroy();
69    }
70
71
72    /**
73     * Tests auto escaping
74     *
75     * @param  UnitTester $I
76     * @param  Example $example
77     *
78     * @author Phalcon Team <team@phalcon.io>
79     * @issue  https://github.com/phalcon/cphalcon/issues/11448
80     * @since  2016-06-15
81     *
82     * @dataProvider testShouldAutoEscapeHtmlProvider
83     */
84    public function testShouldAutoEscapeHtml(UnitTester $I, Example $example)
85    {
86        $function = $example[0];
87
88        $flash = $this->getFlash();
89
90
91        $flash->setAutoescape(false);
92
93        $message = "<script>alert('This will execute as JavaScript!')</script>";
94
95        $flash->$function($message);
96
97        $I->assertEquals(
98            [
99                $message,
100            ],
101            $flash->getMessages($function)
102        );
103
104
105        ob_start();
106        $flash->$function(
107            "<script>alert('This will execute as JavaScript!')</script>"
108        );
109        $flash->output();
110        $actual = ob_get_contents();
111        ob_end_clean();
112
113        $I->assertEquals(
114            "<div class=\"{$function}Message\">" .
115            "<script>alert('This will execute as JavaScript!')</script></div>" . PHP_EOL,
116            $actual
117        );
118
119
120        $flash->setAutoescape(true);
121
122        $message = "<script>alert('This will execute as JavaScript!')</script>";
123
124        $flash->$function($message);
125
126        $I->assertEquals(
127            [
128                $message,
129            ],
130            $flash->getMessages($function)
131        );
132
133
134        ob_start();
135        $flash->$function(
136            "<script>alert('This will execute as JavaScript!')</script>"
137        );
138        $flash->output();
139        $actual = ob_get_contents();
140        ob_end_clean();
141
142        $I->assertEquals(
143            "<div class=\"{$function}Message\">" .
144            "&lt;script&gt;alert(&#039;This will execute as JavaScript!" .
145            "&#039;)&lt;/script&gt;</div>" . PHP_EOL,
146            $actual
147        );
148    }
149
150    private function testShouldAutoEscapeHtmlProvider(): array
151    {
152        return [
153            ['error'],
154            ['success'],
155            ['notice'],
156            ['warning'],
157        ];
158    }
159
160    /**
161     * Return flash instance
162     */
163    protected function getFlash()
164    {
165        $container = $this->getDi();
166
167        $flash = new Session();
168        $flash->setDI($container);
169        $flash->setCssClasses($this->classes);
170
171        return $flash;
172    }
173
174    /**
175     * Test getMessages with specified type and removal
176     * activated, only removes the received messages.
177     *
178     * @param  UnitTester $I
179     *
180     * @author Iván Guillén <zeopix@gmail.com>
181     * @since  2015-10-26
182     */
183    public function testGetMessagesTypeRemoveMessages(UnitTester $I)
184    {
185        $flash = $this->getFlash();
186
187        $flash->success('sample success');
188        $flash->error('sample error');
189
190        $I->assertEquals(
191            [
192                'sample success',
193            ],
194            $flash->getMessages('success')
195        );
196
197        $I->assertEquals(
198            [
199                'sample error',
200            ],
201            $flash->getMessages('error')
202        );
203
204        $I->assertEmpty(
205            $flash->getMessages()
206        );
207    }
208
209    /**
210     * Tests getMessages in case of non existent type request
211     *
212     * @param  UnitTester $I
213     *
214     * @issue  https://github.com/phalcon/cphalcon/issues/11941
215     * @author Phalcon Team <team@phalcon.io>
216     * @since  2016-07-03
217     */
218    public function testGetNonExistentType(UnitTester $I)
219    {
220        $flash = $this->getFlash();
221
222        $flash->error('sample error');
223
224        $I->assertEquals(
225            [],
226            $flash->getMessages('success', false)
227        );
228
229        $I->assertCount(
230            1,
231            $flash->getMessages()
232        );
233    }
234
235    /**
236     * Tests clear method
237     *
238     * @param  UnitTester $I
239     *
240     * @author Iván Guillén <zeopix@gmail.com>
241     * @since  2015-10-26
242     */
243    public function testClearMessagesFormSession(UnitTester $I)
244    {
245        $flash = $this->getFlash();
246
247        ob_start();
248        $flash->output();
249        $flash->success('sample message');
250        $flash->clear();
251        $actual = ob_get_contents();
252        ob_end_clean();
253
254        $I->assertEquals(
255            '',
256            $actual
257        );
258    }
259
260    /**
261     * Test output formatted messages
262     *
263     * @param  UnitTester $I
264     * @param  Example $example
265     *
266     * @author       Iván Guillén <zeopix@gmail.com>
267     * @since        2015-10-26
268     *
269     * @dataProvider testMessageFormatProvider
270     */
271    public function testMessageFormat(UnitTester $I, Example $example)
272    {
273        $function = $example[0];
274
275        $flash = $this->getFlash();
276
277        $class = sprintf(
278            ' class="%s"',
279            $this->classes[$function]
280        );
281
282        $message = 'sample message';
283
284        $expected = sprintf(
285            '<div%s>%s</div>' . PHP_EOL,
286            $class,
287            $message
288        );
289
290        ob_start();
291        $flash->$function($message);
292        $flash->output();
293        $actual = ob_get_contents();
294        ob_end_clean();
295
296        $I->assertEquals($expected, $actual);
297    }
298
299    private function testMessageFormatProvider(): array
300    {
301        return [
302            ['error'],
303            ['success'],
304            ['notice'],
305        ];
306    }
307
308    /**
309     * Test custom message
310     *
311     * @param  UnitTester $I
312     *
313     * @author Phalcon Team <team@phalcon.io>
314     * @issue  https://github.com/phalcon/cphalcon/issues/13445
315     * @since  2018-10-16
316     */
317    public function testCustomFormat(UnitTester $I)
318    {
319        $flash = $this->getFlash();
320
321        $template = '<span class="%cssClass%" aria-label="clickme">%message%</span>';
322
323        $flash->setCustomTemplate($template);
324
325        $message = 'sample message';
326
327        $flash->success($message);
328
329        ob_start();
330        $flash->output();
331        $actual = ob_get_contents();
332        ob_end_clean();
333
334        $I->assertEquals(
335            '<span class="successMessage" aria-label="clickme">sample message</span>',
336            $actual
337        );
338    }
339}
340