aaac1e989f1349eb77cfec7547a844c33d0f3ef2
[moodle.git] / lib / tests / output_mustache_helper_collection_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Unit tests for lib/classes/output/mustache_helper_collection
19  *
20  * @copyright 2019 Ryan Wyllie <ryan@moodle.com>
21  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22  */
24 defined('MOODLE_INTERNAL') || die();
26 use core\output\mustache_helper_collection;
28 /**
29  * Unit tests for the mustache_helper_collection class.
30  */
31 class core_output_mustache_helper_collection_testcase extends advanced_testcase {
32     /**
33      * Test cases to confirm that blacklisted helpers are stripped from the source
34      * text by the helper before being passed to other another helper. This prevents
35      * nested calls to helpers.
36      */
37     public function get_strip_blacklisted_helpers_testcases() {
38         return [
39             'no blacklist' => [
40                 'blacklist' => [],
41                 'input' => 'core, move, {{#js}} some nasty JS {{/js}}',
42                 'expected' => 'core, move, {{#js}} some nasty JS {{/js}}'
43             ],
44             'blacklist no match' => [
45                 'blacklist' => ['foo'],
46                 'input' => 'core, move, {{#js}} some nasty JS {{/js}}',
47                 'expected' => 'core, move, {{#js}} some nasty JS {{/js}}'
48             ],
49             'blacklist partial match 1' => [
50                 'blacklist' => ['js'],
51                 'input' => 'core, move, {{#json}} some nasty JS {{/json}}',
52                 'expected' => 'core, move, {{#json}} some nasty JS {{/json}}'
53             ],
54             'blacklist partial match 2' => [
55                 'blacklist' => ['js'],
56                 'input' => 'core, move, {{#onjs}} some nasty JS {{/onjs}}',
57                 'expected' => 'core, move, {{#onjs}} some nasty JS {{/onjs}}'
58             ],
59             'single blacklist 1' => [
60                 'blacklist' => ['js'],
61                 'input' => 'core, move, {{#js}} some nasty JS {{/js}}',
62                 'expected' => 'core, move, {{}}'
63             ],
64             'single blacklist 2' => [
65                 'blacklist' => ['js'],
66                 'input' => 'core, move, {{ # js }} some nasty JS {{ /  js }}',
67                 'expected' => 'core, move, {{}}'
68             ],
69             'single blacklist 3' => [
70                 'blacklist' => ['js'],
71                 'input' => 'core, {{#js}} some nasty JS {{/js}}, test',
72                 'expected' => 'core, {{}}, test'
73             ],
74             'single blacklist 3' => [
75                 'blacklist' => ['js'],
76                 'input' => 'core, {{#ok}} this is ok {{/ok}}, {{#js}} some nasty JS {{/js}}',
77                 'expected' => 'core, {{#ok}} this is ok {{/ok}}, {{}}'
78             ],
79             'single blacklist multiple matches 1' => [
80                 'blacklist' => ['js'],
81                 'input' => 'core, {{#js}} some nasty JS {{/js}}, {{#js}} some nasty JS {{/js}}',
82                 'expected' => 'core, {{}}'
83             ],
84             'single blacklist multiple matches 2' => [
85                 'blacklist' => ['js'],
86                 'input' => 'core, {{ # js }} some nasty JS {{ /  js }}, {{ # js }} some nasty JS {{ /  js }}',
87                 'expected' => 'core, {{}}'
88             ],
89             'single blacklist multiple matches nested 1' => [
90                 'blacklist' => ['js'],
91                 'input' => 'core, move, {{#js}} some nasty JS {{#js}} some nasty JS {{/js}} {{/js}}',
92                 'expected' => 'core, move, {{}}'
93             ],
94             'single blacklist multiple matches nested 2' => [
95                 'blacklist' => ['js'],
96                 'input' => 'core, move, {{ # js }} some nasty JS {{ # js }} some nasty JS {{ /  js }}{{ /  js }}',
97                 'expected' => 'core, move, {{}}'
98             ],
99             'multiple blacklist 1' => [
100                 'blacklist' => ['js', 'foo'],
101                 'input' => 'core, move, {{#js}} some nasty JS {{/js}}',
102                 'expected' => 'core, move, {{}}'
103             ],
104             'multiple blacklist 2' => [
105                 'blacklist' => ['js', 'foo'],
106                 'input' => 'core, {{#foo}} blah {{/foo}}, {{#js}} js {{/js}}',
107                 'expected' => 'core, {{}}, {{}}'
108             ],
109             'multiple blacklist 3' => [
110                 'blacklist' => ['js', 'foo'],
111                 'input' => '{{#foo}} blah {{/foo}}, {{#foo}} blah {{/foo}}, {{#js}} js {{/js}}',
112                 'expected' => '{{}}, {{}}'
113             ],
114             'multiple blacklist 4' => [
115                 'blacklist' => ['js', 'foo'],
116                 'input' => '{{#foo}} blah {{/foo}}, {{#js}} js {{/js}}, {{#foo}} blah {{/foo}}',
117                 'expected' => '{{}}'
118             ],
119             'multiple blacklist 4' => [
120                 'blacklist' => ['js', 'foo'],
121                 'input' => 'core, move, {{#js}} JS {{#foo}} blah {{/foo}} {{/js}}',
122                 'expected' => 'core, move, {{}}'
123             ],
124         ];
125     }
127     /**
128      * Test that the mustache_helper_collection class correctly strips
129      * @dataProvider get_strip_blacklisted_helpers_testcases()
130      * @param string[] $blacklist The list of helpers to strip
131      * @param string $input The input string for the helper
132      * @param string $expected The expected output of the string after blacklist strip
133      */
134     public function test_strip_blacklisted_helpers($blacklist, $input, $expected) {
135         $collection = new mustache_helper_collection(null, $blacklist);
136         $this->assertEquals($expected, $collection->strip_blacklisted_helpers($blacklist, $input));
137     }
139     /**
140      * Test that the blacklisted helpers are disabled during the execution of other
141      * helpers.
142      *
143      * Any non-blacklisted helper should still be available to call during the
144      * execution of a helper.
145      */
146     public function test_blacklisted_helpers_disabled_during_execution() {
147         $engine = new \Mustache_Engine();
148         $context = new \Mustache_Context();
149         $lambdahelper = new \Mustache_LambdaHelper($engine, $context);
150         $blacklist = ['bad'];
151         $collection = new mustache_helper_collection(null, $blacklist);
152         $badcalled = false;
153         $goodcalled = false;
155         $badhelper = function() use (&$badcalled) {
156             $badcalled = true;
157             return '';
158         };
159         $goodhelper = function() use (&$goodcalled) {
160             $goodcalled = true;
161             return '';
162         };
163         // A test helper that just returns the text without modifying it.
164         $testhelper = function($text, $lambda) use ($collection) {
165             $collection->get('good')($text, $lambda);
166             $collection->get('bad')($text, $lambda);
167             return $text;
168         };
169         $collection->add('bad', $badhelper);
170         $collection->add('good', $goodhelper);
171         $collection->add('test', $testhelper);
173         $this->assertEquals('success output', $collection->get('test')('success output', $lambdahelper));
174         $this->assertTrue($goodcalled);
175         $this->assertFalse($badcalled);
176     }