2 /*********************************************************************************
3 * SugarCRM Community Edition is a customer relationship management program developed by
4 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Affero General Public License version 3 as published by the
8 * Free Software Foundation with the addition of the following permission added
9 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18 * You should have received a copy of the GNU Affero General Public License along with
19 * this program; if not, see http://www.gnu.org/licenses or write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26 * The interactive user interfaces in modified source and object code versions
27 * of this program must display Appropriate Legal Notices, as required under
28 * Section 5 of the GNU Affero General Public License version 3.
30 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31 * these Appropriate Legal Notices must retain the display of the "Powered by
32 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33 * technical reasons, the Appropriate Legal Notices must display the words
34 * "Powered by SugarCRM".
35 ********************************************************************************/
38 require_once 'include/SugarTheme/SugarTheme.php';
39 require_once 'include/dir_inc.php';
41 class SugarThemeTest extends Sugar_PHPUnit_Framework_TestCase
47 private $_themeObject;
48 private $_themeDefChild;
49 private $_themeObjectChild;
50 private $_olddeveloperMode;
52 public function setup()
55 include('themes/'.SugarTestThemeUtilities::createAnonymousTheme().'/themedef.php');
57 $this->_themeDef = $themedef;
58 SugarThemeRegistry::add($this->_themeDef);
59 $this->_themeObject = SugarThemeRegistry::get($this->_themeDef['dirName']);
62 include('themes/'.SugarTestThemeUtilities::createAnonymousChildTheme($this->_themeObject->__toString()).'/themedef.php');
64 $this->_themeDefChild = $themedef;
65 SugarThemeRegistry::add($this->_themeDefChild);
66 $this->_themeObjectChild = SugarThemeRegistry::get($this->_themeDefChild['dirName']);
68 // test assumes developerMode is off, so css minifying happens
69 if (inDeveloperMode())
71 $this->_olddeveloperMode = $GLOBALS['sugar_config']['developerMode'];
73 $GLOBALS['sugar_config']['developerMode'] = false;
76 public function testMagicIssetWorks()
78 $this->assertTrue(isset($this->_themeObject->dirName));
81 public function tearDown()
83 $themesToRemove = array($this->_themeObject->__toString(),$this->_themeObjectChild->__toString());
85 SugarTestThemeUtilities::removeAllCreatedAnonymousThemes();
87 if ( $this->_olddeveloperMode )
88 $GLOBALS['sugar_config']['developerMode'] = $this->_olddeveloperMode;
90 unset($GLOBALS['sugar_config']['developerMode']);
93 public function testCaching()
95 $this->_themeObject->getCSSURL("style.css");
96 $themename = $this->_themeObject->__toString();
97 $pathname = "themes/{$themename}/css/style.css";
99 // test if it's in the local cache
100 $this->assertTrue(isset($this->_themeObject->_cssCache['style.css']));
101 $this->assertEquals($pathname, $this->_themeObject->_cssCache['style.css']);
104 $this->_themeObject->__destruct();
105 unset($this->_themeObject);
107 // now recreate object
108 SugarThemeRegistry::add($this->_themeDef);
109 $this->_themeObject = SugarThemeRegistry::get($this->_themeDef['dirName']);
111 // should still be in local cache
112 $this->assertTrue(isset($this->_themeObject->_cssCache['style.css']));
113 $this->assertEquals($pathname, $this->_themeObject->_cssCache['style.css']);
115 // now, let's tell the theme we want to clear the cache on destroy
116 $this->_themeObject->clearCache();
119 $this->_themeObject->__destruct();
120 unset($this->_themeObject);
122 // now recreate object
123 SugarThemeRegistry::add($this->_themeDef);
124 $this->_themeObject = SugarThemeRegistry::get($this->_themeDef['dirName']);
126 // should not be in local cache
127 $this->assertFalse(isset($this->_themeObject->_cssCache['style.css']));
130 public function testCreateInstance()
132 foreach ( $this->_themeDef as $key => $value )
133 $this->assertEquals($this->_themeObject->$key,$value);
136 public function testGetFilePath()
138 $this->assertEquals($this->_themeObject->getFilePath(),
139 'themes/'.$this->_themeDef['name']);
142 public function testGetImagePath()
144 $this->assertEquals($this->_themeObject->getImagePath(),
145 'themes/'.$this->_themeDef['name'].'/images');
148 public function testGetCSSPath()
150 $this->assertEquals($this->_themeObject->getCSSPath(),
151 'themes/'.$this->_themeDef['name'].'/css');
154 public function testGetCSS()
157 preg_match_all('/href="([^"]+)"/',$this->_themeObject->getCSS(),$matches);
159 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/css\/yui.css/',$matches[1][$i++]);
160 //$this->assertRegExp('/themes\/default\/css\/bootstrap.css/',$matches[1][$i++]);
161 $this->assertRegExp('/include\/javascript\/jquery\/themes\/base\/jquery.ui.all.css/',$matches[1][$i++]);
162 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/css\/deprecated.css/',$matches[1][$i++]);
163 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/css\/style.css/',$matches[1][$i++]);
165 $output = file_get_contents(sugar_cached('themes/').$this->_themeObject->__toString().'/css/style.css');
166 $this->assertRegExp('/h2\{display:inline\}/',$output);
169 public function testGetCSSWithParams()
172 preg_match_all('/href="([^"]+)"/',$this->_themeObject->getCSS('blue','small'),$matches);
174 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/css\/yui.css/',$matches[1][$i++]);
175 //$this->assertRegExp('/themes\/default\/css\/bootstrap.css/',$matches[1][$i++]);
176 $this->assertRegExp('/include\/javascript\/jquery\/themes\/base\/jquery.ui.all.css/',$matches[1][$i++]);
177 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/css\/deprecated.css/',$matches[1][$i++]);
178 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/css\/style.css/',$matches[1][$i++]);
180 $output = file_get_contents(sugar_cached('themes/').$this->_themeObject->__toString().'/css/style.css');
181 $this->assertRegExp('/h2\{display:inline\}/',$output);
184 public function testGetCSSWithCustomStyleCSS()
186 create_custom_directory('themes/'.$this->_themeObject->__toString().'/css/');
187 sugar_file_put_contents('custom/themes/'.$this->_themeObject->__toString().'/css/style.css','h3 { color: red; }');
190 preg_match_all('/href="([^"]+)"/',$this->_themeObject->getCSS(),$matches);
193 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/css\/yui.css/',$matches[1][$i++]);
194 //$this->assertRegExp('/themes\/default\/css\/bootstrap.css/',$matches[1][$i++]);
195 $this->assertRegExp('/include\/javascript\/jquery\/themes\/base\/jquery.ui.all.css/',$matches[1][$i++]);
196 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/css\/deprecated.css/',$matches[1][$i++]);
197 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/css\/style.css/',$matches[1][$i++]);
199 $output = file_get_contents(sugar_cached('themes/').$this->_themeObject->__toString().'/css/style.css');
200 $this->assertRegExp('/h2\{display:inline\}h3\{color:red\}/',$output);
203 public function testGetCSSWithParentTheme()
206 preg_match_all('/href="([^"]+)"/',$this->_themeObjectChild->getCSS(),$matches);
209 $this->assertRegExp('/themes\/'.$this->_themeObjectChild->__toString().'\/css\/yui.css/',$matches[1][$i++]);
210 //$this->assertRegExp('/themes\/default\/css\/bootstrap.css/',$matches[1][$i++]);
211 $this->assertRegExp('/include\/javascript\/jquery\/themes\/base\/jquery.ui.all.css/',$matches[1][$i++]);
212 $this->assertRegExp('/themes\/'.$this->_themeObjectChild->__toString().'\/css\/deprecated.css/',$matches[1][$i++]);
213 $this->assertRegExp('/themes\/'.$this->_themeObjectChild->__toString().'\/css\/style.css/',$matches[1][$i++]);
215 $output = file_get_contents(sugar_cached('themes/').$this->_themeObjectChild->__toString().'/css/style.css');
216 $this->assertRegExp('/h2\{display:inline\}h3\{display:inline\}/',$output);
219 public function testGetCSSURLWithInvalidFileSpecifed()
221 $this->assertFalse($this->_themeObject->getCSSURL('ThisFileDoesNotExist.css'));
224 public function testGetCSSURLAddsJsPathIfSpecified()
226 // check one may not hit cache
227 $this->assertRegExp('/style\.css\?/',$this->_themeObject->getCSSURL('style.css'));
228 // check two definitely should hit cache
229 $this->assertRegExp('/style\.css\?/',$this->_themeObject->getCSSURL('style.css'));
230 // check three for the jspath not being added
231 $this->assertNotContains('?',$this->_themeObject->getCSSURL('style.css',false));
234 public function testGetJS()
237 preg_match_all('/src="([^"]+)"/',$this->_themeObject->getJS(),$matches);
240 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/js\/style-min.js/',$matches[1][$i++]);
242 $output = file_get_contents(sugar_cached('themes/').$this->_themeObject->__toString().'/js/style-min.js');
243 $this->assertRegExp('/var dog="cat";/',$output);
246 public function testGetJSCustom()
248 create_custom_directory('themes/'.$this->_themeObject->__toString().'/js/');
249 sugar_file_put_contents('custom/themes/'.$this->_themeObject->__toString().'/js/style.js','var x = 1;');
252 preg_match_all('/src="([^"]+)"/',$this->_themeObject->getJS(),$matches);
255 $this->assertRegExp('/themes\/'.$this->_themeObject->__toString().'\/js\/style-min.js/',$matches[1][$i++]);
257 $output = file_get_contents(sugar_cached('themes/').$this->_themeObject->__toString().'/js/style-min.js');
258 $this->assertRegExp('/var dog="cat";/',$output);
259 $this->assertRegExp('/var x=1;/',$output);
262 public function testGetJSWithParentTheme()
265 preg_match_all('/src="([^"]+)"/',$this->_themeObjectChild->getJS(),$matches);
268 $this->assertRegExp('/themes\/'.$this->_themeObjectChild->__toString().'\/js\/style-min.js/',$matches[1][$i++]);
270 $output = file_get_contents(sugar_cached('themes/').$this->_themeObjectChild->__toString().'/js/style-min.js');
271 $this->assertRegExp('/var dog="cat";var bird="frog";/',$output);
274 public function testGetJSURLWithInvalidFileSpecifed()
276 $this->assertFalse($this->_themeObject->getJSURL('ThisFileDoesNotExist.js'));
279 public function testGetJSURLAddsJsPathIfSpecified()
281 // check one may not hit cache
282 $this->assertRegExp('/style-min\.js\?/',$this->_themeObject->getJSURL('style.js'));
283 // check two definitely should hit cache
284 $this->assertRegExp('/style-min\.js\?/',$this->_themeObject->getJSURL('style.js'));
285 // check three for the jspath not being added
286 $this->assertNotContains('?',$this->_themeObject->getJSURL('style.js',false));
289 public function testGetImageURL()
291 $this->assertEquals('themes/'.$this->_themeObject->__toString().'/images/Accounts.gif',
292 $this->_themeObject->getImageURL('Accounts.gif',false));
295 public function testGetImageURLWithInvalidFileSpecifed()
297 $this->assertFalse($this->_themeObject->getImageURL('ThisFileDoesNotExist.gif'));
300 public function testGetImageURLCustom()
302 create_custom_directory('themes/'.$this->_themeObject->__toString().'/images/');
303 sugar_touch('custom/themes/'.$this->_themeObject->__toString().'/images/Accounts.gif');
305 $this->assertEquals('custom/themes/'.$this->_themeObject->__toString().'/images/Accounts.gif',
306 $this->_themeObject->getImageURL('Accounts.gif',false));
309 public function testGetImageURLCustomDifferentExtension()
311 create_custom_directory('themes/'.$this->_themeObject->__toString().'/images/');
312 sugar_touch('custom/themes/'.$this->_themeObject->__toString().'/images/Accounts.png');
314 $this->assertEquals('custom/themes/'.$this->_themeObject->__toString().'/images/Accounts.png',
315 $this->_themeObject->getImageURL('Accounts.gif',false));
318 public function testGetImageURLDefault()
320 $this->assertEquals('themes/default/images/Emails.gif',$this->_themeObject->getImageURL('Emails.gif',false));
323 public function testGetImageURLDefaultCustom()
325 create_custom_directory('themes/default/images/');
326 sugar_touch('custom/themes/default/images/Emails.gif');
328 $this->assertEquals('custom/themes/default/images/Emails.gif',
329 $this->_themeObject->getImageURL('Emails.gif',false));
331 unlink('custom/themes/default/images/Emails.gif');
334 public function testGetImageURLNotFound()
336 $this->assertEquals('',$this->_themeObject->getImageURL('NoImageByThisName.gif',false));
339 public function testGetImageURLAddsJsPathIfSpecified()
341 // check one may not hit cache
342 $this->assertRegExp('/Accounts\.gif\?/',$this->_themeObject->getImageURL('Accounts.gif'));
343 // check two definitely should hit cache
344 $this->assertRegExp('/Accounts\.gif\?/',$this->_themeObject->getImageURL('Accounts.gif'));
345 // check three for the jspath not being added
346 $this->assertNotContains('?',$this->_themeObject->getImageURL('Accounts.gif',false));
349 public function testGetImageURLWithParentTheme()
351 $this->assertEquals('themes/'.$this->_themeObject->__toString().'/images/Accounts.gif',
352 $this->_themeObjectChild->getImageURL('Accounts.gif',false));
355 public function testGetTemplate()
357 $this->assertEquals('themes/'.$this->_themeObject->__toString().'/tpls/header.tpl',
358 $this->_themeObject->getTemplate('header.tpl'));
361 public function testGetTemplateCustom()
363 create_custom_directory('themes/'.$this->_themeObject->__toString().'/tpls/');
364 sugar_touch('custom/themes/'.$this->_themeObject->__toString().'/tpls/header.tpl');
366 $this->assertEquals('custom/themes/'.$this->_themeObject->__toString().'/tpls/header.tpl',
367 $this->_themeObject->getTemplate('header.tpl'));
370 public function testGetTemplateDefaultCustom()
372 create_custom_directory('themes/default/tpls/');
373 sugar_touch('custom/themes/default/tpls/SomeDefaultTemplate.tpl');
375 $this->assertEquals('custom/themes/default/tpls/SomeDefaultTemplate.tpl',
376 $this->_themeObject->getTemplate('SomeDefaultTemplate.tpl'));
378 unlink('custom/themes/default/tpls/SomeDefaultTemplate.tpl');
381 public function testGetTemplateWithParentTheme()
383 $this->assertEquals('themes/'.$this->_themeObject->__toString().'/tpls/header.tpl',
384 $this->_themeObjectChild->getTemplate('header.tpl'));
387 public function testGetTemplateNotFound()
389 $this->assertFalse($this->_themeObject->getTemplate('NoTemplateWithThisName.tpl'));
392 public function testGetAllImages()
394 $images = $this->_themeObject->getAllImages();
397 $this->_themeObject->getImageURL('Emails.gif',false),
398 $images['Emails.gif']);
401 public function testGetAllImagesWhenImageIsInParentTheme()
403 $images = $this->_themeObjectChild->getAllImages();
406 $this->_themeObjectChild->getImageURL('Accounts.gif',false),
407 $images['Accounts.gif']);
409 $this->assertContains(
410 $this->_themeObject->getImagePath(),
411 $images['Accounts.gif']);
414 public function testGetImageSpecifyingWidthAndHeightAndOtherAttributes()
417 $this->_themeObject->getImage('Emails','',20,30,'.gif',"Emails"),
418 "<img src=\"". $this->_themeObject->getImageURL('Emails.gif') ."\" width=\"20\" height=\"30\" alt=\"Emails\" />"
421 // check again to see if caching of the image size works as expected
423 $this->_themeObject->getImage('Emails','',30,40,'.gif',"Emails"),
424 "<img src=\"". $this->_themeObject->getImageURL('Emails.gif') ."\" width=\"30\" height=\"40\" alt=\"Emails\" />"
428 public function testGetImageDetectingImageHeightAndWidth()
430 $this->markTestIncomplete("Sprites have been turned off for now, so skipping test");
431 if ($GLOBALS['sugar_flavor'] == 'CE' || $GLOBALS['sugar_flavor'] == 'COM')
432 $this->markTestSkipped("skipping for CE UNTIL JELLE gets a chance to fix the related sprites issue next week");
433 $size = getimagesize($this->_themeObject->getImageURL('Contacts.gif',false));
434 $this->assertRegExp('/<span\s+?class[^>]+?><\/span>/', $this->_themeObject->getImage('Contacts','',null,null,'.gif',"Contacts"));
437 public function testGetImageWithInvalidImage()
439 $this->assertFalse($this->_themeObject->getImage('ThisImageDoesNotExist'));