JsHelperTest.php 27 KB

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