3f4956eba1345ef3fa65bcea647f68e608237725
[civicrm-core.git] / tests / phpunit / CRM / Core / RegionTest.php
1 <?php
2
3 /**
4 * Class CRM_Core_RegionTest
5 * @group headless
6 */
7 class CRM_Core_RegionTest extends CiviUnitTestCase {
8 public function setUp() {
9 parent::setUp();
10 require_once 'CRM/Core/Smarty.php';
11 require_once 'CRM/Core/Region.php';
12
13 // Templates injected into regions should normally be file names, but for unit-testing it's handy to use "string:" notation
14 require_once 'CRM/Core/Smarty/resources/String.php';
15 civicrm_smarty_register_string_resource();
16 }
17
18 /**
19 * When a {crmRegion} is blank and when there are no extra snippets, the
20 * output is blank.
21 */
22 public function testBlank() {
23 $smarty = CRM_Core_Smarty::singleton();
24 $actual = $smarty->fetch('string:{crmRegion name=testBlank}{/crmRegion}');
25 $expected = '';
26 $this->assertEquals($expected, $actual);
27 }
28
29 /**
30 * When a {crmRegion} is not blank and when there are no extra snippets,
31 * the output is only determined by the {crmRegion} block.
32 */
33 public function testDefault() {
34 $smarty = CRM_Core_Smarty::singleton();
35 $actual = $smarty->fetch('string:{crmRegion name=testDefault}default<br/>{/crmRegion}');
36 $expected = 'default<br/>';
37 $this->assertEquals($expected, $actual);
38 }
39
40 /**
41 * Disable the normal content of a {crmRegion} and apply different content from a snippet
42 */
43 public function testOverride() {
44 CRM_Core_Region::instance('testOverride')->update('default', array(
45 'disabled' => TRUE,
46 ));
47 CRM_Core_Region::instance('testOverride')->add(array(
48 'markup' => 'override<br/>',
49 ));
50
51 $smarty = CRM_Core_Smarty::singleton();
52 $actual = $smarty->fetch('string:{crmRegion name=testOverride}default<br/>{/crmRegion}');
53 $expected = 'override<br/>';
54 $this->assertEquals($expected, $actual);
55 }
56
57 /**
58 * Test that each of the major content formats are correctly evaluated.
59 */
60 public function testAllTypes() {
61 CRM_Core_Region::instance('testAllTypes')->add(array(
62 'markup' => 'some-markup<br/>',
63 ));
64 CRM_Core_Region::instance('testAllTypes')->add(array(
65 // note: 'template' would normally be a file name
66 'template' => 'string:smarty-is-{$snippet.extrainfo}<br/>',
67 'extrainfo' => 'dynamic',
68 ));
69 CRM_Core_Region::instance('testAllTypes')->add(array(
70 // note: returns a value which gets appended to the region
71 'callback' => 'implode',
72 'arguments' => array('-', array('callback', 'with', 'specific', 'args<br/>')),
73 ));
74 CRM_Core_Region::instance('testAllTypes')->add(array(
75 // note: returns a value which gets appended to the region
76 'callback' => function(&$spec, &$html) {
77 return "callback-return<br/>";
78 },
79 ));
80 CRM_Core_Region::instance('testAllTypes')->add(array(
81 // note: returns void; directly modifies region's $html
82 'callback' => function(&$spec, &$html) {
83 $html = "callback-ref<br/>" . $html;
84 },
85 ));
86 CRM_Core_Region::instance('testAllTypes')->add(array(
87 'scriptUrl' => '/foo%20bar.js',
88 ));
89 CRM_Core_Region::instance('testAllTypes')->add(array(
90 'script' => 'alert("hi");',
91 ));
92 CRM_Core_Region::instance('testAllTypes')->add(array(
93 'jquery' => '$("div");',
94 ));
95 CRM_Core_Region::instance('testAllTypes')->add(array(
96 'styleUrl' => '/foo%20bar.css',
97 ));
98 CRM_Core_Region::instance('testAllTypes')->add(array(
99 'style' => 'body { background: black; }',
100 ));
101
102 $smarty = CRM_Core_Smarty::singleton();
103 $actual = $smarty->fetch('string:{crmRegion name=testAllTypes}default<br/>{/crmRegion}');
104 $expected = "callback-ref<br/>"
105 . "default<br/>"
106 . "some-markup<br/>"
107 . "smarty-is-dynamic<br/>"
108 . "callback-with-specific-args<br/>"
109 . "callback-return<br/>"
110 . "<script type=\"text/javascript\" src=\"/foo%20bar.js\">\n</script>\n"
111 . "<script type=\"text/javascript\">\nalert(\"hi\");\n</script>\n"
112 . "<script type=\"text/javascript\">\nCRM.\$(function(\$) {\n\$(\"div\");\n});\n</script>\n"
113 . "<link href=\"/foo%20bar.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
114 . "<style type=\"text/css\">\nbody { background: black; }\n</style>\n";
115 $this->assertEquals($expected, $actual);
116 }
117
118 /**
119 * Test of nested arrangement in which one {crmRegion} directly includes another {crmRegion}
120 */
121 public function testDirectNest() {
122 CRM_Core_Region::instance('testDirectNestOuter')->add(array(
123 'template' => 'string:O={$snippet.weight} ',
124 'weight' => -5,
125 ));
126 CRM_Core_Region::instance('testDirectNestOuter')->add(array(
127 'template' => 'string:O={$snippet.weight} ',
128 'weight' => 5,
129 ));
130
131 CRM_Core_Region::instance('testDirectNestInner')->add(array(
132 'template' => 'string:I={$snippet.weight} ',
133 'weight' => -5,
134 ));
135 CRM_Core_Region::instance('testDirectNestInner')->add(array(
136 'template' => 'string:I={$snippet.weight} ',
137 'weight' => 5,
138 ));
139
140 $smarty = CRM_Core_Smarty::singleton();
141 $actual = $smarty->fetch('string:{crmRegion name=testDirectNestOuter}left {crmRegion name=testDirectNestInner}middle {/crmRegion}right {/crmRegion}');
142 $expected = 'O=-5 left I=-5 middle I=5 right O=5 ';
143 $this->assertEquals($expected, $actual);
144 }
145
146 /**
147 * Test of nested arrangement in which one {crmRegion} is enhanced with a snippet which, in turn, includes another {crmRegion}
148 */
149 public function testIndirectNest() {
150 CRM_Core_Region::instance('testIndirectNestOuter')->add(array(
151 // Note: all three $snippet references are bound to the $snippet which caused this template to be included,
152 // regardless of any nested {crmRegion}s
153 'template' => 'string: O={$snippet.region}{crmRegion name=testIndirectNestInner} O={$snippet.region}{/crmRegion} O={$snippet.region}',
154 ));
155
156 CRM_Core_Region::instance('testIndirectNestInner')->add(array(
157 'template' => 'string: I={$snippet.region}',
158 ));
159
160 $smarty = CRM_Core_Smarty::singleton();
161 $actual = $smarty->fetch('string:{crmRegion name=testIndirectNestOuter}default{/crmRegion}');
162 $expected = 'default O=testIndirectNestOuter O=testIndirectNestOuter I=testIndirectNestInner O=testIndirectNestOuter';
163 $this->assertEquals($expected, $actual);
164 }
165
166 /**
167 * Output from an inner-region should not be executed verbatim; this is obvious but good to verify
168 */
169 public function testNoInjection() {
170 CRM_Core_Region::instance('testNoInjectionOuter')->add(array(
171 'template' => 'string:{$snippet.scarystuff} ',
172 'scarystuff' => '{$is_outer_scary}',
173 ));
174 CRM_Core_Region::instance('testNoInjectionInner')->add(array(
175 'template' => 'string:{$snippet.scarystuff} ',
176 'scarystuff' => '{$is_inner_scary}',
177 ));
178
179 $smarty = CRM_Core_Smarty::singleton();
180 $smarty->assign('is_outer_scary', 'egad');
181 $smarty->assign('is_inner_scary', 'egad');
182 $smarty->assign('also_scary', 'egad');
183 $actual = $smarty->fetch('string:{crmRegion name=testNoInjectionOuter}left {crmRegion name=testNoInjectionInner}middle {literal}{$also_scary}{/literal} {/crmRegion}right {/crmRegion}');
184 $expected = 'left middle {$also_scary} {$is_inner_scary} right {$is_outer_scary} ';
185 $this->assertEquals($expected, $actual);
186 }
187
188 /**
189 * Make sure that standard Smarty variables ($smarty->assign(...)) as well
190 * as the magical $snippet variable both evaluate correctly.
191 */
192 public function testSmartyVars() {
193 $smarty = CRM_Core_Smarty::singleton();
194 $smarty->assign('extrainfo', 'one');
195 CRM_Core_Region::instance('testSmartyVars')->add(array(
196 'template' => 'string:var-style-{$extrainfo}<br/>',
197 ));
198
199 CRM_Core_Region::instance('testSmartyVars')->add(array(
200 'template' => 'string:var-style-{$snippet.extrainfo}<br/>',
201 'extrainfo' => 'two',
202 ));
203
204 $actual = $smarty->fetch('string:{crmRegion name=testSmartyVars}default<br/>{/crmRegion}');
205 $expected = 'default<br/>var-style-one<br/>var-style-two<br/>';
206 $this->assertEquals($expected, $actual);
207 }
208
209 public function testWeight() {
210 CRM_Core_Region::instance('testWeight')->add(array(
211 'markup' => 'prepend-5<br/>',
212 'weight' => -5,
213 ));
214 CRM_Core_Region::instance('testWeight')->add(array(
215 'markup' => 'append+3<br/>',
216 'weight' => 3,
217 ));
218 CRM_Core_Region::instance('testWeight')->add(array(
219 'markup' => 'prepend-3<br/>',
220 'weight' => -3,
221 ));
222 CRM_Core_Region::instance('testWeight')->add(array(
223 'markup' => 'append+5<br/>',
224 'weight' => 5,
225 ));
226
227 $smarty = CRM_Core_Smarty::singleton();
228 $actual = $smarty->fetch('string:{crmRegion name=testWeight}default<br/>{/crmRegion}');
229 $expected = 'prepend-5<br/>prepend-3<br/>default<br/>append+3<br/>append+5<br/>';
230 $this->assertEquals($expected, $actual);
231 }
232
233 }