ArrayContextTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP(tm) Project
  13. * @since 3.0.0
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\Test\TestCase\View\Form;
  17. use Cake\TestSuite\TestCase;
  18. use Cake\View\Form\ArrayContext;
  19. /**
  20. * Array context test case.
  21. */
  22. class ArrayContextTest extends TestCase
  23. {
  24. /**
  25. * setup method.
  26. */
  27. public function setUp(): void
  28. {
  29. parent::setUp();
  30. }
  31. public function testGetRequiredMessage(): void
  32. {
  33. $context = new ArrayContext([
  34. 'required' => [
  35. 'Comments' => [
  36. 'required' => 'My custom message',
  37. 'nope' => false,
  38. 'tags' => true,
  39. ],
  40. ],
  41. ]);
  42. $this->assertSame('My custom message', $context->getRequiredMessage('Comments.required'));
  43. $this->assertSame('This field cannot be left empty', $context->getRequiredMessage('Comments.tags'));
  44. $this->assertSame(null, $context->getRequiredMessage('Comments.nope'));
  45. }
  46. /**
  47. * Test getting the primary key.
  48. */
  49. public function testPrimaryKey(): void
  50. {
  51. $context = new ArrayContext([]);
  52. $this->assertEquals([], $context->getPrimaryKey());
  53. $context = new ArrayContext([
  54. 'schema' => [
  55. '_constraints' => 'mistake',
  56. ],
  57. ]);
  58. $this->assertEquals([], $context->getPrimaryKey());
  59. $data = [
  60. 'schema' => [
  61. '_constraints' => [
  62. 'primary' => ['type' => 'primary', 'columns' => ['id']],
  63. ],
  64. ],
  65. ];
  66. $context = new ArrayContext($data);
  67. $expected = ['id'];
  68. $this->assertEquals($expected, $context->getPrimaryKey());
  69. }
  70. /**
  71. * Test isPrimaryKey.
  72. */
  73. public function testIsPrimaryKey(): void
  74. {
  75. $context = new ArrayContext([]);
  76. $this->assertFalse($context->isPrimaryKey('id'));
  77. $context = new ArrayContext([
  78. 'schema' => [
  79. '_constraints' => 'mistake',
  80. ],
  81. ]);
  82. $this->assertFalse($context->isPrimaryKey('mistake'));
  83. $data = [
  84. 'schema' => [
  85. '_constraints' => [
  86. 'primary' => ['type' => 'primary', 'columns' => ['id']],
  87. ],
  88. ],
  89. ];
  90. $context = new ArrayContext($data);
  91. $this->assertTrue($context->isPrimaryKey('id'));
  92. $this->assertFalse($context->isPrimaryKey('name'));
  93. $data = [
  94. 'schema' => [
  95. '_constraints' => [
  96. 'primary' => ['type' => 'primary', 'columns' => ['id', 'name']],
  97. ],
  98. ],
  99. ];
  100. $context = new ArrayContext($data);
  101. $this->assertTrue($context->isPrimaryKey('id'));
  102. $this->assertTrue($context->isPrimaryKey('name'));
  103. }
  104. /**
  105. * Test the isCreate method.
  106. */
  107. public function testIsCreate(): void
  108. {
  109. $context = new ArrayContext([]);
  110. $this->assertTrue($context->isCreate());
  111. $data = [
  112. 'schema' => [
  113. '_constraints' => [
  114. 'primary' => ['type' => 'primary', 'columns' => ['id']],
  115. ],
  116. ],
  117. ];
  118. $context = new ArrayContext($data);
  119. $this->assertTrue($context->isCreate());
  120. $data['defaults'] = ['id' => 2];
  121. $context = new ArrayContext($data);
  122. $this->assertFalse($context->isCreate());
  123. }
  124. /**
  125. * Test reading values from data & defaults.
  126. */
  127. public function testValPresent(): void
  128. {
  129. $context = new ArrayContext([
  130. 'data' => [
  131. 'Articles' => [
  132. 'title' => 'New title',
  133. 'body' => 'My copy',
  134. ],
  135. ],
  136. 'defaults' => [
  137. 'Articles' => [
  138. 'title' => 'Default value',
  139. 'published' => 0,
  140. ],
  141. ],
  142. ]);
  143. $this->assertSame('New title', $context->val('Articles.title'));
  144. $this->assertSame('My copy', $context->val('Articles.body'));
  145. $this->assertSame(0, $context->val('Articles.published'));
  146. $this->assertNull($context->val('Articles.nope'));
  147. }
  148. /**
  149. * Test getting values when the data and defaults are missing.
  150. */
  151. public function testValMissing(): void
  152. {
  153. $context = new ArrayContext([]);
  154. $this->assertNull($context->val('Comments.field'));
  155. }
  156. /**
  157. * Test getting default value
  158. *
  159. * Tests includes making sure numeric elements are stripped but not keys beginning with numeric
  160. * value
  161. */
  162. public function testValDefault(): void
  163. {
  164. $context = new ArrayContext([
  165. 'defaults' => [
  166. 'title' => 'Default value',
  167. 'users' => ['tags' => 'common1', '9tags' => 'common2'],
  168. ],
  169. ]);
  170. $this->assertSame('Default value', $context->val('title'));
  171. $this->assertSame('common1', $context->val('users.0.tags'));
  172. $this->assertSame('common1', $context->val('users.99.tags'));
  173. $this->assertSame('common2', $context->val('users.9.9tags'));
  174. $result = $context->val('title', ['default' => 'explicit default']);
  175. $this->assertSame('explicit default', $result);
  176. }
  177. /**
  178. * Test isRequired
  179. */
  180. public function testIsRequired(): void
  181. {
  182. $context = new ArrayContext([
  183. 'required' => [
  184. 'Comments' => [
  185. 'required' => true,
  186. 'nope' => false,
  187. 'tags' => true,
  188. ],
  189. ],
  190. ]);
  191. $this->assertTrue($context->isRequired('Comments.required'));
  192. $this->assertFalse($context->isRequired('Comments.nope'));
  193. $this->assertTrue($context->isRequired('Comments.0.tags'));
  194. $this->assertNull($context->isRequired('Articles.id'));
  195. }
  196. /**
  197. * Test isRequired when the required key is omitted
  198. */
  199. public function testIsRequiredUndefined(): void
  200. {
  201. $context = new ArrayContext([]);
  202. $this->assertNull($context->isRequired('Comments.field'));
  203. }
  204. /**
  205. * Test the type method.
  206. */
  207. public function testType(): void
  208. {
  209. $context = new ArrayContext([
  210. 'schema' => [
  211. 'Comments' => [
  212. 'id' => ['type' => 'integer'],
  213. 'tags' => ['type' => 'string'],
  214. 'comment' => ['length' => 255],
  215. ],
  216. ],
  217. ]);
  218. $this->assertNull($context->type('Comments.undefined'));
  219. $this->assertSame('integer', $context->type('Comments.id'));
  220. $this->assertSame('string', $context->type('Comments.0.tags'));
  221. $this->assertNull($context->type('Comments.comment'));
  222. }
  223. /**
  224. * Test the type method when the data is missing.
  225. */
  226. public function testIsTypeUndefined(): void
  227. {
  228. $context = new ArrayContext([]);
  229. $this->assertNull($context->type('Comments.undefined'));
  230. }
  231. /**
  232. * Test fetching attributes.
  233. */
  234. public function testAttributes(): void
  235. {
  236. $context = new ArrayContext([
  237. 'schema' => [
  238. 'Comments' => [
  239. 'id' => ['type' => 'integer'],
  240. 'comment' => ['type' => 'string', 'length' => 255],
  241. 'decimal' => ['type' => 'decimal', 'precision' => 2, 'length' => 5],
  242. 'floaty' => ['type' => 'float', 'precision' => 2, 'length' => 5],
  243. 'tags' => ['type' => 'string', 'length' => 25],
  244. ],
  245. ],
  246. ]);
  247. $this->assertEquals([], $context->attributes('Comments.id'));
  248. $this->assertEquals(['length' => 25], $context->attributes('Comments.0.tags'));
  249. $this->assertEquals(['length' => 255], $context->attributes('Comments.comment'));
  250. $this->assertEquals(['precision' => 2, 'length' => 5], $context->attributes('Comments.decimal'));
  251. $this->assertEquals(['precision' => 2, 'length' => 5], $context->attributes('Comments.floaty'));
  252. }
  253. /**
  254. * Test fetching errors.
  255. */
  256. public function testError(): void
  257. {
  258. $context = new ArrayContext([]);
  259. $this->assertEquals([], $context->error('Comments.empty'));
  260. $context = new ArrayContext([
  261. 'errors' => [
  262. 'Comments' => [
  263. 'comment' => ['Comment is required'],
  264. 'empty' => [],
  265. 'user_id' => 'A valid userid is required',
  266. ],
  267. ],
  268. ]);
  269. $this->assertEquals(['Comment is required'], $context->error('Comments.comment'));
  270. $this->assertEquals(['A valid userid is required'], $context->error('Comments.user_id'));
  271. $this->assertEquals([], $context->error('Comments.empty'));
  272. $this->assertEquals([], $context->error('Comments.not_there'));
  273. }
  274. /**
  275. * Test checking errors.
  276. */
  277. public function testHasError(): void
  278. {
  279. $context = new ArrayContext([
  280. 'errors' => [
  281. 'Comments' => [
  282. 'comment' => ['Comment is required'],
  283. 'empty' => [],
  284. 'user_id' => 'A valid userid is required',
  285. ],
  286. ],
  287. ]);
  288. $this->assertFalse($context->hasError('Comments.not_there'));
  289. $this->assertFalse($context->hasError('Comments.empty'));
  290. $this->assertTrue($context->hasError('Comments.user_id'));
  291. $this->assertTrue($context->hasError('Comments.comment'));
  292. }
  293. }