HtmlHelperTest.php 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484
  1. <?php
  2. /**
  3. * HtmlHelperTest file
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
  8. * Copyright 2005-2011, Cake Software Foundation, Inc.
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice
  12. *
  13. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc.
  14. * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
  15. * @package Cake.Test.Case.View.Helper
  16. * @since CakePHP(tm) v 1.2.0.4206
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. App::uses('Controller', 'Controller');
  20. App::uses('Helper', 'View');
  21. App::uses('AppHelper', 'View/Helper');
  22. App::uses('HtmlHelper', 'View/Helper');
  23. App::uses('FormHelper', 'View/Helper');
  24. App::uses('ClassRegistry', 'Utility');
  25. App::uses('Folder', 'Utility');
  26. if (!defined('FULL_BASE_URL')) {
  27. define('FULL_BASE_URL', 'http://cakephp.org');
  28. }
  29. /**
  30. * TheHtmlTestController class
  31. *
  32. * @package Cake.Test.Case.View.Helper
  33. */
  34. class TheHtmlTestController extends Controller {
  35. /**
  36. * name property
  37. *
  38. * @var string 'TheTest'
  39. */
  40. public $name = 'TheTest';
  41. /**
  42. * uses property
  43. *
  44. * @var mixed null
  45. */
  46. public $uses = null;
  47. }
  48. class TestHtmlHelper extends HtmlHelper {
  49. /**
  50. * expose a method as public
  51. *
  52. * @param string $options
  53. * @param string $exclude
  54. * @param string $insertBefore
  55. * @param string $insertAfter
  56. * @return void
  57. */
  58. public function parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
  59. return $this->_parseAttributes($options, $exclude, $insertBefore, $insertAfter);
  60. }
  61. /**
  62. * Get a protected attribute value
  63. *
  64. * @param string $attribute
  65. * @return mixed
  66. */
  67. public function getAttribute($attribute) {
  68. if (!isset($this->{$attribute})) {
  69. return null;
  70. }
  71. return $this->{$attribute};
  72. }
  73. }
  74. /**
  75. * Html5TestHelper class
  76. *
  77. * @package Cake.Test.Case.View.Helper
  78. */
  79. class Html5TestHelper extends TestHtmlHelper {
  80. /**
  81. * Minimized
  82. *
  83. * @var array
  84. */
  85. protected $_minimizedAttributes = array('require', 'checked');
  86. /**
  87. * Allow compact use in HTML
  88. *
  89. * @var string
  90. */
  91. protected $_minimizedAttributeFormat = '%s';
  92. /**
  93. * Test to attribute format
  94. *
  95. * @var string
  96. */
  97. protected $_attributeFormat = 'data-%s="%s"';
  98. }
  99. /**
  100. * HtmlHelperTest class
  101. *
  102. * @package Cake.Test.Case.View.Helper
  103. */
  104. class HtmlHelperTest extends CakeTestCase {
  105. /**
  106. * Regexp for CDATA start block
  107. *
  108. * @var string
  109. */
  110. public $cDataStart = 'preg:/^\/\/<!\[CDATA\[[\n\r]*/';
  111. /**
  112. * Regexp for CDATA end block
  113. *
  114. * @var string
  115. */
  116. public $cDataEnd = 'preg:/[^\]]*\]\]\>[\s\r\n]*/';
  117. /**
  118. * html property
  119. *
  120. * @var object
  121. */
  122. public $Html = null;
  123. /**
  124. * setUp method
  125. *
  126. * @return void
  127. */
  128. public function setUp() {
  129. parent::setUp();
  130. $this->View = $this->getMock('View', array('addScript'), array(new TheHtmlTestController()));
  131. $this->Html = new TestHtmlHelper($this->View);
  132. $this->Html->request = new CakeRequest(null, false);
  133. $this->Html->request->webroot = '';
  134. Configure::write('Asset.timestamp', false);
  135. }
  136. /**
  137. * tearDown method
  138. *
  139. * @return void
  140. */
  141. public function tearDown() {
  142. parent::tearDown();
  143. unset($this->Html, $this->View);
  144. }
  145. /**
  146. * testDocType method
  147. *
  148. * @return void
  149. */
  150. public function testDocType() {
  151. $result = $this->Html->docType();
  152. $expected = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
  153. $this->assertEqual($expected, $result);
  154. $result = $this->Html->docType('html4-strict');
  155. $expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">';
  156. $this->assertEqual($expected, $result);
  157. $this->assertNull($this->Html->docType('non-existing-doctype'));
  158. }
  159. /**
  160. * testLink method
  161. *
  162. * @return void
  163. */
  164. public function testLink() {
  165. $this->Html->request->webroot = '';
  166. $result = $this->Html->link('/home');
  167. $expected = array('a' => array('href' => '/home'), 'preg:/\/home/', '/a');
  168. $this->assertTags($result, $expected);
  169. $result = $this->Html->link('Posts', array('controller' => 'posts', 'action' => 'index', 'full_base' => true));
  170. $expected = array('a' => array('href' => FULL_BASE_URL . '/posts'), 'Posts', '/a');
  171. $this->assertTags($result, $expected);
  172. $result = $this->Html->link('Home', '/home', array('confirm' => 'Are you sure you want to do this?'));
  173. $expected = array(
  174. 'a' => array('href' => '/home', 'onclick' => 'return confirm(&#039;Are you sure you want to do this?&#039;);'),
  175. 'Home',
  176. '/a'
  177. );
  178. $this->assertTags($result, $expected);
  179. $result = $this->Html->link('Home', '/home', array('default' => false));
  180. $expected = array(
  181. 'a' => array('href' => '/home', 'onclick' => 'event.returnValue = false; return false;'),
  182. 'Home',
  183. '/a'
  184. );
  185. $this->assertTags($result, $expected);
  186. $result = $this->Html->link('Home', '/home', array('default' => false, 'onclick' => 'someFunction();'));
  187. $expected = array(
  188. 'a' => array('href' => '/home', 'onclick' => 'someFunction(); event.returnValue = false; return false;'),
  189. 'Home',
  190. '/a'
  191. );
  192. $this->assertTags($result, $expected);
  193. $result = $this->Html->link('Next >', '#');
  194. $expected = array(
  195. 'a' => array('href' => '#'),
  196. 'Next &gt;',
  197. '/a'
  198. );
  199. $this->assertTags($result, $expected);
  200. $result = $this->Html->link('Next >', '#', array('escape' => true));
  201. $expected = array(
  202. 'a' => array('href' => '#'),
  203. 'Next &gt;',
  204. '/a'
  205. );
  206. $this->assertTags($result, $expected);
  207. $result = $this->Html->link('Next >', '#', array('escape' => 'utf-8'));
  208. $expected = array(
  209. 'a' => array('href' => '#'),
  210. 'Next &gt;',
  211. '/a'
  212. );
  213. $this->assertTags($result, $expected);
  214. $result = $this->Html->link('Next >', '#', array('escape' => false));
  215. $expected = array(
  216. 'a' => array('href' => '#'),
  217. 'Next >',
  218. '/a'
  219. );
  220. $this->assertTags($result, $expected);
  221. $result = $this->Html->link('Next >', '#', array(
  222. 'title' => 'to escape &#8230; or not escape?',
  223. 'escape' => false
  224. ));
  225. $expected = array(
  226. 'a' => array('href' => '#', 'title' => 'to escape &#8230; or not escape?'),
  227. 'Next >',
  228. '/a'
  229. );
  230. $this->assertTags($result, $expected);
  231. $result = $this->Html->link('Next >', '#', array(
  232. 'title' => 'to escape &#8230; or not escape?',
  233. 'escape' => true
  234. ));
  235. $expected = array(
  236. 'a' => array('href' => '#', 'title' => 'to escape &amp;#8230; or not escape?'),
  237. 'Next &gt;',
  238. '/a'
  239. );
  240. $this->assertTags($result, $expected);
  241. $result = $this->Html->link('Original size', array(
  242. 'controller' => 'images', 'action' => 'view', 3, '?' => array('height' => 100, 'width' => 200)
  243. ));
  244. $expected = array(
  245. 'a' => array('href' => '/images/view/3?height=100&amp;width=200'),
  246. 'Original size',
  247. '/a'
  248. );
  249. $this->assertTags($result, $expected);
  250. Configure::write('Asset.timestamp', false);
  251. $result = $this->Html->link($this->Html->image('test.gif'), '#', array('escape' => false));
  252. $expected = array(
  253. 'a' => array('href' => '#'),
  254. 'img' => array('src' => 'img/test.gif', 'alt' => ''),
  255. '/a'
  256. );
  257. $this->assertTags($result, $expected);
  258. $result = $this->Html->image('test.gif', array('url' => '#'));
  259. $expected = array(
  260. 'a' => array('href' => '#'),
  261. 'img' => array('src' => 'img/test.gif', 'alt' => ''),
  262. '/a'
  263. );
  264. $this->assertTags($result, $expected);
  265. Configure::write('Asset.timestamp', 'force');
  266. $result = $this->Html->link($this->Html->image('../favicon.ico'), '#', array('escape' => false));
  267. $expected = array(
  268. 'a' => array('href' => '#'),
  269. 'img' => array('src' => 'preg:/img\/..\/favicon\.ico\?\d*/', 'alt' => ''),
  270. '/a'
  271. );
  272. $this->assertTags($result, $expected);
  273. $result = $this->Html->image('../favicon.ico', array('url' => '#'));
  274. $expected = array(
  275. 'a' => array('href' => '#'),
  276. 'img' => array('src' => 'preg:/img\/..\/favicon\.ico\?\d*/', 'alt' => ''),
  277. '/a'
  278. );
  279. $this->assertTags($result, $expected);
  280. }
  281. /**
  282. * testImageTag method
  283. *
  284. * @return void
  285. */
  286. public function testImageTag() {
  287. $this->Html->request->webroot = '';
  288. $result = $this->Html->image('test.gif');
  289. $this->assertTags($result, array('img' => array('src' => 'img/test.gif', 'alt' => '')));
  290. $result = $this->Html->image('http://google.com/logo.gif');
  291. $this->assertTags($result, array('img' => array('src' => 'http://google.com/logo.gif', 'alt' => '')));
  292. $result = $this->Html->image(array('controller' => 'test', 'action' => 'view', 1, 'ext' => 'gif'));
  293. $this->assertTags($result, array('img' => array('src' => '/test/view/1.gif', 'alt' => '')));
  294. $result = $this->Html->image('/test/view/1.gif');
  295. $this->assertTags($result, array('img' => array('src' => '/test/view/1.gif', 'alt' => '')));
  296. }
  297. /**
  298. * test image() with Asset.timestamp
  299. *
  300. * @return void
  301. */
  302. public function testImageWithTimestampping() {
  303. Configure::write('Asset.timestamp', 'force');
  304. $this->Html->request->webroot = '/';
  305. $result = $this->Html->image('cake.icon.png');
  306. $this->assertTags($result, array('img' => array('src' => 'preg:/\/img\/cake\.icon\.png\?\d+/', 'alt' => '')));
  307. Configure::write('debug', 0);
  308. Configure::write('Asset.timestamp', 'force');
  309. $result = $this->Html->image('cake.icon.png');
  310. $this->assertTags($result, array('img' => array('src' => 'preg:/\/img\/cake\.icon\.png\?\d+/', 'alt' => '')));
  311. $this->Html->request->webroot = '/testing/longer/';
  312. $result = $this->Html->image('cake.icon.png');
  313. $expected = array(
  314. 'img' => array('src' => 'preg:/\/testing\/longer\/img\/cake\.icon\.png\?[0-9]+/', 'alt' => '')
  315. );
  316. $this->assertTags($result, $expected);
  317. }
  318. /**
  319. * Tests creation of an image tag using a theme and asset timestamping
  320. *
  321. * @return void
  322. */
  323. public function testImageTagWithTheme() {
  324. $this->skipIf(!is_writable(WWW_ROOT . 'theme'), 'Cannot write to webroot/theme.');
  325. App::uses('File', 'Utility');
  326. $testfile = WWW_ROOT . 'theme' . DS . 'test_theme' . DS . 'img' . DS . '__cake_test_image.gif';
  327. $File = new File($testfile, true);
  328. App::build(array(
  329. 'views' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS)
  330. ));
  331. Configure::write('Asset.timestamp', true);
  332. Configure::write('debug', 1);
  333. $this->Html->request->webroot = '/';
  334. $this->Html->theme = 'test_theme';
  335. $result = $this->Html->image('__cake_test_image.gif');
  336. $this->assertTags($result, array(
  337. 'img' => array(
  338. 'src' => 'preg:/\/theme\/test_theme\/img\/__cake_test_image\.gif\?\d+/',
  339. 'alt' => ''
  340. )));
  341. $this->Html->request->webroot = '/testing/';
  342. $result = $this->Html->image('__cake_test_image.gif');
  343. $this->assertTags($result, array(
  344. 'img' => array(
  345. 'src' => 'preg:/\/testing\/theme\/test_theme\/img\/__cake_test_image\.gif\?\d+/',
  346. 'alt' => ''
  347. )));
  348. $dir = new Folder(WWW_ROOT . 'theme' . DS . 'test_theme');
  349. $dir->delete();
  350. }
  351. /**
  352. * test theme assets in main webroot path
  353. *
  354. * @return void
  355. */
  356. public function testThemeAssetsInMainWebrootPath() {
  357. App::build(array(
  358. 'views' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS)
  359. ));
  360. $webRoot = Configure::read('App.www_root');
  361. Configure::write('App.www_root', CAKE . 'Test' . DS . 'test_app' . DS . 'webroot' . DS);
  362. $this->Html->theme = 'test_theme';
  363. $result = $this->Html->css('webroot_test');
  364. $expected = array(
  365. 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => 'preg:/.*theme\/test_theme\/css\/webroot_test\.css/')
  366. );
  367. $this->assertTags($result, $expected);
  368. $this->Html->theme = 'test_theme';
  369. $result = $this->Html->css('theme_webroot');
  370. $expected = array(
  371. 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => 'preg:/.*theme\/test_theme\/css\/theme_webroot\.css/')
  372. );
  373. $this->assertTags($result, $expected);
  374. Configure::write('App.www_root', $webRoot);
  375. }
  376. /**
  377. * testStyle method
  378. *
  379. * @return void
  380. */
  381. public function testStyle() {
  382. $result = $this->Html->style('display: none;');
  383. $this->assertEqual($result, 'display: none;');
  384. $result = $this->Html->style(array('display'=> 'none', 'margin'=>'10px'));
  385. $expected = 'display:none; margin:10px;';
  386. $this->assertPattern('/^display\s*:\s*none\s*;\s*margin\s*:\s*10px\s*;?$/', $expected);
  387. $result = $this->Html->style(array('display'=> 'none', 'margin'=>'10px'), false);
  388. $lines = explode("\n", $result);
  389. $this->assertPattern('/^\s*display\s*:\s*none\s*;\s*$/', $lines[0]);
  390. $this->assertPattern('/^\s*margin\s*:\s*10px\s*;?$/', $lines[1]);
  391. }
  392. /**
  393. * testCssLink method
  394. *
  395. * @return void
  396. */
  397. public function testCssLink() {
  398. Configure::write('Asset.filter.css', false);
  399. $result = $this->Html->css('screen');
  400. $expected = array(
  401. 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => 'preg:/.*css\/screen\.css/')
  402. );
  403. $this->assertTags($result, $expected);
  404. $result = $this->Html->css('screen.css');
  405. $this->assertTags($result, $expected);
  406. $result = $this->Html->css('my.css.library');
  407. $expected['link']['href'] = 'preg:/.*css\/my\.css\.library\.css/';
  408. $this->assertTags($result, $expected);
  409. $result = $this->Html->css('screen.css?1234');
  410. $expected['link']['href'] = 'preg:/.*css\/screen\.css\?1234/';
  411. $this->assertTags($result, $expected);
  412. $result = $this->Html->css('http://whatever.com/screen.css?1234');
  413. $expected['link']['href'] = 'preg:/http:\/\/.*\/screen\.css\?1234/';
  414. $this->assertTags($result, $expected);
  415. Configure::write('Asset.filter.css', 'css.php');
  416. $result = $this->Html->css('cake.generic');
  417. $expected['link']['href'] = 'preg:/.*ccss\/cake\.generic\.css/';
  418. $this->assertTags($result, $expected);
  419. Configure::write('Asset.filter.css', false);
  420. $result = explode("\n", trim($this->Html->css(array('cake.generic', 'vendor.generic'))));
  421. $expected['link']['href'] = 'preg:/.*css\/cake\.generic\.css/';
  422. $this->assertTags($result[0], $expected);
  423. $expected['link']['href'] = 'preg:/.*css\/vendor\.generic\.css/';
  424. $this->assertTags($result[1], $expected);
  425. $this->assertEqual(count($result), 2);
  426. $this->View->expects($this->at(0))->method('addScript')
  427. ->with($this->matchesRegularExpression('/css_in_head.css/'));
  428. $this->View->expects($this->at(1))
  429. ->method('addScript')
  430. ->with($this->matchesRegularExpression('/more_css_in_head.css/'));
  431. $result = $this->Html->css('css_in_head', null, array('inline' => false));
  432. $this->assertNull($result);
  433. $result = $this->Html->css('more_css_in_head', null, array('inline' => false));
  434. $this->assertNull($result);
  435. }
  436. /**
  437. * test use of css() and timestamping
  438. *
  439. * @return void
  440. */
  441. public function testCssTimestamping() {
  442. Configure::write('debug', 2);
  443. Configure::write('Asset.timestamp', true);
  444. $expected = array(
  445. 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => '')
  446. );
  447. $result = $this->Html->css('cake.generic');
  448. $expected['link']['href'] = 'preg:/.*css\/cake\.generic\.css\?[0-9]+/';
  449. $this->assertTags($result, $expected);
  450. Configure::write('debug', 0);
  451. $result = $this->Html->css('cake.generic');
  452. $expected['link']['href'] = 'preg:/.*css\/cake\.generic\.css/';
  453. $this->assertTags($result, $expected);
  454. Configure::write('Asset.timestamp', 'force');
  455. $result = $this->Html->css('cake.generic');
  456. $expected['link']['href'] = 'preg:/.*css\/cake\.generic\.css\?[0-9]+/';
  457. $this->assertTags($result, $expected);
  458. $this->Html->request->webroot = '/testing/';
  459. $result = $this->Html->css('cake.generic');
  460. $expected['link']['href'] = 'preg:/\/testing\/css\/cake\.generic\.css\?[0-9]+/';
  461. $this->assertTags($result, $expected);
  462. $this->Html->request->webroot = '/testing/longer/';
  463. $result = $this->Html->css('cake.generic');
  464. $expected['link']['href'] = 'preg:/\/testing\/longer\/css\/cake\.generic\.css\?[0-9]+/';
  465. $this->assertTags($result, $expected);
  466. }
  467. /**
  468. * test timestamp enforcement for script tags.
  469. *
  470. * @return void
  471. */
  472. public function testScriptTimestamping() {
  473. $this->skipIf(!is_writable(JS), 'webroot/js is not Writable, timestamp testing has been skipped.');
  474. Configure::write('debug', 2);
  475. Configure::write('Asset.timestamp', true);
  476. touch(WWW_ROOT . 'js' . DS. '__cake_js_test.js');
  477. $timestamp = substr(strtotime('now'), 0, 8);
  478. $result = $this->Html->script('__cake_js_test', array('inline' => true, 'once' => false));
  479. $this->assertPattern('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s');
  480. Configure::write('debug', 0);
  481. Configure::write('Asset.timestamp', 'force');
  482. $result = $this->Html->script('__cake_js_test', array('inline' => true, 'once' => false));
  483. $this->assertPattern('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s');
  484. unlink(WWW_ROOT . 'js' . DS. '__cake_js_test.js');
  485. Configure::write('Asset.timestamp', false);
  486. }
  487. /**
  488. * test that scripts added with uses() are only ever included once.
  489. * test script tag generation
  490. *
  491. * @return void
  492. */
  493. public function testScript() {
  494. $result = $this->Html->script('foo');
  495. $expected = array(
  496. 'script' => array('type' => 'text/javascript', 'src' => 'js/foo.js')
  497. );
  498. $this->assertTags($result, $expected);
  499. $result = $this->Html->script(array('foobar', 'bar'));
  500. $expected = array(
  501. array('script' => array('type' => 'text/javascript', 'src' => 'js/foobar.js')),
  502. '/script',
  503. array('script' => array('type' => 'text/javascript', 'src' => 'js/bar.js')),
  504. '/script',
  505. );
  506. $this->assertTags($result, $expected);
  507. $result = $this->Html->script('jquery-1.3');
  508. $expected = array(
  509. 'script' => array('type' => 'text/javascript', 'src' => 'js/jquery-1.3.js')
  510. );
  511. $this->assertTags($result, $expected);
  512. $result = $this->Html->script('test.json');
  513. $expected = array(
  514. 'script' => array('type' => 'text/javascript', 'src' => 'js/test.json.js')
  515. );
  516. $this->assertTags($result, $expected);
  517. $result = $this->Html->script('http://example.com/test.json');
  518. $expected = array(
  519. 'script' => array('type' => 'text/javascript', 'src' => 'http://example.com/test.json')
  520. );
  521. $this->assertTags($result, $expected);
  522. $result = $this->Html->script('/plugin/js/jquery-1.3.2.js?someparam=foo');
  523. $expected = array(
  524. 'script' => array('type' => 'text/javascript', 'src' => '/plugin/js/jquery-1.3.2.js?someparam=foo')
  525. );
  526. $this->assertTags($result, $expected);
  527. $result = $this->Html->script('test.json.js?foo=bar');
  528. $expected = array(
  529. 'script' => array('type' => 'text/javascript', 'src' => 'js/test.json.js?foo=bar')
  530. );
  531. $this->assertTags($result, $expected);
  532. $result = $this->Html->script('foo');
  533. $this->assertNull($result, 'Script returned upon duplicate inclusion %s');
  534. $result = $this->Html->script(array('foo', 'bar', 'baz'));
  535. $this->assertNoPattern('/foo.js/', $result);
  536. $result = $this->Html->script('foo', array('inline' => true, 'once' => false));
  537. $this->assertNotNull($result);
  538. $result = $this->Html->script('jquery-1.3.2', array('defer' => true, 'encoding' => 'utf-8'));
  539. $expected = array(
  540. 'script' => array('type' => 'text/javascript', 'src' => 'js/jquery-1.3.2.js', 'defer' => 'defer', 'encoding' => 'utf-8')
  541. );
  542. $this->assertTags($result, $expected);
  543. $this->View->expects($this->any())->method('addScript')
  544. ->with($this->matchesRegularExpression('/script_in_head.js/'));
  545. $result = $this->Html->script('script_in_head', array('inline' => false));
  546. $this->assertNull($result);
  547. }
  548. /**
  549. * test a script file in the webroot/theme dir.
  550. *
  551. * @return void
  552. */
  553. public function testScriptInTheme() {
  554. $this->skipIf(!is_writable(WWW_ROOT . 'theme'), 'Cannot write to webroot/theme.');
  555. App::uses('File', 'Utility');
  556. $testfile = WWW_ROOT . 'theme' . DS . 'test_theme' . DS . 'js' . DS . '__test_js.js';
  557. $File = new File($testfile, true);
  558. App::build(array(
  559. 'views' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS)
  560. ));
  561. $this->Html->webroot = '/';
  562. $this->Html->theme = 'test_theme';
  563. $result = $this->Html->script('__test_js.js');
  564. $expected = array(
  565. 'script' => array('src' => '/theme/test_theme/js/__test_js.js', 'type' => 'text/javascript')
  566. );
  567. $this->assertTags($result, $expected);
  568. $Folder = new Folder(WWW_ROOT . 'theme' . DS . 'test_theme');
  569. $Folder->delete();
  570. App::build();
  571. }
  572. /**
  573. * test Script block generation
  574. *
  575. * @return void
  576. */
  577. public function testScriptBlock() {
  578. $result = $this->Html->scriptBlock('window.foo = 2;');
  579. $expected = array(
  580. 'script' => array('type' => 'text/javascript'),
  581. $this->cDataStart,
  582. 'window.foo = 2;',
  583. $this->cDataEnd,
  584. '/script',
  585. );
  586. $this->assertTags($result, $expected);
  587. $result = $this->Html->scriptBlock('window.foo = 2;', array('safe' => false));
  588. $expected = array(
  589. 'script' => array('type' => 'text/javascript'),
  590. 'window.foo = 2;',
  591. '/script',
  592. );
  593. $this->assertTags($result, $expected);
  594. $result = $this->Html->scriptBlock('window.foo = 2;', array('safe' => true));
  595. $expected = array(
  596. 'script' => array('type' => 'text/javascript'),
  597. $this->cDataStart,
  598. 'window.foo = 2;',
  599. $this->cDataEnd,
  600. '/script',
  601. );
  602. $this->assertTags($result, $expected);
  603. $this->View->expects($this->any())->method('addScript')
  604. ->with($this->matchesRegularExpression('/window\.foo\s\=\s2;/'));
  605. $result = $this->Html->scriptBlock('window.foo = 2;', array('inline' => false));
  606. $this->assertNull($result);
  607. $result = $this->Html->scriptBlock('window.foo = 2;', array('safe' => false, 'encoding' => 'utf-8'));
  608. $expected = array(
  609. 'script' => array('type' => 'text/javascript', 'encoding' => 'utf-8'),
  610. 'window.foo = 2;',
  611. '/script',
  612. );
  613. $this->assertTags($result, $expected);
  614. }
  615. /**
  616. * test script tag output buffering when using scriptStart() and scriptEnd();
  617. *
  618. * @return void
  619. */
  620. public function testScriptStartAndScriptEnd() {
  621. $result = $this->Html->scriptStart(array('safe' => true));
  622. $this->assertNull($result);
  623. echo 'this is some javascript';
  624. $result = $this->Html->scriptEnd();
  625. $expected = array(
  626. 'script' => array('type' => 'text/javascript'),
  627. $this->cDataStart,
  628. 'this is some javascript',
  629. $this->cDataEnd,
  630. '/script'
  631. );
  632. $this->assertTags($result, $expected);
  633. $result = $this->Html->scriptStart(array('safe' => false));
  634. $this->assertNull($result);
  635. echo 'this is some javascript';
  636. $result = $this->Html->scriptEnd();
  637. $expected = array(
  638. 'script' => array('type' => 'text/javascript'),
  639. 'this is some javascript',
  640. '/script'
  641. );
  642. $this->assertTags($result, $expected);
  643. $this->View->expects($this->once())->method('addScript');
  644. $result = $this->Html->scriptStart(array('safe' => false, 'inline' => false));
  645. $this->assertNull($result);
  646. echo 'this is some javascript';
  647. $result = $this->Html->scriptEnd();
  648. $this->assertNull($result);
  649. }
  650. /**
  651. * testCharsetTag method
  652. *
  653. * @return void
  654. */
  655. public function testCharsetTag() {
  656. Configure::write('App.encoding', null);
  657. $result = $this->Html->charset();
  658. $this->assertTags($result, array('meta' => array('http-equiv' => 'Content-Type', 'content' => 'text/html; charset=utf-8')));
  659. Configure::write('App.encoding', 'ISO-8859-1');
  660. $result = $this->Html->charset();
  661. $this->assertTags($result, array('meta' => array('http-equiv' => 'Content-Type', 'content' => 'text/html; charset=iso-8859-1')));
  662. $result = $this->Html->charset('UTF-7');
  663. $this->assertTags($result, array('meta' => array('http-equiv' => 'Content-Type', 'content' => 'text/html; charset=UTF-7')));
  664. }
  665. /**
  666. * testBreadcrumb method
  667. *
  668. * @return void
  669. */
  670. public function testBreadcrumb() {
  671. $this->assertNull($this->Html->getCrumbs());
  672. $this->Html->addCrumb('First', '#first');
  673. $this->Html->addCrumb('Second', '#second');
  674. $this->Html->addCrumb('Third', '#third');
  675. $result = $this->Html->getCrumbs();
  676. $expected = array(
  677. array('a' => array('href' => '#first')),
  678. 'First',
  679. '/a',
  680. '&raquo;',
  681. array('a' => array('href' => '#second')),
  682. 'Second',
  683. '/a',
  684. '&raquo;',
  685. array('a' => array('href' => '#third')),
  686. 'Third',
  687. '/a',
  688. );
  689. $this->assertTags($result, $expected);
  690. $result = $this->Html->getCrumbs(' &gt; ');
  691. $expected = array(
  692. array('a' => array('href' => '#first')),
  693. 'First',
  694. '/a',
  695. ' &gt; ',
  696. array('a' => array('href' => '#second')),
  697. 'Second',
  698. '/a',
  699. ' &gt; ',
  700. array('a' => array('href' => '#third')),
  701. 'Third',
  702. '/a',
  703. );
  704. $this->assertTags($result, $expected);
  705. $this->assertPattern('/^<a[^<>]+>First<\/a> &gt; <a[^<>]+>Second<\/a> &gt; <a[^<>]+>Third<\/a>$/', $result);
  706. $this->assertPattern('/<a\s+href=["\']+\#first["\']+[^<>]*>First<\/a>/', $result);
  707. $this->assertPattern('/<a\s+href=["\']+\#second["\']+[^<>]*>Second<\/a>/', $result);
  708. $this->assertPattern('/<a\s+href=["\']+\#third["\']+[^<>]*>Third<\/a>/', $result);
  709. $this->assertNoPattern('/<a[^<>]+[^href]=[^<>]*>/', $result);
  710. $this->Html->addCrumb('Fourth', null);
  711. $result = $this->Html->getCrumbs();
  712. $expected = array(
  713. array('a' => array('href' => '#first')),
  714. 'First',
  715. '/a',
  716. '&raquo;',
  717. array('a' => array('href' => '#second')),
  718. 'Second',
  719. '/a',
  720. '&raquo;',
  721. array('a' => array('href' => '#third')),
  722. 'Third',
  723. '/a',
  724. '&raquo;',
  725. 'Fourth'
  726. );
  727. $this->assertTags($result, $expected);
  728. $result = $this->Html->getCrumbs('-', 'Start');
  729. $expected = array(
  730. array('a' => array('href' => '/')),
  731. 'Start',
  732. '/a',
  733. '-',
  734. array('a' => array('href' => '#first')),
  735. 'First',
  736. '/a',
  737. '-',
  738. array('a' => array('href' => '#second')),
  739. 'Second',
  740. '/a',
  741. '-',
  742. array('a' => array('href' => '#third')),
  743. 'Third',
  744. '/a',
  745. '-',
  746. 'Fourth'
  747. );
  748. $this->assertTags($result, $expected);
  749. }
  750. /**
  751. * testNestedList method
  752. *
  753. * @return void
  754. */
  755. public function testNestedList() {
  756. $list = array(
  757. 'Item 1',
  758. 'Item 2' => array(
  759. 'Item 2.1'
  760. ),
  761. 'Item 3',
  762. 'Item 4' => array(
  763. 'Item 4.1',
  764. 'Item 4.2',
  765. 'Item 4.3' => array(
  766. 'Item 4.3.1',
  767. 'Item 4.3.2'
  768. )
  769. ),
  770. 'Item 5' => array(
  771. 'Item 5.1',
  772. 'Item 5.2'
  773. )
  774. );
  775. $result = $this->Html->nestedList($list);
  776. $expected = array(
  777. '<ul',
  778. '<li', 'Item 1', '/li',
  779. '<li', 'Item 2',
  780. '<ul', '<li', 'Item 2.1', '/li', '/ul',
  781. '/li',
  782. '<li', 'Item 3', '/li',
  783. '<li', 'Item 4',
  784. '<ul',
  785. '<li', 'Item 4.1', '/li',
  786. '<li', 'Item 4.2', '/li',
  787. '<li', 'Item 4.3',
  788. '<ul',
  789. '<li', 'Item 4.3.1', '/li',
  790. '<li', 'Item 4.3.2', '/li',
  791. '/ul',
  792. '/li',
  793. '/ul',
  794. '/li',
  795. '<li', 'Item 5',
  796. '<ul',
  797. '<li', 'Item 5.1', '/li',
  798. '<li', 'Item 5.2', '/li',
  799. '/ul',
  800. '/li',
  801. '/ul'
  802. );
  803. $this->assertTags($result, $expected);
  804. $result = $this->Html->nestedList($list, null);
  805. $expected = array(
  806. '<ul',
  807. '<li', 'Item 1', '/li',
  808. '<li', 'Item 2',
  809. '<ul', '<li', 'Item 2.1', '/li', '/ul',
  810. '/li',
  811. '<li', 'Item 3', '/li',
  812. '<li', 'Item 4',
  813. '<ul',
  814. '<li', 'Item 4.1', '/li',
  815. '<li', 'Item 4.2', '/li',
  816. '<li', 'Item 4.3',
  817. '<ul',
  818. '<li', 'Item 4.3.1', '/li',
  819. '<li', 'Item 4.3.2', '/li',
  820. '/ul',
  821. '/li',
  822. '/ul',
  823. '/li',
  824. '<li', 'Item 5',
  825. '<ul',
  826. '<li', 'Item 5.1', '/li',
  827. '<li', 'Item 5.2', '/li',
  828. '/ul',
  829. '/li',
  830. '/ul'
  831. );
  832. $this->assertTags($result, $expected);
  833. $result = $this->Html->nestedList($list, array(), array(), 'ol');
  834. $expected = array(
  835. '<ol',
  836. '<li', 'Item 1', '/li',
  837. '<li', 'Item 2',
  838. '<ol', '<li', 'Item 2.1', '/li', '/ol',
  839. '/li',
  840. '<li', 'Item 3', '/li',
  841. '<li', 'Item 4',
  842. '<ol',
  843. '<li', 'Item 4.1', '/li',
  844. '<li', 'Item 4.2', '/li',
  845. '<li', 'Item 4.3',
  846. '<ol',
  847. '<li', 'Item 4.3.1', '/li',
  848. '<li', 'Item 4.3.2', '/li',
  849. '/ol',
  850. '/li',
  851. '/ol',
  852. '/li',
  853. '<li', 'Item 5',
  854. '<ol',
  855. '<li', 'Item 5.1', '/li',
  856. '<li', 'Item 5.2', '/li',
  857. '/ol',
  858. '/li',
  859. '/ol'
  860. );
  861. $this->assertTags($result, $expected);
  862. $result = $this->Html->nestedList($list, 'ol');
  863. $expected = array(
  864. '<ol',
  865. '<li', 'Item 1', '/li',
  866. '<li', 'Item 2',
  867. '<ol', '<li', 'Item 2.1', '/li', '/ol',
  868. '/li',
  869. '<li', 'Item 3', '/li',
  870. '<li', 'Item 4',
  871. '<ol',
  872. '<li', 'Item 4.1', '/li',
  873. '<li', 'Item 4.2', '/li',
  874. '<li', 'Item 4.3',
  875. '<ol',
  876. '<li', 'Item 4.3.1', '/li',
  877. '<li', 'Item 4.3.2', '/li',
  878. '/ol',
  879. '/li',
  880. '/ol',
  881. '/li',
  882. '<li', 'Item 5',
  883. '<ol',
  884. '<li', 'Item 5.1', '/li',
  885. '<li', 'Item 5.2', '/li',
  886. '/ol',
  887. '/li',
  888. '/ol'
  889. );
  890. $this->assertTags($result, $expected);
  891. $result = $this->Html->nestedList($list, array('class'=>'list'));
  892. $expected = array(
  893. array('ul' => array('class' => 'list')),
  894. '<li', 'Item 1', '/li',
  895. '<li', 'Item 2',
  896. array('ul' => array('class' => 'list')), '<li', 'Item 2.1', '/li', '/ul',
  897. '/li',
  898. '<li', 'Item 3', '/li',
  899. '<li', 'Item 4',
  900. array('ul' => array('class' => 'list')),
  901. '<li', 'Item 4.1', '/li',
  902. '<li', 'Item 4.2', '/li',
  903. '<li', 'Item 4.3',
  904. array('ul' => array('class' => 'list')),
  905. '<li', 'Item 4.3.1', '/li',
  906. '<li', 'Item 4.3.2', '/li',
  907. '/ul',
  908. '/li',
  909. '/ul',
  910. '/li',
  911. '<li', 'Item 5',
  912. array('ul' => array('class' => 'list')),
  913. '<li', 'Item 5.1', '/li',
  914. '<li', 'Item 5.2', '/li',
  915. '/ul',
  916. '/li',
  917. '/ul'
  918. );
  919. $this->assertTags($result, $expected);
  920. $result = $this->Html->nestedList($list, array(), array('class' => 'item'));
  921. $expected = array(
  922. '<ul',
  923. array('li' => array('class' => 'item')), 'Item 1', '/li',
  924. array('li' => array('class' => 'item')), 'Item 2',
  925. '<ul', array('li' => array('class' => 'item')), 'Item 2.1', '/li', '/ul',
  926. '/li',
  927. array('li' => array('class' => 'item')), 'Item 3', '/li',
  928. array('li' => array('class' => 'item')), 'Item 4',
  929. '<ul',
  930. array('li' => array('class' => 'item')), 'Item 4.1', '/li',
  931. array('li' => array('class' => 'item')), 'Item 4.2', '/li',
  932. array('li' => array('class' => 'item')), 'Item 4.3',
  933. '<ul',
  934. array('li' => array('class' => 'item')), 'Item 4.3.1', '/li',
  935. array('li' => array('class' => 'item')), 'Item 4.3.2', '/li',
  936. '/ul',
  937. '/li',
  938. '/ul',
  939. '/li',
  940. array('li' => array('class' => 'item')), 'Item 5',
  941. '<ul',
  942. array('li' => array('class' => 'item')), 'Item 5.1', '/li',
  943. array('li' => array('class' => 'item')), 'Item 5.2', '/li',
  944. '/ul',
  945. '/li',
  946. '/ul'
  947. );
  948. $this->assertTags($result, $expected);
  949. $result = $this->Html->nestedList($list, array(), array('even' => 'even', 'odd' => 'odd'));
  950. $expected = array(
  951. '<ul',
  952. array('li' => array('class' => 'odd')), 'Item 1', '/li',
  953. array('li' => array('class' => 'even')), 'Item 2',
  954. '<ul', array('li' => array('class' => 'odd')), 'Item 2.1', '/li', '/ul',
  955. '/li',
  956. array('li' => array('class' => 'odd')), 'Item 3', '/li',
  957. array('li' => array('class' => 'even')), 'Item 4',
  958. '<ul',
  959. array('li' => array('class' => 'odd')), 'Item 4.1', '/li',
  960. array('li' => array('class' => 'even')), 'Item 4.2', '/li',
  961. array('li' => array('class' => 'odd')), 'Item 4.3',
  962. '<ul',
  963. array('li' => array('class' => 'odd')), 'Item 4.3.1', '/li',
  964. array('li' => array('class' => 'even')), 'Item 4.3.2', '/li',
  965. '/ul',
  966. '/li',
  967. '/ul',
  968. '/li',
  969. array('li' => array('class' => 'odd')), 'Item 5',
  970. '<ul',
  971. array('li' => array('class' => 'odd')), 'Item 5.1', '/li',
  972. array('li' => array('class' => 'even')), 'Item 5.2', '/li',
  973. '/ul',
  974. '/li',
  975. '/ul'
  976. );
  977. $this->assertTags($result, $expected);
  978. $result = $this->Html->nestedList($list, array('class'=>'list'), array('class' => 'item'));
  979. $expected = array(
  980. array('ul' => array('class' => 'list')),
  981. array('li' => array('class' => 'item')), 'Item 1', '/li',
  982. array('li' => array('class' => 'item')), 'Item 2',
  983. array('ul' => array('class' => 'list')), array('li' => array('class' => 'item')), 'Item 2.1', '/li', '/ul',
  984. '/li',
  985. array('li' => array('class' => 'item')), 'Item 3', '/li',
  986. array('li' => array('class' => 'item')), 'Item 4',
  987. array('ul' => array('class' => 'list')),
  988. array('li' => array('class' => 'item')), 'Item 4.1', '/li',
  989. array('li' => array('class' => 'item')), 'Item 4.2', '/li',
  990. array('li' => array('class' => 'item')), 'Item 4.3',
  991. array('ul' => array('class' => 'list')),
  992. array('li' => array('class' => 'item')), 'Item 4.3.1', '/li',
  993. array('li' => array('class' => 'item')), 'Item 4.3.2', '/li',
  994. '/ul',
  995. '/li',
  996. '/ul',
  997. '/li',
  998. array('li' => array('class' => 'item')), 'Item 5',
  999. array('ul' => array('class' => 'list')),
  1000. array('li' => array('class' => 'item')), 'Item 5.1', '/li',
  1001. array('li' => array('class' => 'item')), 'Item 5.2', '/li',
  1002. '/ul',
  1003. '/li',
  1004. '/ul'
  1005. );
  1006. $this->assertTags($result, $expected);
  1007. }
  1008. /**
  1009. * testMeta method
  1010. *
  1011. * @return void
  1012. */
  1013. public function testMeta() {
  1014. $result = $this->Html->meta('this is an rss feed', array('controller' => 'posts', 'ext' => 'rss'));
  1015. $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.rss/', 'type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => 'this is an rss feed')));
  1016. $result = $this->Html->meta('rss', array('controller' => 'posts', 'ext' => 'rss'), array('title' => 'this is an rss feed'));
  1017. $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.rss/', 'type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => 'this is an rss feed')));
  1018. $result = $this->Html->meta('atom', array('controller' => 'posts', 'ext' => 'xml'));
  1019. $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.xml/', 'type' => 'application/atom+xml', 'title' => 'atom')));
  1020. $result = $this->Html->meta('non-existing');
  1021. $this->assertTags($result, array('<meta'));
  1022. $result = $this->Html->meta('non-existing', '/posts.xpp');
  1023. $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.xpp/', 'type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => 'non-existing')));
  1024. $result = $this->Html->meta('non-existing', '/posts.xpp', array('type' => 'atom'));
  1025. $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.xpp/', 'type' => 'application/atom+xml', 'title' => 'non-existing')));
  1026. $result = $this->Html->meta('atom', array('controller' => 'posts', 'ext' => 'xml'), array('link' => '/articles.rss'));
  1027. $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/articles\.rss/', 'type' => 'application/atom+xml', 'title' => 'atom')));
  1028. $result = $this->Html->meta(array('link' => 'favicon.ico', 'rel' => 'icon'));
  1029. $expected = array(
  1030. 'link' => array('href' => 'preg:/.*favicon\.ico/', 'rel' => 'icon'),
  1031. array('link' => array('href' => 'preg:/.*favicon\.ico/', 'rel' => 'shortcut icon'))
  1032. );
  1033. $this->assertTags($result, $expected);
  1034. $result = $this->Html->meta('icon', 'favicon.ico');
  1035. $expected = array(
  1036. 'link' => array('href' => 'preg:/.*favicon\.ico/', 'type' => 'image/x-icon', 'rel' => 'icon'),
  1037. array('link' => array('href' => 'preg:/.*favicon\.ico/', 'type' => 'image/x-icon', 'rel' => 'shortcut icon'))
  1038. );
  1039. $this->assertTags($result, $expected);
  1040. $result = $this->Html->meta('icon');
  1041. $expected = array(
  1042. 'link' => array('href' => 'preg:/.*favicon\.ico/', 'type' => 'image/x-icon', 'rel' => 'icon'),
  1043. array('link' => array('href' => 'preg:/.*favicon\.ico/', 'type' => 'image/x-icon', 'rel' => 'shortcut icon'))
  1044. );
  1045. $this->assertTags($result, $expected);
  1046. $result = $this->Html->meta('keywords', 'these, are, some, meta, keywords');
  1047. $this->assertTags($result, array('meta' => array('name' => 'keywords', 'content' => 'these, are, some, meta, keywords')));
  1048. $this->assertPattern('/\s+\/>$/', $result);
  1049. $result = $this->Html->meta('description', 'this is the meta description');
  1050. $this->assertTags($result, array('meta' => array('name' => 'description', 'content' => 'this is the meta description')));
  1051. $result = $this->Html->meta(array('name' => 'ROBOTS', 'content' => 'ALL'));
  1052. $this->assertTags($result, array('meta' => array('name' => 'ROBOTS', 'content' => 'ALL')));
  1053. $this->View->expects($this->any())->method('addScript')
  1054. ->with($this->matchesRegularExpression('/^<meta/'));
  1055. $result = $this->Html->meta(array('name' => 'ROBOTS', 'content' => 'ALL'), null, array('inline' => false));
  1056. $this->assertNull($result);
  1057. }
  1058. /**
  1059. * testTableHeaders method
  1060. *
  1061. * @return void
  1062. */
  1063. public function testTableHeaders() {
  1064. $result = $this->Html->tableHeaders(array('ID', 'Name', 'Date'));
  1065. $expected = array('<tr', '<th', 'ID', '/th', '<th', 'Name', '/th', '<th', 'Date', '/th', '/tr');
  1066. $this->assertTags($result, $expected);
  1067. }
  1068. /**
  1069. * testTableCells method
  1070. *
  1071. * @return void
  1072. */
  1073. public function testTableCells() {
  1074. $tr = array(
  1075. 'td content 1',
  1076. array('td content 2', array("width" => "100px")),
  1077. array('td content 3', "width=100px")
  1078. );
  1079. $result = $this->Html->tableCells($tr);
  1080. $expected = array(
  1081. '<tr',
  1082. '<td', 'td content 1', '/td',
  1083. array('td' => array('width' => '100px')), 'td content 2', '/td',
  1084. array('td' => array('width' => 'preg:/100px/')), 'td content 3', '/td',
  1085. '/tr'
  1086. );
  1087. $this->assertTags($result, $expected);
  1088. $tr = array('td content 1', 'td content 2', 'td content 3');
  1089. $result = $this->Html->tableCells($tr, null, null, true);
  1090. $expected = array(
  1091. '<tr',
  1092. array('td' => array('class' => 'column-1')), 'td content 1', '/td',
  1093. array('td' => array('class' => 'column-2')), 'td content 2', '/td',
  1094. array('td' => array('class' => 'column-3')), 'td content 3', '/td',
  1095. '/tr'
  1096. );
  1097. $this->assertTags($result, $expected);
  1098. $tr = array('td content 1', 'td content 2', 'td content 3');
  1099. $result = $this->Html->tableCells($tr, true);
  1100. $expected = array(
  1101. '<tr',
  1102. array('td' => array('class' => 'column-1')), 'td content 1', '/td',
  1103. array('td' => array('class' => 'column-2')), 'td content 2', '/td',
  1104. array('td' => array('class' => 'column-3')), 'td content 3', '/td',
  1105. '/tr'
  1106. );
  1107. $this->assertTags($result, $expected);
  1108. $tr = array(
  1109. array('td content 1', 'td content 2', 'td content 3'),
  1110. array('td content 1', 'td content 2', 'td content 3'),
  1111. array('td content 1', 'td content 2', 'td content 3')
  1112. );
  1113. $result = $this->Html->tableCells($tr, array('class' => 'odd'), array('class' => 'even'));
  1114. $expected = "<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>";
  1115. $this->assertEqual($expected, $result);
  1116. $tr = array(
  1117. array('td content 1', 'td content 2', 'td content 3'),
  1118. array('td content 1', 'td content 2', 'td content 3'),
  1119. array('td content 1', 'td content 2', 'td content 3'),
  1120. array('td content 1', 'td content 2', 'td content 3')
  1121. );
  1122. $result = $this->Html->tableCells($tr, array('class' => 'odd'), array('class' => 'even'));
  1123. $expected = "<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>";
  1124. $this->assertEqual($expected, $result);
  1125. $tr = array(
  1126. array('td content 1', 'td content 2', 'td content 3'),
  1127. array('td content 1', 'td content 2', 'td content 3'),
  1128. array('td content 1', 'td content 2', 'td content 3')
  1129. );
  1130. $this->Html->tableCells($tr, array('class' => 'odd'), array('class' => 'even'));
  1131. $result = $this->Html->tableCells($tr, array('class' => 'odd'), array('class' => 'even'), false, false);
  1132. $expected = "<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>";
  1133. $this->assertEqual($expected, $result);
  1134. }
  1135. /**
  1136. * testTag method
  1137. *
  1138. * @return void
  1139. */
  1140. public function testTag() {
  1141. $result = $this->Html->tag('div');
  1142. $this->assertTags($result, '<div');
  1143. $result = $this->Html->tag('div', 'text');
  1144. $this->assertTags($result, '<div', 'text', '/div');
  1145. $result = $this->Html->tag('div', '<text>', 'class-name');
  1146. $this->assertTags($result, array('div' => array('class' => 'class-name'), 'preg:/<text>/', '/div'));
  1147. $result = $this->Html->tag('div', '<text>', array('class' => 'class-name', 'escape' => true));
  1148. $this->assertTags($result, array('div' => array('class' => 'class-name'), '&lt;text&gt;', '/div'));
  1149. }
  1150. /**
  1151. * testUseTag method
  1152. *
  1153. * @return void
  1154. */
  1155. public function testUseTag() {
  1156. $result = $this->Html->useTag('unknowntag');
  1157. $this->assertEqual($result, '');
  1158. $result = $this->Html->useTag('formend');
  1159. $this->assertTags($result, '/form');
  1160. $result = $this->Html->useTag('form', 'url', ' test');
  1161. $this->assertEqual($result, '<form action="url" test>');
  1162. $result = $this->Html->useTag('form', 'example.com', array('test' => 'ok'));
  1163. $this->assertTags($result, array('form' => array('test' => 'ok', 'action' => 'example.com')));
  1164. }
  1165. /**
  1166. * testDiv method
  1167. *
  1168. * @return void
  1169. */
  1170. public function testDiv() {
  1171. $result = $this->Html->div('class-name');
  1172. $this->assertTags($result, array('div' => array('class' => 'class-name')));
  1173. $result = $this->Html->div('class-name', 'text');
  1174. $this->assertTags($result, array('div' => array('class' => 'class-name'), 'text', '/div'));
  1175. $result = $this->Html->div('class-name', '<text>', array('escape' => true));
  1176. $this->assertTags($result, array('div' => array('class' => 'class-name'), '&lt;text&gt;', '/div'));
  1177. }
  1178. /**
  1179. * testPara method
  1180. *
  1181. * @return void
  1182. */
  1183. public function testPara() {
  1184. $result = $this->Html->para('class-name', '');
  1185. $this->assertTags($result, array('p' => array('class' => 'class-name')));
  1186. $result = $this->Html->para('class-name', 'text');
  1187. $this->assertTags($result, array('p' => array('class' => 'class-name'), 'text', '/p'));
  1188. $result = $this->Html->para('class-name', '<text>', array('escape' => true));
  1189. $this->assertTags($result, array('p' => array('class' => 'class-name'), '&lt;text&gt;', '/p'));
  1190. }
  1191. /**
  1192. * testCrumbList method
  1193. *
  1194. *
  1195. * @return void
  1196. */
  1197. public function testCrumbList() {
  1198. $this->assertNull($this->Html->getCrumbList());
  1199. $this->Html->addCrumb('Home', '/', array('class' => 'home'));
  1200. $this->Html->addCrumb('Some page', '/some_page');
  1201. $this->Html->addCrumb('Another page');
  1202. $result = $this->Html->getCrumbList(
  1203. array('class' => 'breadcrumbs')
  1204. );
  1205. $this->assertTags(
  1206. $result,
  1207. array(
  1208. array('ul' => array('class' => 'breadcrumbs')),
  1209. array('li' => array('class' => 'first')),
  1210. array('a' => array('class' => 'home', 'href' => '/')), 'Home', '/a',
  1211. '/li',
  1212. '<li',
  1213. array('a' => array('href' => '/some_page')), 'Some page', '/a',
  1214. '/li',
  1215. array('li' => array('class' => 'last')),
  1216. 'Another page',
  1217. '/li',
  1218. '/ul'
  1219. )
  1220. );
  1221. }
  1222. /**
  1223. * testLoadConfig method
  1224. *
  1225. * @return void
  1226. */
  1227. public function testLoadConfig() {
  1228. $path = CAKE . 'Test' . DS . 'test_app' . DS . 'Config'. DS;
  1229. $result = $this->Html->loadConfig('htmlhelper_tags', $path);
  1230. $expected = array(
  1231. 'tags' => array(
  1232. 'form' => 'start form',
  1233. 'formend' => 'finish form'
  1234. )
  1235. );
  1236. $this->assertEqual($expected, $result);
  1237. $tags = $this->Html->getAttribute('_tags');
  1238. $this->assertEqual($tags['form'], 'start form');
  1239. $this->assertEqual($tags['formend'], 'finish form');
  1240. $this->assertEqual($tags['selectend'], '</select>');
  1241. $result = $this->Html->loadConfig(array('htmlhelper_minimized.ini', 'ini'), $path);
  1242. $expected = array(
  1243. 'minimizedAttributeFormat' => 'format'
  1244. );
  1245. $this->assertEqual($expected, $result);
  1246. $this->assertEqual($this->Html->getAttribute('_minimizedAttributeFormat'), 'format');
  1247. }
  1248. /**
  1249. * testLoadConfigWrongFile method
  1250. *
  1251. * @return void
  1252. * @expectedException ConfigureException
  1253. */
  1254. public function testLoadConfigWrongFile() {
  1255. $result = $this->Html->loadConfig('wrong_file');
  1256. }
  1257. /**
  1258. * testLoadConfigWrongReader method
  1259. *
  1260. * @return void
  1261. * @expectedException ConfigureException
  1262. */
  1263. public function testLoadConfigWrongReader() {
  1264. $path = CAKE . 'Test' . DS . 'test_app' . DS . 'Config'. DS;
  1265. $result = $this->Html->loadConfig(array('htmlhelper_tags', 'wrong_reader'), $path);
  1266. }
  1267. /**
  1268. * test parsing attributes.
  1269. *
  1270. * @return void
  1271. */
  1272. public function testParseAttributeCompact() {
  1273. $helper = new TestHtmlHelper($this->View);
  1274. $compact = array('compact', 'checked', 'declare', 'readonly', 'disabled',
  1275. 'selected', 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize');
  1276. foreach ($compact as $attribute) {
  1277. foreach (array('true', true, 1, '1', $attribute) as $value) {
  1278. $attrs = array($attribute => $value);
  1279. $expected = ' ' . $attribute . '="' . $attribute . '"';
  1280. $this->assertEqual($helper->parseAttributes($attrs), $expected, '%s Failed on ' . $value);
  1281. }
  1282. }
  1283. $this->assertEqual($helper->parseAttributes(array('compact')), ' compact="compact"');
  1284. $helper = new Html5TestHelper($this->View);
  1285. $expected = ' require';
  1286. $this->assertEqual($helper->parseAttributes(array('require')), $expected);
  1287. $this->assertEqual($helper->parseAttributes(array('require' => true)), $expected);
  1288. $this->assertEqual($helper->parseAttributes(array('require' => false)), '');
  1289. }
  1290. }