JsHelperTest.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940
  1. <?php
  2. /**
  3. * JsHelper Test Case
  4. *
  5. * TestCase for the JsHelper
  6. *
  7. * PHP 5
  8. *
  9. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  10. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. *
  12. * Licensed under The MIT License
  13. * Redistributions of files must retain the above copyright notice
  14. *
  15. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  16. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  17. * @package Cake.Test.Case.View.Helper
  18. * @since CakePHP(tm) v 1.3
  19. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  20. */
  21. App::uses('HtmlHelper', 'View/Helper');
  22. App::uses('JsHelper', 'View/Helper');
  23. App::uses('JsBaseEngineHelper', 'View/Helper');
  24. App::uses('FormHelper', 'View/Helper');
  25. App::uses('View', 'View');
  26. App::uses('ClassRegistry', 'Utility');
  27. class JsEncodingObject {
  28. protected $_title = 'Old thing';
  29. //@codingStandardsIgnoreStart
  30. private $__noshow = 'Never ever';
  31. //@codingStandardsIgnoreEnd
  32. }
  33. class OptionEngineHelper extends JsBaseEngineHelper {
  34. protected $_optionMap = array(
  35. 'request' => array(
  36. 'complete' => 'success',
  37. 'request' => 'beforeSend',
  38. 'type' => 'dataType'
  39. )
  40. );
  41. /**
  42. * test method for testing option mapping
  43. *
  44. * @return array
  45. */
  46. public function testMap($options = array()) {
  47. return $this->_mapOptions('request', $options);
  48. }
  49. /**
  50. * test method for option parsing
  51. *
  52. * @return void
  53. */
  54. public function testParseOptions($options, $safe = array()) {
  55. return $this->_parseOptions($options, $safe);
  56. }
  57. public function get($selector) {
  58. }
  59. public function event($type, $callback, $options = array()) {
  60. }
  61. public function domReady($functionBody) {
  62. }
  63. public function each($callback) {
  64. }
  65. public function effect($name, $options = array()) {
  66. }
  67. public function request($url, $options = array()) {
  68. }
  69. public function drag($options = array()) {
  70. }
  71. public function drop($options = array()) {
  72. }
  73. public function sortable($options = array()) {
  74. }
  75. public function slider($options = array()) {
  76. }
  77. public function serializeForm($options = array()) {
  78. }
  79. }
  80. /**
  81. * JsHelper TestCase.
  82. *
  83. * @package Cake.Test.Case.View.Helper
  84. */
  85. class JsHelperTest extends CakeTestCase {
  86. /**
  87. * Regexp for CDATA start block
  88. *
  89. * @var string
  90. */
  91. public $cDataStart = 'preg:/^\/\/<!\[CDATA\[[\n\r]*/';
  92. /**
  93. * Regexp for CDATA end block
  94. *
  95. * @var string
  96. */
  97. public $cDataEnd = 'preg:/[^\]]*\]\]\>[\s\r\n]*/';
  98. /**
  99. * setUp method
  100. *
  101. * @return void
  102. */
  103. public function setUp() {
  104. parent::setUp();
  105. Configure::write('Asset.timestamp', false);
  106. $controller = null;
  107. $this->View = $this->getMock('View', array('append'), array(&$controller));
  108. $this->Js = new JsHelper($this->View, 'Option');
  109. $request = new CakeRequest(null, false);
  110. $this->Js->request = $request;
  111. $this->Js->Html = new HtmlHelper($this->View);
  112. $this->Js->Html->request = $request;
  113. $this->Js->Form = new FormHelper($this->View);
  114. $this->Js->Form->request = $request;
  115. $this->Js->Form->Html = $this->Js->Html;
  116. $this->Js->OptionEngine = new OptionEngineHelper($this->View);
  117. }
  118. /**
  119. * tearDown method
  120. *
  121. * @return void
  122. */
  123. public function tearDown() {
  124. parent::tearDown();
  125. unset($this->Js);
  126. }
  127. /**
  128. * Switches $this->Js to a mocked engine.
  129. *
  130. * @return void
  131. */
  132. protected function _useMock() {
  133. $request = new CakeRequest(null, false);
  134. if (!class_exists('TestJsEngineHelper', false)) {
  135. $this->getMock('JsBaseEngineHelper', array(), array($this->View), 'TestJsEngineHelper');
  136. }
  137. $this->Js = new JsHelper($this->View, array('TestJs'));
  138. $this->Js->TestJsEngine = new TestJsEngineHelper($this->View);
  139. $this->mockObjects[] = $this->Js->TestJsEngine;
  140. $this->Js->request = $request;
  141. $this->Js->Html = new HtmlHelper($this->View);
  142. $this->Js->Html->request = $request;
  143. $this->Js->Form = new FormHelper($this->View);
  144. $this->Js->Form->request = $request;
  145. $this->Js->Form->Html = new HtmlHelper($this->View);
  146. }
  147. /**
  148. * test object construction
  149. *
  150. * @return void
  151. */
  152. public function testConstruction() {
  153. $js = new JsHelper($this->View);
  154. $this->assertEquals(array('Html', 'Form', 'JqueryEngine'), $js->helpers);
  155. $js = new JsHelper($this->View, array('mootools'));
  156. $this->assertEquals(array('Html', 'Form', 'mootoolsEngine'), $js->helpers);
  157. $js = new JsHelper($this->View, 'prototype');
  158. $this->assertEquals(array('Html', 'Form', 'prototypeEngine'), $js->helpers);
  159. $js = new JsHelper($this->View, 'MyPlugin.Dojo');
  160. $this->assertEquals(array('Html', 'Form', 'MyPlugin.DojoEngine'), $js->helpers);
  161. }
  162. /**
  163. * test that methods dispatch internally and to the engine class
  164. *
  165. * @expectedException PHPUnit_Framework_Error_Warning
  166. * @return void
  167. */
  168. public function testMethodDispatching() {
  169. $this->_useMock();
  170. $this->Js->TestJsEngine
  171. ->expects($this->once())
  172. ->method('event')
  173. ->with('click', 'callback');
  174. $this->Js->event('click', 'callback');
  175. $this->Js->TestJsEngine = new StdClass();
  176. $this->Js->someMethodThatSurelyDoesntExist();
  177. }
  178. /**
  179. * Test that method dispatching for events respects buffer parameters and bufferedMethods Lists.
  180. *
  181. * @return void
  182. */
  183. public function testEventDispatchWithBuffering() {
  184. $this->_useMock();
  185. $this->Js->TestJsEngine->bufferedMethods = array('event', 'sortables');
  186. $this->Js->TestJsEngine->expects($this->exactly(3))
  187. ->method('event')
  188. ->will($this->returnValue('This is an event call'));
  189. $this->Js->event('click', 'foo');
  190. $result = $this->Js->getBuffer();
  191. $this->assertEquals(1, count($result));
  192. $this->assertEquals('This is an event call', $result[0]);
  193. $result = $this->Js->event('click', 'foo', array('buffer' => false));
  194. $buffer = $this->Js->getBuffer();
  195. $this->assertTrue(empty($buffer));
  196. $this->assertEquals('This is an event call', $result);
  197. $result = $this->Js->event('click', 'foo', false);
  198. $buffer = $this->Js->getBuffer();
  199. $this->assertTrue(empty($buffer));
  200. $this->assertEquals('This is an event call', $result);
  201. }
  202. /**
  203. * Test that method dispatching for effects respects buffer parameters and bufferedMethods Lists.
  204. *
  205. * @return void
  206. */
  207. public function testEffectDispatchWithBuffering() {
  208. $this->_useMock();
  209. $this->Js->TestJsEngine->expects($this->exactly(4))
  210. ->method('effect')
  211. ->will($this->returnValue('I am not buffered.'));
  212. $result = $this->Js->effect('slideIn');
  213. $buffer = $this->Js->getBuffer();
  214. $this->assertTrue(empty($buffer));
  215. $this->assertEquals('I am not buffered.', $result);
  216. $result = $this->Js->effect('slideIn', true);
  217. $buffer = $this->Js->getBuffer();
  218. $this->assertNull($result);
  219. $this->assertEquals(1, count($buffer));
  220. $this->assertEquals('I am not buffered.', $buffer[0]);
  221. $result = $this->Js->effect('slideIn', array('speed' => 'slow'), true);
  222. $buffer = $this->Js->getBuffer();
  223. $this->assertNull($result);
  224. $this->assertEquals(1, count($buffer));
  225. $this->assertEquals('I am not buffered.', $buffer[0]);
  226. $result = $this->Js->effect('slideIn', array('speed' => 'slow', 'buffer' => true));
  227. $buffer = $this->Js->getBuffer();
  228. $this->assertNull($result);
  229. $this->assertEquals(1, count($buffer));
  230. $this->assertEquals('I am not buffered.', $buffer[0]);
  231. }
  232. /**
  233. * test that writeScripts generates scripts inline.
  234. *
  235. * @return void
  236. */
  237. public function testWriteScriptsNoFile() {
  238. $this->_useMock();
  239. $this->Js->buffer('one = 1;');
  240. $this->Js->buffer('two = 2;');
  241. $result = $this->Js->writeBuffer(array('onDomReady' => false, 'cache' => false, 'clear' => false));
  242. $expected = array(
  243. 'script' => array('type' => 'text/javascript'),
  244. $this->cDataStart,
  245. "one = 1;\ntwo = 2;",
  246. $this->cDataEnd,
  247. '/script',
  248. );
  249. $this->assertTags($result, $expected);
  250. $this->Js->TestJsEngine->expects($this->atLeastOnce())->method('domReady');
  251. $result = $this->Js->writeBuffer(array('onDomReady' => true, 'cache' => false, 'clear' => false));
  252. $this->View->expects($this->once())
  253. ->method('append')
  254. ->with('script', $this->matchesRegularExpression('/one\s\=\s1;\ntwo\s\=\s2;/'));
  255. $result = $this->Js->writeBuffer(array('onDomReady' => false, 'inline' => false, 'cache' => false));
  256. }
  257. /**
  258. * test that writing the buffer with inline = false includes a script tag.
  259. *
  260. * @return void
  261. */
  262. public function testWriteBufferNotInline() {
  263. $this->Js->set('foo', 1);
  264. $this->View->expects($this->once())
  265. ->method('append')
  266. ->with('script', $this->matchesRegularExpression('#<script type="text\/javascript">window.app \= \{"foo"\:1\}\;<\/script>#'));
  267. $this->Js->writeBuffer(array('onDomReady' => false, 'inline' => false, 'safe' => false));
  268. }
  269. /**
  270. * test that writeBuffer() sets domReady = false when the request is done by XHR.
  271. * Including a domReady() when in XHR can cause issues as events aren't triggered by some libraries
  272. *
  273. * @return void
  274. */
  275. public function testWriteBufferAndXhr() {
  276. $this->_useMock();
  277. $requestWith = null;
  278. if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
  279. $requestWith = $_SERVER['HTTP_X_REQUESTED_WITH'];
  280. }
  281. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
  282. $this->Js->buffer('alert("test");');
  283. $this->Js->TestJsEngine->expects($this->never())->method('domReady');
  284. $this->Js->writeBuffer();
  285. unset($_SERVER['HTTP_X_REQUESTED_WITH']);
  286. if ($requestWith !== null) {
  287. $_SERVER['HTTP_X_REQUESTED_WITH'] = $requestWith;
  288. }
  289. }
  290. /**
  291. * test that writeScripts makes files, and puts the events into them.
  292. *
  293. * @return void
  294. */
  295. public function testWriteScriptsInFile() {
  296. $this->skipIf(!is_writable(JS), 'webroot/js is not Writable, script caching test has been skipped.');
  297. Configure::write('Cache.disable', false);
  298. $this->Js->request->webroot = '/';
  299. $this->Js->JsBaseEngine = new TestJsEngineHelper($this->View);
  300. $this->Js->buffer('one = 1;');
  301. $this->Js->buffer('two = 2;');
  302. $result = $this->Js->writeBuffer(array('onDomReady' => false, 'cache' => true));
  303. $expected = array(
  304. 'script' => array('type' => 'text/javascript', 'src' => 'preg:/(.)*\.js/'),
  305. );
  306. $this->assertTags($result, $expected);
  307. preg_match('/src="(.*\.js)"/', $result, $filename);
  308. $this->assertTrue(file_exists(WWW_ROOT . $filename[1]));
  309. $contents = file_get_contents(WWW_ROOT . $filename[1]);
  310. $this->assertRegExp('/one\s=\s1;\ntwo\s=\s2;/', $contents);
  311. if (file_exists(WWW_ROOT . $filename[1])) {
  312. unlink(WWW_ROOT . $filename[1]);
  313. }
  314. Configure::write('Cache.disable', true);
  315. $this->Js->buffer('one = 1;');
  316. $this->Js->buffer('two = 2;');
  317. $result = $this->Js->writeBuffer(array('onDomReady' => false, 'cache' => true));
  318. $this->assertRegExp('/one\s=\s1;\ntwo\s=\s2;/', $result);
  319. $this->assertFalse(file_exists(WWW_ROOT . $filename[1]));
  320. }
  321. /**
  322. * test link()
  323. *
  324. * @return void
  325. */
  326. public function testLinkWithMock() {
  327. $this->_useMock();
  328. $options = array('update' => '#content');
  329. $this->Js->TestJsEngine->expects($this->at(0))
  330. ->method('get');
  331. $this->Js->TestJsEngine->expects($this->at(1))
  332. ->method('request')
  333. ->with('/posts/view/1', $options)
  334. ->will($this->returnValue('--ajax code--'));
  335. $this->Js->TestJsEngine->expects($this->at(2))
  336. ->method('event')
  337. ->with('click', '--ajax code--', $options + array('buffer' => null));
  338. $result = $this->Js->link('test link', '/posts/view/1', $options);
  339. $expected = array(
  340. 'a' => array('id' => 'preg:/link-\d+/', 'href' => '/posts/view/1'),
  341. 'test link',
  342. '/a'
  343. );
  344. $this->assertTags($result, $expected);
  345. }
  346. /**
  347. * test link with a mock and confirmation
  348. *
  349. * @return void
  350. */
  351. public function testLinkWithMockAndConfirm() {
  352. $this->_useMock();
  353. $options = array(
  354. 'confirm' => 'Are you sure?',
  355. 'update' => '#content',
  356. 'class' => 'my-class',
  357. 'id' => 'custom-id',
  358. 'escape' => false
  359. );
  360. $this->Js->TestJsEngine->expects($this->once())
  361. ->method('confirmReturn')
  362. ->with($options['confirm'])
  363. ->will($this->returnValue('--confirm script--'));
  364. $this->Js->TestJsEngine->expects($this->once())
  365. ->method('request')
  366. ->with('/posts/view/1');
  367. $this->Js->TestJsEngine->expects($this->once())
  368. ->method('event')
  369. ->with('click', '--confirm script--');
  370. $result = $this->Js->link('test link »', '/posts/view/1', $options);
  371. $expected = array(
  372. 'a' => array('id' => $options['id'], 'class' => $options['class'], 'href' => '/posts/view/1'),
  373. 'test link »',
  374. '/a'
  375. );
  376. $this->assertTags($result, $expected);
  377. }
  378. /**
  379. * test link passing on htmlAttributes
  380. *
  381. * @return void
  382. */
  383. public function testLinkWithAribtraryAttributes() {
  384. $this->_useMock();
  385. $options = array('id' => 'something', 'htmlAttributes' => array('arbitrary' => 'value', 'batman' => 'robin'));
  386. $result = $this->Js->link('test link', '/posts/view/1', $options);
  387. $expected = array(
  388. 'a' => array('id' => $options['id'], 'href' => '/posts/view/1', 'arbitrary' => 'value',
  389. 'batman' => 'robin'),
  390. 'test link',
  391. '/a'
  392. );
  393. $this->assertTags($result, $expected);
  394. }
  395. /**
  396. * test that link() and no buffering returns an <a> and <script> tags.
  397. *
  398. * @return void
  399. */
  400. public function testLinkWithNoBuffering() {
  401. $this->_useMock();
  402. $this->Js->TestJsEngine->expects($this->at(1))
  403. ->method('request')
  404. ->with('/posts/view/1', array('update' => '#content'))
  405. ->will($this->returnValue('ajax code'));
  406. $this->Js->TestJsEngine->expects($this->at(2))
  407. ->method('event')
  408. ->will($this->returnValue('-event handler-'));
  409. $options = array('update' => '#content', 'buffer' => false);
  410. $result = $this->Js->link('test link', '/posts/view/1', $options);
  411. $expected = array(
  412. 'a' => array('id' => 'preg:/link-\d+/', 'href' => '/posts/view/1'),
  413. 'test link',
  414. '/a',
  415. 'script' => array('type' => 'text/javascript'),
  416. $this->cDataStart,
  417. '-event handler-',
  418. $this->cDataEnd,
  419. '/script'
  420. );
  421. $this->assertTags($result, $expected);
  422. }
  423. /**
  424. * test link with buffering off and safe on.
  425. *
  426. * @return void
  427. */
  428. public function testLinkWithNoBufferingAndSafe() {
  429. $this->_useMock();
  430. $this->Js->TestJsEngine->expects($this->at(1))
  431. ->method('request')
  432. ->with('/posts/view/1', array('update' => '#content'))
  433. ->will($this->returnValue('ajax code'));
  434. $this->Js->TestJsEngine->expects($this->at(2))
  435. ->method('event')
  436. ->will($this->returnValue('-event handler-'));
  437. $options = array('update' => '#content', 'buffer' => false, 'safe' => false);
  438. $result = $this->Js->link('test link', '/posts/view/1', $options);
  439. $expected = array(
  440. 'a' => array('id' => 'preg:/link-\d+/', 'href' => '/posts/view/1'),
  441. 'test link',
  442. '/a',
  443. 'script' => array('type' => 'text/javascript'),
  444. '-event handler-',
  445. '/script'
  446. );
  447. $this->assertTags($result, $expected);
  448. }
  449. /**
  450. * test submit() with a Mock to check Engine method calls
  451. *
  452. * @return void
  453. */
  454. public function testSubmitWithMock() {
  455. $this->_useMock();
  456. $options = array('update' => '#content', 'id' => 'test-submit', 'style' => 'margin: 0');
  457. $this->Js->TestJsEngine->expects($this->at(0))
  458. ->method('get');
  459. $this->Js->TestJsEngine->expects($this->at(1))
  460. ->method('serializeForm')
  461. ->will($this->returnValue('serialize-code'));
  462. $this->Js->TestJsEngine->expects($this->at(2))
  463. ->method('request')
  464. ->will($this->returnValue('ajax-code'));
  465. $params = array(
  466. 'update' => $options['update'], 'data' => 'serialize-code',
  467. 'method' => 'post', 'dataExpression' => true, 'buffer' => null
  468. );
  469. $this->Js->TestJsEngine->expects($this->at(3))
  470. ->method('event')
  471. ->with('click', "ajax-code", $params);
  472. $result = $this->Js->submit('Save', $options);
  473. $expected = array(
  474. 'div' => array('class' => 'submit'),
  475. 'input' => array('type' => 'submit', 'id' => $options['id'], 'value' => 'Save', 'style' => 'margin: 0'),
  476. '/div'
  477. );
  478. $this->assertTags($result, $expected);
  479. }
  480. /**
  481. * test submit() with a mock
  482. *
  483. * @return void
  484. */
  485. public function testSubmitWithMockRequestParams() {
  486. $this->_useMock();
  487. $this->Js->TestJsEngine->expects($this->at(0))
  488. ->method('get');
  489. $this->Js->TestJsEngine->expects($this->at(1))
  490. ->method('serializeForm')
  491. ->will($this->returnValue('serialize-code'));
  492. $requestParams = array(
  493. 'update' => '#content',
  494. 'data' => 'serialize-code',
  495. 'method' => 'post',
  496. 'dataExpression' => true
  497. );
  498. $this->Js->TestJsEngine->expects($this->at(2))
  499. ->method('request')
  500. ->with('/custom/url', $requestParams)
  501. ->will($this->returnValue('ajax-code'));
  502. $params = array(
  503. 'update' => '#content', 'data' => 'serialize-code',
  504. 'method' => 'post', 'dataExpression' => true, 'buffer' => null
  505. );
  506. $this->Js->TestJsEngine->expects($this->at(3))
  507. ->method('event')
  508. ->with('click', "ajax-code", $params);
  509. $options = array('update' => '#content', 'id' => 'test-submit', 'url' => '/custom/url');
  510. $result = $this->Js->submit('Save', $options);
  511. $expected = array(
  512. 'div' => array('class' => 'submit'),
  513. 'input' => array('type' => 'submit', 'id' => $options['id'], 'value' => 'Save'),
  514. '/div'
  515. );
  516. $this->assertTags($result, $expected);
  517. }
  518. /**
  519. * test that no buffer works with submit() and that parameters are leaking into the script tag.
  520. *
  521. * @return void
  522. */
  523. public function testSubmitWithNoBuffer() {
  524. $this->_useMock();
  525. $options = array('update' => '#content', 'id' => 'test-submit', 'buffer' => false, 'safe' => false);
  526. $this->Js->TestJsEngine->expects($this->at(0))
  527. ->method('get');
  528. $this->Js->TestJsEngine->expects($this->at(1))
  529. ->method('serializeForm')
  530. ->will($this->returnValue('serialize-code'));
  531. $this->Js->TestJsEngine->expects($this->at(2))
  532. ->method('request')
  533. ->will($this->returnValue('ajax-code'));
  534. $this->Js->TestJsEngine->expects($this->at(3))
  535. ->method('event')
  536. ->will($this->returnValue('event-handler'));
  537. $params = array(
  538. 'update' => $options['update'], 'data' => 'serialize-code',
  539. 'method' => 'post', 'dataExpression' => true, 'buffer' => false
  540. );
  541. $this->Js->TestJsEngine->expects($this->at(3))
  542. ->method('event')
  543. ->with('click', "ajax-code", $params);
  544. $result = $this->Js->submit('Save', $options);
  545. $expected = array(
  546. 'div' => array('class' => 'submit'),
  547. 'input' => array('type' => 'submit', 'id' => $options['id'], 'value' => 'Save'),
  548. '/div',
  549. 'script' => array('type' => 'text/javascript'),
  550. 'event-handler',
  551. '/script'
  552. );
  553. $this->assertTags($result, $expected);
  554. }
  555. /**
  556. * Test that Object::Object() is not breaking json output in JsHelper
  557. *
  558. * @return void
  559. */
  560. public function testObjectPassThrough() {
  561. $result = $this->Js->object(array('one' => 'first', 'two' => 'second'));
  562. $expected = '{"one":"first","two":"second"}';
  563. $this->assertEquals($expected, $result);
  564. }
  565. /**
  566. * Test that inherited Helper::value() is overwritten in JsHelper::value()
  567. * and calls JsBaseEngineHelper::value().
  568. *
  569. * @return void
  570. */
  571. public function testValuePassThrough() {
  572. $result = $this->Js->value('string "quote"', true);
  573. $expected = '"string \"quote\""';
  574. $this->assertEquals($expected, $result);
  575. }
  576. /**
  577. * test set()'ing variables to the Javascript buffer and controlling the output var name.
  578. *
  579. * @return void
  580. */
  581. public function testSet() {
  582. $this->Js->set('loggedIn', true);
  583. $this->Js->set(array('height' => 'tall', 'color' => 'purple'));
  584. $result = $this->Js->getBuffer();
  585. $expected = 'window.app = {"loggedIn":true,"height":"tall","color":"purple"};';
  586. $this->assertEquals($expected, $result[0]);
  587. $this->Js->set('loggedIn', true);
  588. $this->Js->set(array('height' => 'tall', 'color' => 'purple'));
  589. $this->Js->setVariable = 'WICKED';
  590. $result = $this->Js->getBuffer();
  591. $expected = 'window.WICKED = {"loggedIn":true,"height":"tall","color":"purple"};';
  592. $this->assertEquals($expected, $result[0]);
  593. $this->Js->set('loggedIn', true);
  594. $this->Js->set(array('height' => 'tall', 'color' => 'purple'));
  595. $this->Js->setVariable = 'Application.variables';
  596. $result = $this->Js->getBuffer();
  597. $expected = 'Application.variables = {"loggedIn":true,"height":"tall","color":"purple"};';
  598. $this->assertEquals($expected, $result[0]);
  599. }
  600. /**
  601. * test that vars set with Js->set() go to the top of the buffered scripts list.
  602. *
  603. * @return void
  604. */
  605. public function testSetVarsAtTopOfBufferedScripts() {
  606. $this->Js->set(array('height' => 'tall', 'color' => 'purple'));
  607. $this->Js->alert('hey you!', array('buffer' => true));
  608. $this->Js->confirm('Are you sure?', array('buffer' => true));
  609. $result = $this->Js->getBuffer(false);
  610. $expected = 'window.app = {"height":"tall","color":"purple"};';
  611. $this->assertEquals($expected, $result[0]);
  612. $this->assertEquals('alert("hey you!");', $result[1]);
  613. $this->assertEquals('confirm("Are you sure?");', $result[2]);
  614. }
  615. }
  616. /**
  617. * JsBaseEngine Class Test case
  618. *
  619. * @package Cake.Test.Case.View.Helper
  620. */
  621. class JsBaseEngineTest extends CakeTestCase {
  622. /**
  623. * setUp method
  624. *
  625. * @return void
  626. */
  627. public function setUp() {
  628. parent::setUp();
  629. $controller = null;
  630. $this->View = $this->getMock('View', array('append'), array(&$controller));
  631. $this->JsEngine = new OptionEngineHelper($this->View);
  632. }
  633. /**
  634. * tearDown method
  635. *
  636. * @return void
  637. */
  638. public function tearDown() {
  639. parent::tearDown();
  640. unset($this->JsEngine);
  641. }
  642. /**
  643. * test escape string skills
  644. *
  645. * @return void
  646. */
  647. public function testEscaping() {
  648. $result = $this->JsEngine->escape('');
  649. $expected = '';
  650. $this->assertEquals($expected, $result);
  651. $result = $this->JsEngine->escape('CakePHP' . "\n" . 'Rapid Development Framework');
  652. $expected = 'CakePHP\\nRapid Development Framework';
  653. $this->assertEquals($expected, $result);
  654. $result = $this->JsEngine->escape('CakePHP' . "\r\n" . 'Rapid Development Framework' . "\r" . 'For PHP');
  655. $expected = 'CakePHP\\r\\nRapid Development Framework\\rFor PHP';
  656. $this->assertEquals($expected, $result);
  657. $result = $this->JsEngine->escape('CakePHP: "Rapid Development Framework"');
  658. $expected = 'CakePHP: \\"Rapid Development Framework\\"';
  659. $this->assertEquals($expected, $result);
  660. $result = $this->JsEngine->escape("CakePHP: 'Rapid Development Framework'");
  661. $expected = "CakePHP: 'Rapid Development Framework'";
  662. $this->assertEquals($expected, $result);
  663. $result = $this->JsEngine->escape('my \\"string\\"');
  664. $expected = 'my \\\\\\"string\\\\\\"';
  665. $this->assertEquals($expected, $result);
  666. }
  667. /**
  668. * test prompt() creation
  669. *
  670. * @return void
  671. */
  672. public function testPrompt() {
  673. $result = $this->JsEngine->prompt('Hey, hey you', 'hi!');
  674. $expected = 'prompt("Hey, hey you", "hi!");';
  675. $this->assertEquals($expected, $result);
  676. $result = $this->JsEngine->prompt('"Hey"', '"hi"');
  677. $expected = 'prompt("\"Hey\"", "\"hi\"");';
  678. $this->assertEquals($expected, $result);
  679. }
  680. /**
  681. * test alert generation
  682. *
  683. * @return void
  684. */
  685. public function testAlert() {
  686. $result = $this->JsEngine->alert('Hey there');
  687. $expected = 'alert("Hey there");';
  688. $this->assertEquals($expected, $result);
  689. $result = $this->JsEngine->alert('"Hey"');
  690. $expected = 'alert("\"Hey\"");';
  691. $this->assertEquals($expected, $result);
  692. }
  693. /**
  694. * test confirm generation
  695. *
  696. * @return void
  697. */
  698. public function testConfirm() {
  699. $result = $this->JsEngine->confirm('Are you sure?');
  700. $expected = 'confirm("Are you sure?");';
  701. $this->assertEquals($expected, $result);
  702. $result = $this->JsEngine->confirm('"Are you sure?"');
  703. $expected = 'confirm("\"Are you sure?\"");';
  704. $this->assertEquals($expected, $result);
  705. }
  706. /**
  707. * test Redirect
  708. *
  709. * @return void
  710. */
  711. public function testRedirect() {
  712. $result = $this->JsEngine->redirect(array('controller' => 'posts', 'action' => 'view', 1));
  713. $expected = 'window.location = "/posts/view/1";';
  714. $this->assertEquals($expected, $result);
  715. }
  716. /**
  717. * testObject encoding with non-native methods.
  718. *
  719. * @return void
  720. */
  721. public function testObject() {
  722. $object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8));
  723. $result = $this->JsEngine->object($object);
  724. $expected = '{"title":"New thing","indexes":[5,6,7,8]}';
  725. $this->assertEquals($expected, $result);
  726. $object = new JsEncodingObject();
  727. $object->title = 'New thing';
  728. $object->indexes = array(5,6,7,8);
  729. $result = $this->JsEngine->object($object);
  730. $this->assertEquals($expected, $result);
  731. $result = $this->JsEngine->object(array('default' => 0));
  732. $expected = '{"default":0}';
  733. $this->assertEquals($expected, $result);
  734. $result = $this->JsEngine->object(array(
  735. '2007' => array(
  736. 'Spring' => array(
  737. '1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
  738. ),
  739. 'Fall' => array(
  740. '1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
  741. )
  742. ),
  743. '2006' => array(
  744. 'Spring' => array(
  745. '1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
  746. ),
  747. 'Fall' => array(
  748. '1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
  749. )
  750. )
  751. ));
  752. $expected = '{"2007":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}},"2006":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}}}';
  753. $this->assertEquals($expected, $result);
  754. foreach (array('true' => true, 'false' => false, 'null' => null) as $expected => $data) {
  755. $result = $this->JsEngine->object($data);
  756. $this->assertEquals($expected, $result);
  757. }
  758. $object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8), 'object' => array('inner' => array('value' => 1)));
  759. $result = $this->JsEngine->object($object, array('prefix' => 'PREFIX', 'postfix' => 'POSTFIX'));
  760. $this->assertRegExp('/^PREFIX/', $result);
  761. $this->assertRegExp('/POSTFIX$/', $result);
  762. $this->assertNotRegExp('/.PREFIX./', $result);
  763. $this->assertNotRegExp('/.POSTFIX./', $result);
  764. }
  765. /**
  766. * test Mapping of options.
  767. *
  768. * @return void
  769. */
  770. public function testOptionMapping() {
  771. $JsEngine = new OptionEngineHelper($this->View);
  772. $result = $JsEngine->testMap();
  773. $this->assertSame(array(), $result);
  774. $result = $JsEngine->testMap(array('foo' => 'bar', 'baz' => 'sho'));
  775. $this->assertEquals(array('foo' => 'bar', 'baz' => 'sho'), $result);
  776. $result = $JsEngine->testMap(array('complete' => 'myFunc', 'type' => 'json', 'update' => '#element'));
  777. $this->assertEquals(array('success' => 'myFunc', 'dataType' => 'json', 'update' => '#element'), $result);
  778. $result = $JsEngine->testMap(array('success' => 'myFunc', 'dataType' => 'json', 'update' => '#element'));
  779. $this->assertEquals(array('success' => 'myFunc', 'dataType' => 'json', 'update' => '#element'), $result);
  780. }
  781. /**
  782. * test that option parsing escapes strings and saves what is supposed to be saved.
  783. *
  784. * @return void
  785. */
  786. public function testOptionParsing() {
  787. $JsEngine = new OptionEngineHelper($this->View);
  788. $result = $JsEngine->testParseOptions(array('url' => '/posts/view/1', 'key' => 1));
  789. $expected = 'key:1, url:"\\/posts\\/view\\/1"';
  790. $this->assertEquals($expected, $result);
  791. $result = $JsEngine->testParseOptions(array('url' => '/posts/view/1', 'success' => 'doSuccess'), array('success'));
  792. $expected = 'success:doSuccess, url:"\\/posts\\/view\\/1"';
  793. $this->assertEquals($expected, $result);
  794. }
  795. }