MultiCheckboxWidgetTest.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\View\Widget;
  16. use Cake\TestSuite\TestCase;
  17. use Cake\View\StringTemplate;
  18. use Cake\View\Widget\LabelWidget;
  19. use Cake\View\Widget\MultiCheckboxWidget;
  20. /**
  21. * MultiCheckbox test case.
  22. */
  23. class MultiCheckboxWidgetTest extends TestCase
  24. {
  25. /**
  26. * setup method.
  27. *
  28. * @return void
  29. */
  30. public function setUp()
  31. {
  32. parent::setUp();
  33. $templates = [
  34. 'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>',
  35. 'label' => '<label{{attrs}}>{{text}}</label>',
  36. 'checkboxWrapper' => '<div class="checkbox">{{input}}{{label}}</div>',
  37. 'multicheckboxWrapper' => '<fieldset{{attrs}}>{{content}}</fieldset>',
  38. 'multicheckboxTitle' => '<legend>{{text}}</legend>',
  39. ];
  40. $this->templates = new StringTemplate($templates);
  41. $this->context = $this->getMockBuilder('Cake\View\Form\ContextInterface')->getMock();
  42. }
  43. /**
  44. * Test render simple option sets.
  45. *
  46. * @return void
  47. */
  48. public function testRenderSimple()
  49. {
  50. $label = new LabelWidget($this->templates);
  51. $input = new MultiCheckboxWidget($this->templates, $label);
  52. $data = [
  53. 'name' => 'Tags[id]',
  54. 'options' => [
  55. 1 => 'CakePHP',
  56. 2 => 'Development',
  57. ]
  58. ];
  59. $result = $input->render($data, $this->context);
  60. $expected = [
  61. ['div' => ['class' => 'checkbox']],
  62. ['input' => [
  63. 'type' => 'checkbox',
  64. 'name' => 'Tags[id][]',
  65. 'value' => 1,
  66. 'id' => 'tags-id-1',
  67. ]],
  68. ['label' => ['for' => 'tags-id-1']],
  69. 'CakePHP',
  70. '/label',
  71. '/div',
  72. ['div' => ['class' => 'checkbox']],
  73. ['input' => [
  74. 'type' => 'checkbox',
  75. 'name' => 'Tags[id][]',
  76. 'value' => 2,
  77. 'id' => 'tags-id-2',
  78. ]],
  79. ['label' => ['for' => 'tags-id-2']],
  80. 'Development',
  81. '/label',
  82. '/div',
  83. ];
  84. $this->assertHtml($expected, $result);
  85. }
  86. /**
  87. * Test render complex and additional attributes.
  88. *
  89. * @return void
  90. */
  91. public function testRenderComplex()
  92. {
  93. $label = new LabelWidget($this->templates);
  94. $input = new MultiCheckboxWidget($this->templates, $label);
  95. $data = [
  96. 'name' => 'Tags[id]',
  97. 'val' => 2,
  98. 'disabled' => ['1'],
  99. 'options' => [
  100. ['value' => '1', 'text' => 'CakePHP', 'data-test' => 'val'],
  101. ['value' => '2', 'text' => 'Development', 'class' => 'custom'],
  102. ]
  103. ];
  104. $result = $input->render($data, $this->context);
  105. $expected = [
  106. ['div' => ['class' => 'checkbox']],
  107. ['input' => [
  108. 'disabled' => 'disabled',
  109. 'type' => 'checkbox',
  110. 'name' => 'Tags[id][]',
  111. 'value' => 1,
  112. 'id' => 'tags-id-1',
  113. 'data-test' => 'val',
  114. ]],
  115. ['label' => ['for' => 'tags-id-1']],
  116. 'CakePHP',
  117. '/label',
  118. '/div',
  119. ['div' => ['class' => 'checkbox']],
  120. ['input' => [
  121. 'type' => 'checkbox',
  122. 'checked' => 'checked',
  123. 'name' => 'Tags[id][]',
  124. 'value' => 2,
  125. 'id' => 'tags-id-2',
  126. 'class' => 'custom',
  127. ]],
  128. ['label' => ['class' => 'selected', 'for' => 'tags-id-2']],
  129. 'Development',
  130. '/label',
  131. '/div',
  132. ];
  133. $this->assertHtml($expected, $result);
  134. }
  135. /**
  136. * Test render escpaing options.
  137. *
  138. * @return void
  139. */
  140. public function testRenderEscaping()
  141. {
  142. $label = new LabelWidget($this->templates);
  143. $input = new MultiCheckboxWidget($this->templates, $label);
  144. $data = [
  145. 'name' => 'Tags[id]',
  146. 'options' => [
  147. '>' => '>>',
  148. ]
  149. ];
  150. $result = $input->render($data, $this->context);
  151. $expected = [
  152. ['div' => ['class' => 'checkbox']],
  153. ['input' => [
  154. 'type' => 'checkbox',
  155. 'name' => 'Tags[id][]',
  156. 'value' => '&gt;',
  157. 'id' => 'tags-id',
  158. ]],
  159. ['label' => ['for' => 'tags-id']],
  160. '&gt;&gt;',
  161. '/label',
  162. '/div',
  163. ];
  164. $this->assertHtml($expected, $result);
  165. }
  166. /**
  167. * Test render selected checkboxes.
  168. *
  169. * @return void
  170. */
  171. public function testRenderSelected()
  172. {
  173. $label = new LabelWidget($this->templates);
  174. $input = new MultiCheckboxWidget($this->templates, $label);
  175. $data = [
  176. 'name' => 'Tags[id]',
  177. 'options' => [
  178. 1 => 'CakePHP',
  179. '1x' => 'Development',
  180. ],
  181. 'val' => [1],
  182. 'disabled' => false
  183. ];
  184. $result = $input->render($data, $this->context);
  185. $expected = [
  186. ['div' => ['class' => 'checkbox']],
  187. ['input' => [
  188. 'type' => 'checkbox',
  189. 'name' => 'Tags[id][]',
  190. 'value' => 1,
  191. 'id' => 'tags-id-1',
  192. 'checked' => 'checked'
  193. ]],
  194. ['label' => ['class' => 'selected', 'for' => 'tags-id-1']],
  195. 'CakePHP',
  196. '/label',
  197. '/div',
  198. ['div' => ['class' => 'checkbox']],
  199. ['input' => [
  200. 'type' => 'checkbox',
  201. 'name' => 'Tags[id][]',
  202. 'value' => '1x',
  203. 'id' => 'tags-id-1x',
  204. ]],
  205. ['label' => ['for' => 'tags-id-1x']],
  206. 'Development',
  207. '/label',
  208. '/div',
  209. ];
  210. $this->assertHtml($expected, $result);
  211. $data['val'] = 1;
  212. $result = $input->render($data, $this->context);
  213. $this->assertHtml($expected, $result);
  214. $data['val'] = '1';
  215. $result = $input->render($data, $this->context);
  216. $this->assertHtml($expected, $result);
  217. }
  218. /**
  219. * Test render disabled checkboxes.
  220. *
  221. * @return void
  222. */
  223. public function testRenderDisabled()
  224. {
  225. $label = new LabelWidget($this->templates);
  226. $input = new MultiCheckboxWidget($this->templates, $label);
  227. $data = [
  228. 'name' => 'Tags[id]',
  229. 'options' => [
  230. 1 => 'CakePHP',
  231. '1x' => 'Development',
  232. ],
  233. 'disabled' => true,
  234. ];
  235. $result = $input->render($data, $this->context);
  236. $expected = [
  237. ['div' => ['class' => 'checkbox']],
  238. ['input' => [
  239. 'type' => 'checkbox',
  240. 'name' => 'Tags[id][]',
  241. 'value' => 1,
  242. 'id' => 'tags-id-1',
  243. 'disabled' => 'disabled'
  244. ]],
  245. ['label' => ['for' => 'tags-id-1']],
  246. 'CakePHP',
  247. '/label',
  248. '/div',
  249. ['div' => ['class' => 'checkbox']],
  250. ['input' => [
  251. 'type' => 'checkbox',
  252. 'name' => 'Tags[id][]',
  253. 'value' => '1x',
  254. 'id' => 'tags-id-1x',
  255. 'disabled' => 'disabled'
  256. ]],
  257. ['label' => ['for' => 'tags-id-1x']],
  258. 'Development',
  259. '/label',
  260. '/div',
  261. ];
  262. $this->assertHtml($expected, $result);
  263. $data['disabled'] = 'a string';
  264. $result = $input->render($data, $this->context);
  265. $this->assertHtml($expected, $result);
  266. $data['disabled'] = ['1', '1x'];
  267. $this->assertHtml($expected, $result);
  268. $data = [
  269. 'name' => 'Tags[id]',
  270. 'options' => [
  271. 1 => 'CakePHP',
  272. '1x' => 'Development',
  273. ],
  274. 'disabled' => [1]
  275. ];
  276. $result = $input->render($data, $this->context);
  277. $expected = [
  278. ['div' => ['class' => 'checkbox']],
  279. ['input' => [
  280. 'type' => 'checkbox',
  281. 'name' => 'Tags[id][]',
  282. 'value' => 1,
  283. 'id' => 'tags-id-1',
  284. 'disabled' => 'disabled'
  285. ]],
  286. ['label' => ['for' => 'tags-id-1']],
  287. 'CakePHP',
  288. '/label',
  289. '/div',
  290. ['div' => ['class' => 'checkbox']],
  291. ['input' => [
  292. 'type' => 'checkbox',
  293. 'name' => 'Tags[id][]',
  294. 'value' => '1x',
  295. 'id' => 'tags-id-1x',
  296. ]],
  297. ['label' => ['for' => 'tags-id-1x']],
  298. 'Development',
  299. '/label',
  300. '/div',
  301. ];
  302. $this->assertHtml($expected, $result);
  303. }
  304. /**
  305. * Test render templateVars
  306. *
  307. * @return void
  308. */
  309. public function testRenderTemplateVars()
  310. {
  311. $templates = [
  312. 'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}" data-var="{{inputVar}}" {{attrs}}>',
  313. 'label' => '<label{{attrs}}>{{text}} {{inputVar}}</label>',
  314. 'checkboxWrapper' => '<div class="checkbox" data-wrap="{{wrapVar}}">{{input}}{{label}}</div>',
  315. ];
  316. $this->templates->add($templates);
  317. $label = new LabelWidget($this->templates);
  318. $input = new MultiCheckboxWidget($this->templates, $label);
  319. $data = [
  320. 'name' => 'Tags[id]',
  321. 'options' => [
  322. ['value' => '1', 'text' => 'CakePHP', 'templateVars' => ['inputVar' => 'i-var']],
  323. '1x' => 'Development',
  324. ],
  325. 'templateVars' => ['inputVar' => 'default', 'wrapVar' => 'val'],
  326. ];
  327. $result = $input->render($data, $this->context);
  328. $expected = [
  329. ['div' => ['class' => 'checkbox', 'data-wrap' => 'val']],
  330. ['input' => [
  331. 'type' => 'checkbox',
  332. 'name' => 'Tags[id][]',
  333. 'value' => 1,
  334. 'id' => 'tags-id-1',
  335. 'data-var' => 'i-var',
  336. ]],
  337. ['label' => ['for' => 'tags-id-1']],
  338. 'CakePHP i-var',
  339. '/label',
  340. '/div',
  341. ['div' => ['class' => 'checkbox', 'data-wrap' => 'val']],
  342. ['input' => [
  343. 'type' => 'checkbox',
  344. 'name' => 'Tags[id][]',
  345. 'value' => '1x',
  346. 'id' => 'tags-id-1x',
  347. 'data-var' => 'default'
  348. ]],
  349. ['label' => ['for' => 'tags-id-1x']],
  350. 'Development default',
  351. '/label',
  352. '/div',
  353. ];
  354. $this->assertHtml($expected, $result);
  355. }
  356. /**
  357. * Test render with groupings.
  358. *
  359. * @return void
  360. */
  361. public function testRenderGrouped()
  362. {
  363. $label = new LabelWidget($this->templates);
  364. $input = new MultiCheckboxWidget($this->templates, $label);
  365. $data = [
  366. 'name' => 'Tags[id]',
  367. 'options' => [
  368. 'Group 1' => [
  369. 1 => 'CakePHP',
  370. ],
  371. 'Group 2' => [
  372. 2 => 'Development',
  373. ]
  374. ]
  375. ];
  376. $result = $input->render($data, $this->context);
  377. $expected = [
  378. '<fieldset',
  379. '<legend', 'Group 1', '/legend',
  380. ['div' => ['class' => 'checkbox']],
  381. ['input' => [
  382. 'type' => 'checkbox',
  383. 'name' => 'Tags[id][]',
  384. 'value' => 1,
  385. 'id' => 'tags-id-1',
  386. ]],
  387. ['label' => ['for' => 'tags-id-1']],
  388. 'CakePHP',
  389. '/label',
  390. '/div',
  391. '/fieldset',
  392. '<fieldset',
  393. '<legend', 'Group 2', '/legend',
  394. ['div' => ['class' => 'checkbox']],
  395. ['input' => [
  396. 'type' => 'checkbox',
  397. 'name' => 'Tags[id][]',
  398. 'value' => 2,
  399. 'id' => 'tags-id-2',
  400. ]],
  401. ['label' => ['for' => 'tags-id-2']],
  402. 'Development',
  403. '/label',
  404. '/div',
  405. '/fieldset',
  406. ];
  407. $this->assertHtml($expected, $result);
  408. }
  409. /**
  410. * Test render with partial groupings.
  411. *
  412. * @return void
  413. */
  414. public function testRenderPartialGrouped()
  415. {
  416. $label = new LabelWidget($this->templates);
  417. $input = new MultiCheckboxWidget($this->templates, $label);
  418. $data = [
  419. 'name' => 'Tags[id]',
  420. 'options' => [
  421. 1 => 'PHP',
  422. 'Group 1' => [
  423. 2 => 'CakePHP',
  424. ],
  425. 3 => 'Development',
  426. ]
  427. ];
  428. $result = $input->render($data, $this->context);
  429. $expected = [
  430. ['div' => ['class' => 'checkbox']],
  431. ['input' => [
  432. 'type' => 'checkbox',
  433. 'name' => 'Tags[id][]',
  434. 'value' => 1,
  435. 'id' => 'tags-id-1',
  436. ]],
  437. ['label' => ['for' => 'tags-id-1']],
  438. 'PHP',
  439. '/label',
  440. '/div',
  441. '<fieldset',
  442. '<legend', 'Group 1', '/legend',
  443. ['div' => ['class' => 'checkbox']],
  444. ['input' => [
  445. 'type' => 'checkbox',
  446. 'name' => 'Tags[id][]',
  447. 'value' => 2,
  448. 'id' => 'tags-id-2',
  449. ]],
  450. ['label' => ['for' => 'tags-id-2']],
  451. 'CakePHP',
  452. '/label',
  453. '/div',
  454. '/fieldset',
  455. ['div' => ['class' => 'checkbox']],
  456. ['input' => [
  457. 'type' => 'checkbox',
  458. 'name' => 'Tags[id][]',
  459. 'value' => 3,
  460. 'id' => 'tags-id-3',
  461. ]],
  462. ['label' => ['for' => 'tags-id-3']],
  463. 'Development',
  464. '/label',
  465. '/div',
  466. ];
  467. $this->assertHtml($expected, $result);
  468. }
  469. /**
  470. * testRenderCustomAttributes method
  471. *
  472. * Test render with custom attributes
  473. *
  474. * @return void
  475. */
  476. public function testRenderCustomAttributes()
  477. {
  478. $label = new LabelWidget($this->templates);
  479. $input = new MultiCheckboxWidget($this->templates, $label);
  480. $result = $input->render([
  481. 'name' => 'category',
  482. 'options' => ['1', '2'],
  483. 'class' => 'my-class',
  484. 'data-ref' => 'custom-attr',
  485. ], $this->context);
  486. $expected = [
  487. ['div' => ['class' => 'checkbox']],
  488. [
  489. 'input' => [
  490. 'type' => 'checkbox',
  491. 'name' => 'category[]',
  492. 'value' => '0',
  493. 'id' => 'category-0',
  494. 'class' => 'my-class',
  495. 'data-ref' => 'custom-attr'
  496. ]
  497. ],
  498. ['label' => ['for' => 'category-0']],
  499. '1',
  500. '/label',
  501. '/div',
  502. ['div' => ['class' => 'checkbox']],
  503. [
  504. 'input' => [
  505. 'type' => 'checkbox',
  506. 'name' => 'category[]',
  507. 'value' => '1',
  508. 'id' => 'category-1',
  509. 'class' => 'my-class',
  510. 'data-ref' => 'custom-attr'
  511. ]
  512. ],
  513. ['label' => ['for' => 'category-1']],
  514. '2',
  515. '/label',
  516. '/div'
  517. ];
  518. $this->assertHtml($expected, $result);
  519. }
  520. }