Merge pull request #7680 from JMAConsulting/CRM-16259-9
[civicrm-core.git] / tests / phpunit / CRM / Core / ResourcesTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
81621fee 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
e7112fa7 6 | Copyright CiviCRM LLC (c) 2004-2015 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035 27
6a488035
TO
28/**
29 * Tests for linking to resource files
acb109b7 30 * @group headless
6a488035
TO
31 */
32class CRM_Core_ResourcesTest extends CiviUnitTestCase {
6a488035
TO
33
34 /**
35 * @var CRM_Core_Resources
36 */
37 protected $res;
38
39 /**
40 * @var CRM_Extension_Mapper
41 */
42 protected $mapper;
43
00be9182 44 public function setUp() {
6a488035
TO
45 parent::setUp();
46
47 list ($this->basedir, $this->container, $this->mapper) = $this->_createMapper();
48 $cache = new CRM_Utils_Cache_Arraycache(array());
49 $this->res = new CRM_Core_Resources($this->mapper, $cache, NULL);
50 $this->res->setCacheCode('resTest');
51 CRM_Core_Resources::singleton($this->res);
52
53 // Templates injected into regions should normally be file names, but for unit-testing it's handy to use "string:" notation
54 require_once 'CRM/Core/Smarty/resources/String.php';
481a74f4 55 civicrm_smarty_register_string_resource();
6a488035
TO
56 }
57
00be9182 58 public function testAddScriptFile() {
6a488035
TO
59 $this->res
60 ->addScriptFile('com.example.ext', 'foo%20bar.js', 0, 'testAddScriptFile')
92915c55 61 ->addScriptFile('com.example.ext', 'foo%20bar.js', 0, 'testAddScriptFile')// extra
6c6e6187 62 ->addScriptFile('civicrm', 'foo%20bar.js', 0, 'testAddScriptFile');
6a488035
TO
63
64 $smarty = CRM_Core_Smarty::singleton();
65 $actual = $smarty->fetch('string:{crmRegion name=testAddScriptFile}{/crmRegion}');
66 $expected = "" // stable ordering: alphabetical by (snippet.weight,snippet.name)
67 . "<script type=\"text/javascript\" src=\"http://core-app/foo%20bar.js?r=resTest\">\n</script>\n"
6c6e6187 68 . "<script type=\"text/javascript\" src=\"http://ext-dir/com.example.ext/foo%20bar.js?r=resTest\">\n</script>\n";
6a488035
TO
69 $this->assertEquals($expected, $actual);
70 }
71
72 /**
73 * When adding a script file, any ts() expressions should be translated and added to the 'strings'
74 *
75 * FIXME: This can't work because the tests run in English and CRM_Core_Resources optimizes
76 * away the English data from $settings['strings']
92915c55
TO
77 * public function testAddScriptFile_strings() {
78 * file_put_contents($this->mapper->keyToBasePath('com.example.ext') . '/hello.js', 'alert(ts("Hello world"));');
79 * $this->res->addScriptFile('com.example.ext', 'hello.js', 0, 'testAddScriptFile_strings');
80 * $settings = $this->res->getSettings();
81 * $expected = array('Hello world');
82 * $this->assertEquals($expected, $settings['strings']);
83 * }
6c6e6187 84 */
6a488035 85
a1a2a83d
TO
86 /**
87 * Ensure that adding a script URL creates expected markup.
88 */
00be9182 89 public function testAddScriptURL() {
6a488035
TO
90 $this->res
91 ->addScriptUrl('/whiz/foo%20bar.js', 0, 'testAddScriptURL')
92915c55 92 ->addScriptUrl('/whiz/foo%20bar.js', 0, 'testAddScriptURL')// extra
6c6e6187 93 ->addScriptUrl('/whizbang/foo%20bar.js', 0, 'testAddScriptURL');
6a488035
TO
94
95 $smarty = CRM_Core_Smarty::singleton();
96 $actual = $smarty->fetch('string:{crmRegion name=testAddScriptURL}{/crmRegion}');
97 $expected = "" // stable ordering: alphabetical by (snippet.weight,snippet.name)
98 . "<script type=\"text/javascript\" src=\"/whiz/foo%20bar.js\">\n</script>\n"
6c6e6187 99 . "<script type=\"text/javascript\" src=\"/whizbang/foo%20bar.js\">\n</script>\n";
6a488035
TO
100 $this->assertEquals($expected, $actual);
101 }
102
00be9182 103 public function testAddScript() {
6a488035
TO
104 $this->res
105 ->addScript('alert("hi");', 0, 'testAddScript')
6c6e6187 106 ->addScript('alert("there");', 0, 'testAddScript');
6a488035
TO
107
108 $smarty = CRM_Core_Smarty::singleton();
109 $actual = $smarty->fetch('string:{crmRegion name=testAddScript}{/crmRegion}');
110 $expected = ""
111 . "<script type=\"text/javascript\">\nalert(\"hi\");\n</script>\n"
6c6e6187 112 . "<script type=\"text/javascript\">\nalert(\"there\");\n</script>\n";
6a488035
TO
113 $this->assertEquals($expected, $actual);
114 }
115
00be9182 116 public function testAddVars() {
73bcd446
CW
117 $this->res
118 ->addVars('food', array('fruit' => array('mine' => 'apple', 'ours' => 'banana')))
6c6e6187 119 ->addVars('food', array('fruit' => array('mine' => 'new apple', 'yours' => 'orange')));
73bcd446 120 $this->assertTreeEquals(
92915c55
TO
121 array(
122 'vars' => array(
123 'food' => array(
124 'fruit' => array(
125 'yours' => 'orange',
126 'mine' => 'new apple',
af9b09df
TO
127 'ours' => 'banana',
128 ),
129 ),
130 ),
92915c55 131 ),
73bcd446
CW
132 $this->res->getSettings()
133 );
134 }
135
00be9182 136 public function testAddSetting() {
6a488035
TO
137 $this->res
138 ->addSetting(array('fruit' => array('mine' => 'apple')))
6c6e6187 139 ->addSetting(array('fruit' => array('yours' => 'orange')));
6a488035
TO
140 $this->assertTreeEquals(
141 array('fruit' => array('yours' => 'orange', 'mine' => 'apple')),
142 $this->res->getSettings()
143 );
144 $actual = $this->res->renderSetting();
6521a306
CW
145 $expected = json_encode(array('fruit' => array('yours' => 'orange', 'mine' => 'apple')));
146 $this->assertTrue(strpos($actual, $expected) !== FALSE);
6a488035
TO
147 }
148
00be9182 149 public function testAddSettingFactory() {
92915c55 150 $this->res->addSettingsFactory(function () {
6a488035
TO
151 return array('fruit' => array('yours' => 'orange'));
152 });
92915c55 153 $this->res->addSettingsFactory(function () {
6a488035
TO
154 return array('fruit' => array('mine' => 'apple'));
155 });
156
157 $actual = $this->res->getSettings();
158 $expected = array('fruit' => array('yours' => 'orange', 'mine' => 'apple'));
159 $this->assertTreeEquals($expected, $actual);
160 }
161
00be9182 162 public function testAddSettingAndSettingFactory() {
6a488035
TO
163 $this->res->addSetting(array('fruit' => array('mine' => 'apple')));
164
165 $muckableValue = array('fruit' => array('yours' => 'orange', 'theirs' => 'apricot'));
92915c55 166 $this->res->addSettingsFactory(function () use (&$muckableValue) {
6a488035
TO
167 return $muckableValue;
168 });
169 $actual = $this->res->getSettings();
170 $expected = array('fruit' => array('mine' => 'apple', 'yours' => 'orange', 'theirs' => 'apricot'));
171 $this->assertTreeEquals($expected, $actual);
172
173 // note: the setting is not fixed based on what the factory returns when registered; it's based
174 // on what the factory returns when getSettings is called
175 $muckableValue = array('fruit' => array('yours' => 'banana'));
176 $actual = $this->res->getSettings();
177 $expected = array('fruit' => array('mine' => 'apple', 'yours' => 'banana'));
178 $this->assertTreeEquals($expected, $actual);
179 }
180
00be9182 181 public function testCrmJS() {
6a488035
TO
182 $smarty = CRM_Core_Smarty::singleton();
183
184 $actual = $smarty->fetch('string:{crmScript ext=com.example.ext file=foo%20bar.js region=testCrmJS}');
185 $this->assertEquals('', $actual);
186
187 $actual = $smarty->fetch('string:{crmScript url=/whiz/foo%20bar.js region=testCrmJS weight=1}');
188 $this->assertEquals('', $actual);
189
190 $actual = $smarty->fetch('string:{crmRegion name=testCrmJS}{/crmRegion}');
191 $expected = "" // stable ordering: alphabetical by (snippet.weight,snippet.name)
192 . "<script type=\"text/javascript\" src=\"http://ext-dir/com.example.ext/foo%20bar.js?r=resTest\">\n</script>\n"
6c6e6187 193 . "<script type=\"text/javascript\" src=\"/whiz/foo%20bar.js\">\n</script>\n";
6a488035
TO
194 $this->assertEquals($expected, $actual);
195 }
196
00be9182 197 public function testAddStyleFile() {
6a488035
TO
198 $this->res
199 ->addStyleFile('com.example.ext', 'foo%20bar.css', 0, 'testAddStyleFile')
92915c55 200 ->addStyleFile('com.example.ext', 'foo%20bar.css', 0, 'testAddStyleFile')// extra
6c6e6187 201 ->addStyleFile('civicrm', 'foo%20bar.css', 0, 'testAddStyleFile');
6a488035
TO
202
203 $smarty = CRM_Core_Smarty::singleton();
204 $actual = $smarty->fetch('string:{crmRegion name=testAddStyleFile}{/crmRegion}');
205 $expected = "" // stable ordering: alphabetical by (snippet.weight,snippet.name)
206 . "<link href=\"http://core-app/foo%20bar.css?r=resTest\" rel=\"stylesheet\" type=\"text/css\"/>\n"
6c6e6187 207 . "<link href=\"http://ext-dir/com.example.ext/foo%20bar.css?r=resTest\" rel=\"stylesheet\" type=\"text/css\"/>\n";
6a488035
TO
208 $this->assertEquals($expected, $actual);
209 }
210
00be9182 211 public function testAddStyleURL() {
6a488035
TO
212 $this->res
213 ->addStyleUrl('/whiz/foo%20bar.css', 0, 'testAddStyleURL')
92915c55 214 ->addStyleUrl('/whiz/foo%20bar.css', 0, 'testAddStyleURL')// extra
6c6e6187 215 ->addStyleUrl('/whizbang/foo%20bar.css', 0, 'testAddStyleURL');
6a488035
TO
216
217 $smarty = CRM_Core_Smarty::singleton();
218 $actual = $smarty->fetch('string:{crmRegion name=testAddStyleURL}{/crmRegion}');
219 $expected = "" // stable ordering: alphabetical by (snippet.weight,snippet.name)
220 . "<link href=\"/whiz/foo%20bar.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
6c6e6187 221 . "<link href=\"/whizbang/foo%20bar.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
6a488035
TO
222 $this->assertEquals($expected, $actual);
223 }
224
00be9182 225 public function testAddStyle() {
6a488035
TO
226 $this->res
227 ->addStyle('body { background: black; }', 0, 'testAddStyle')
6c6e6187 228 ->addStyle('body { text-color: black; }', 0, 'testAddStyle');
6a488035
TO
229
230 $smarty = CRM_Core_Smarty::singleton();
231 $actual = $smarty->fetch('string:{crmRegion name=testAddStyle}{/crmRegion}');
232 $expected = ""
233 . "<style type=\"text/css\">\nbody { background: black; }\n</style>\n"
6c6e6187 234 . "<style type=\"text/css\">\nbody { text-color: black; }\n</style>\n";
6a488035
TO
235 $this->assertEquals($expected, $actual);
236 }
237
00be9182 238 public function testCrmCSS() {
6a488035
TO
239 $smarty = CRM_Core_Smarty::singleton();
240
241 $actual = $smarty->fetch('string:{crmStyle ext=com.example.ext file=foo%20bar.css region=testCrmCSS}');
242 $this->assertEquals('', $actual);
243
244 $actual = $smarty->fetch('string:{crmStyle url=/whiz/foo%20bar.css region=testCrmCSS weight=1}');
245 $this->assertEquals('', $actual);
246
247 $actual = $smarty->fetch('string:{crmRegion name=testCrmCSS}{/crmRegion}');
248 $expected = "" // stable ordering: alphabetical by (snippet.weight,snippet.name)
249 . "<link href=\"http://ext-dir/com.example.ext/foo%20bar.css?r=resTest\" rel=\"stylesheet\" type=\"text/css\"/>\n"
6c6e6187 250 . "<link href=\"/whiz/foo%20bar.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
6a488035
TO
251 $this->assertEquals($expected, $actual);
252 }
253
00be9182 254 public function testGetURL() {
6a488035
TO
255 $this->assertEquals(
256 'http://core-app/dir/file%20name.txt',
257 $this->res->getURL('civicrm', 'dir/file%20name.txt')
258 );
259 $this->assertEquals(
260 'http://ext-dir/com.example.ext/dir/file%20name.txt',
261 $this->res->getURL('com.example.ext', 'dir/file%20name.txt')
262 );
263 $this->assertEquals(
264 'http://core-app/',
265 $this->res->getURL('civicrm')
266 );
267 $this->assertEquals(
268 'http://ext-dir/com.example.ext/',
269 $this->res->getURL('com.example.ext')
270 );
271 }
272
00be9182 273 public function testCrmResURL() {
6a488035
TO
274 $smarty = CRM_Core_Smarty::singleton();
275
276 $actual = $smarty->fetch('string:{crmResURL ext=com.example.ext file=foo%20bar.png}');
277 $this->assertEquals('http://ext-dir/com.example.ext/foo%20bar.png', $actual);
278
279 $actual = $smarty->fetch('string:{crmResURL ext=com.example.ext file=foo%20bar.png addCacheCode=1}');
280 $this->assertEquals('http://ext-dir/com.example.ext/foo%20bar.png?r=resTest', $actual);
281
282 $actual = $smarty->fetch('string:{crmResURL ext=com.example.ext}');
283 $this->assertEquals('http://ext-dir/com.example.ext/', $actual);
284 }
285
16cd1eca
TO
286 public function testGlob() {
287 $this->assertEquals(
288 array('info.xml'),
289 $this->res->glob('com.example.ext', 'info.xml')
290 );
291 $this->assertEquals(
292 array('js/example.js'),
293 $this->res->glob('com.example.ext', 'js/*.js')
294 );
295 $this->assertEquals(
296 array('js/example.js'),
297 $this->res->glob('com.example.ext', array('js/*.js'))
298 );
299 }
300
6a488035
TO
301 /**
302 * @param CRM_Utils_Cache_Interface $cache
72b3a70c 303 * @param string $cacheKey
2a6da8d7 304 *
72b3a70c
CW
305 * @return array
306 * [string $basedir, CRM_Extension_Container_Interface, CRM_Extension_Mapper]
6a488035 307 */
00be9182 308 public function _createMapper(CRM_Utils_Cache_Interface $cache = NULL, $cacheKey = NULL) {
6a488035
TO
309 $basedir = rtrim($this->createTempDir('ext-'), '/');
310 mkdir("$basedir/com.example.ext");
16cd1eca 311 mkdir("$basedir/com.example.ext/js");
6a488035 312 file_put_contents("$basedir/com.example.ext/info.xml", "<extension key='com.example.ext' type='report'><file>oddball</file></extension>");
16cd1eca 313 file_put_contents("$basedir/com.example.ext/js/example.js", "alert('Boo!');");
6a488035
TO
314 // not needed for now // file_put_contents("$basedir/weird/bar/oddball.php", "<?php\n");
315 $c = new CRM_Extension_Container_Basic($basedir, 'http://ext-dir', $cache, $cacheKey);
316 $mapper = new CRM_Extension_Mapper($c, NULL, NULL, '/pathto/civicrm', 'http://core-app');
317 return array($basedir, $c, $mapper);
318 }
319
320}