AssociationCollectionTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://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. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\ORM;
  16. use Cake\ORM\AssociationCollection;
  17. use Cake\ORM\Association\BelongsTo;
  18. use Cake\ORM\Association\BelongsToMany;
  19. use Cake\ORM\Entity;
  20. use Cake\TestSuite\TestCase;
  21. /**
  22. * AssociationCollection test case.
  23. */
  24. class AssociationCollectionTest extends TestCase
  25. {
  26. /**
  27. * setup
  28. *
  29. * @return void
  30. */
  31. public function setUp()
  32. {
  33. parent::setUp();
  34. $this->associations = new AssociationCollection();
  35. }
  36. /**
  37. * Test the simple add/has and get methods.
  38. *
  39. * @return void
  40. */
  41. public function testAddHasRemoveAndGet()
  42. {
  43. $this->assertFalse($this->associations->has('users'));
  44. $this->assertFalse($this->associations->has('Users'));
  45. $this->assertNull($this->associations->get('users'));
  46. $this->assertNull($this->associations->get('Users'));
  47. $belongsTo = new BelongsTo('');
  48. $this->assertSame($belongsTo, $this->associations->add('Users', $belongsTo));
  49. $this->assertTrue($this->associations->has('users'));
  50. $this->assertTrue($this->associations->has('Users'));
  51. $this->assertSame($belongsTo, $this->associations->get('users'));
  52. $this->assertSame($belongsTo, $this->associations->get('Users'));
  53. $this->assertNull($this->associations->remove('Users'));
  54. $this->assertFalse($this->associations->has('users'));
  55. $this->assertFalse($this->associations->has('Users'));
  56. $this->assertNull($this->associations->get('users'));
  57. $this->assertNull($this->associations->get('Users'));
  58. }
  59. /**
  60. * Test removeAll method
  61. *
  62. * @return void
  63. */
  64. public function testRemoveAll()
  65. {
  66. $this->assertEmpty($this->associations->keys());
  67. $belongsTo = new BelongsTo('');
  68. $this->assertSame($belongsTo, $this->associations->add('Users', $belongsTo));
  69. $belongsToMany = new BelongsToMany('');
  70. $this->assertSame($belongsToMany, $this->associations->add('Cart', $belongsToMany));
  71. $this->associations->removeAll();
  72. $this->assertEmpty($this->associations->keys());
  73. }
  74. /**
  75. * Test getting associations by property.
  76. *
  77. * @return void
  78. */
  79. public function testGetByProperty()
  80. {
  81. $belongsTo = new BelongsTo('Users', []);
  82. $this->assertEquals('user', $belongsTo->property());
  83. $this->associations->add('Users', $belongsTo);
  84. $this->assertNull($this->associations->get('user'));
  85. $this->assertSame($belongsTo, $this->associations->getByProperty('user'));
  86. }
  87. /**
  88. * Test associations with plugin names.
  89. *
  90. * @return void
  91. */
  92. public function testAddHasRemoveGetWithPlugin()
  93. {
  94. $this->assertFalse($this->associations->has('Photos.Photos'));
  95. $this->assertFalse($this->associations->has('Photos'));
  96. $belongsTo = new BelongsTo('');
  97. $this->assertSame($belongsTo, $this->associations->add('Photos.Photos', $belongsTo));
  98. $this->assertTrue($this->associations->has('Photos'));
  99. $this->assertFalse($this->associations->has('Photos.Photos'));
  100. }
  101. /**
  102. * Test keys()
  103. *
  104. * @return void
  105. */
  106. public function testKeys()
  107. {
  108. $belongsTo = new BelongsTo('');
  109. $this->associations->add('Users', $belongsTo);
  110. $this->associations->add('Categories', $belongsTo);
  111. $this->assertEquals(['users', 'categories'], $this->associations->keys());
  112. $this->associations->remove('Categories');
  113. $this->assertEquals(['users'], $this->associations->keys());
  114. }
  115. /**
  116. * Test getting association names by type.
  117. *
  118. * @return void
  119. */
  120. public function testType()
  121. {
  122. $belongsTo = new BelongsTo('');
  123. $this->associations->add('Users', $belongsTo);
  124. $belongsToMany = new BelongsToMany('');
  125. $this->associations->add('Tags', $belongsToMany);
  126. $this->assertSame([$belongsTo], $this->associations->type('BelongsTo'));
  127. $this->assertSame([$belongsToMany], $this->associations->type('BelongsToMany'));
  128. $this->assertSame([], $this->associations->type('HasMany'));
  129. $this->assertSame(
  130. [$belongsTo, $belongsToMany],
  131. $this->associations->type(['BelongsTo', 'BelongsToMany'])
  132. );
  133. }
  134. /**
  135. * test cascading deletes.
  136. *
  137. * @return void
  138. */
  139. public function testCascadeDelete()
  140. {
  141. $mockOne = $this->getMock('Cake\ORM\Association\BelongsTo', [], ['']);
  142. $mockTwo = $this->getMock('Cake\ORM\Association\HasMany', [], ['']);
  143. $entity = new Entity();
  144. $options = ['option' => 'value'];
  145. $this->associations->add('One', $mockOne);
  146. $this->associations->add('Two', $mockTwo);
  147. $mockOne->expects($this->once())
  148. ->method('cascadeDelete')
  149. ->with($entity, $options);
  150. $mockTwo->expects($this->once())
  151. ->method('cascadeDelete')
  152. ->with($entity, $options);
  153. $this->assertNull($this->associations->cascadeDelete($entity, $options));
  154. }
  155. /**
  156. * Test saving parent associations
  157. *
  158. * @return void
  159. */
  160. public function testSaveParents()
  161. {
  162. $table = $this->getMock('Cake\ORM\Table', [], [[]]);
  163. $mockOne = $this->getMock(
  164. 'Cake\ORM\Association\BelongsTo',
  165. ['saveAssociated'],
  166. ['Parent', [
  167. 'sourceTable' => $table,
  168. ]]
  169. );
  170. $mockTwo = $this->getMock(
  171. 'Cake\ORM\Association\HasMany',
  172. ['saveAssociated'],
  173. ['Child', [
  174. 'sourceTable' => $table
  175. ]]
  176. );
  177. $this->associations->add('Parent', $mockOne);
  178. $this->associations->add('Child', $mockTwo);
  179. $entity = new Entity();
  180. $entity->set('parent', ['key' => 'value']);
  181. $entity->set('child', ['key' => 'value']);
  182. $options = ['option' => 'value'];
  183. $mockOne->expects($this->once())
  184. ->method('saveAssociated')
  185. ->with($entity, $options)
  186. ->will($this->returnValue(true));
  187. $mockTwo->expects($this->never())
  188. ->method('saveAssociated');
  189. $result = $this->associations->saveParents(
  190. $table,
  191. $entity,
  192. ['Parent', 'Child'],
  193. $options
  194. );
  195. $this->assertTrue($result, 'Save should work.');
  196. }
  197. /**
  198. * Test saving filtered parent associations.
  199. *
  200. * @return void
  201. */
  202. public function testSaveParentsFiltered()
  203. {
  204. $table = $this->getMock('Cake\ORM\Table', [], [[]]);
  205. $mockOne = $this->getMock(
  206. 'Cake\ORM\Association\BelongsTo',
  207. ['saveAssociated'],
  208. ['Parents', [
  209. 'sourceTable' => $table,
  210. ]]
  211. );
  212. $mockTwo = $this->getMock(
  213. 'Cake\ORM\Association\BelongsTo',
  214. ['saveAssociated'],
  215. ['Categories', [
  216. 'sourceTable' => $table
  217. ]]
  218. );
  219. $this->associations->add('Parents', $mockOne);
  220. $this->associations->add('Categories', $mockTwo);
  221. $entity = new Entity();
  222. $entity->set('parent', ['key' => 'value']);
  223. $entity->set('category', ['key' => 'value']);
  224. $options = ['atomic' => true];
  225. $mockOne->expects($this->once())
  226. ->method('saveAssociated')
  227. ->with($entity, ['atomic' => true, 'associated' => ['Others']])
  228. ->will($this->returnValue(true));
  229. $mockTwo->expects($this->never())
  230. ->method('saveAssociated');
  231. $result = $this->associations->saveParents(
  232. $table,
  233. $entity,
  234. ['Parents' => ['associated' => ['Others']]],
  235. $options
  236. );
  237. $this->assertTrue($result, 'Save should work.');
  238. }
  239. /**
  240. * Test saving filtered child associations.
  241. *
  242. * @return void
  243. */
  244. public function testSaveChildrenFiltered()
  245. {
  246. $table = $this->getMock('Cake\ORM\Table', [], [[]]);
  247. $mockOne = $this->getMock(
  248. 'Cake\ORM\Association\HasMany',
  249. ['saveAssociated'],
  250. ['Comments', [
  251. 'sourceTable' => $table,
  252. ]]
  253. );
  254. $mockTwo = $this->getMock(
  255. 'Cake\ORM\Association\HasOne',
  256. ['saveAssociated'],
  257. ['Profiles', [
  258. 'sourceTable' => $table
  259. ]]
  260. );
  261. $this->associations->add('Comments', $mockOne);
  262. $this->associations->add('Profiles', $mockTwo);
  263. $entity = new Entity();
  264. $entity->set('comments', ['key' => 'value']);
  265. $entity->set('profile', ['key' => 'value']);
  266. $options = ['atomic' => true];
  267. $mockOne->expects($this->once())
  268. ->method('saveAssociated')
  269. ->with($entity, $options + ['associated' => ['Other']])
  270. ->will($this->returnValue(true));
  271. $mockTwo->expects($this->never())
  272. ->method('saveAssociated');
  273. $result = $this->associations->saveChildren(
  274. $table,
  275. $entity,
  276. ['Comments' => ['associated' => ['Other']]],
  277. $options
  278. );
  279. $this->assertTrue($result, 'Should succeed.');
  280. }
  281. /**
  282. * Test exceptional case.
  283. *
  284. * @expectedException \InvalidArgumentException
  285. * @expectedExceptionMessage Cannot save Profiles, it is not associated to Users
  286. */
  287. public function testErrorOnUnknownAlias()
  288. {
  289. $table = $this->getMock(
  290. 'Cake\ORM\Table',
  291. ['save'],
  292. [['alias' => 'Users']]
  293. );
  294. $entity = new Entity();
  295. $entity->set('profile', ['key' => 'value']);
  296. $this->associations->saveChildren(
  297. $table,
  298. $entity,
  299. ['Profiles'],
  300. ['atomic' => true]
  301. );
  302. }
  303. /**
  304. * Tests the normalizeKeys method
  305. *
  306. * @return void
  307. */
  308. public function testNormalizeKeys()
  309. {
  310. $this->assertSame([], $this->associations->normalizeKeys([]));
  311. $this->assertSame([], $this->associations->normalizeKeys(false));
  312. $assocs = ['a', 'b', 'd' => ['something']];
  313. $expected = ['a' => [], 'b' => [], 'd' => ['something']];
  314. $this->assertSame($expected, $this->associations->normalizeKeys($assocs));
  315. $belongsTo = new BelongsTo('');
  316. $this->associations->add('users', $belongsTo);
  317. $this->associations->add('categories', $belongsTo);
  318. $expected = ['users' => [], 'categories' => []];
  319. $this->assertSame($expected, $this->associations->normalizeKeys(true));
  320. }
  321. /**
  322. * Ensure that the association collection can be iterated.
  323. *
  324. * @return void
  325. */
  326. public function testAssociationsCanBeIterated()
  327. {
  328. $belongsTo = new BelongsTo('');
  329. $this->associations->add('Users', $belongsTo);
  330. $belongsToMany = new BelongsToMany('');
  331. $this->associations->add('Cart', $belongsToMany);
  332. $expected = ['users' => $belongsTo, 'cart' => $belongsToMany];
  333. $result = iterator_to_array($this->associations, true);
  334. $this->assertSame($expected, $result);
  335. }
  336. }