AssociationCollectionTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  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. }
  130. /**
  131. * test cascading deletes.
  132. *
  133. * @return void
  134. */
  135. public function testCascadeDelete()
  136. {
  137. $mockOne = $this->getMock('Cake\ORM\Association\BelongsTo', [], ['']);
  138. $mockTwo = $this->getMock('Cake\ORM\Association\HasMany', [], ['']);
  139. $entity = new Entity();
  140. $options = ['option' => 'value'];
  141. $this->associations->add('One', $mockOne);
  142. $this->associations->add('Two', $mockTwo);
  143. $mockOne->expects($this->once())
  144. ->method('cascadeDelete')
  145. ->with($entity, $options);
  146. $mockTwo->expects($this->once())
  147. ->method('cascadeDelete')
  148. ->with($entity, $options);
  149. $this->assertNull($this->associations->cascadeDelete($entity, $options));
  150. }
  151. /**
  152. * Test saving parent associations
  153. *
  154. * @return void
  155. */
  156. public function testSaveParents()
  157. {
  158. $table = $this->getMock('Cake\ORM\Table', [], [[]]);
  159. $mockOne = $this->getMock(
  160. 'Cake\ORM\Association\BelongsTo',
  161. ['saveAssociated'],
  162. ['Parent', [
  163. 'sourceTable' => $table,
  164. ]]
  165. );
  166. $mockTwo = $this->getMock(
  167. 'Cake\ORM\Association\HasMany',
  168. ['saveAssociated'],
  169. ['Child', [
  170. 'sourceTable' => $table
  171. ]]
  172. );
  173. $this->associations->add('Parent', $mockOne);
  174. $this->associations->add('Child', $mockTwo);
  175. $entity = new Entity();
  176. $entity->set('parent', ['key' => 'value']);
  177. $entity->set('child', ['key' => 'value']);
  178. $options = ['option' => 'value'];
  179. $mockOne->expects($this->once())
  180. ->method('saveAssociated')
  181. ->with($entity, $options)
  182. ->will($this->returnValue(true));
  183. $mockTwo->expects($this->never())
  184. ->method('saveAssociated');
  185. $result = $this->associations->saveParents(
  186. $table,
  187. $entity,
  188. ['Parent', 'Child'],
  189. $options
  190. );
  191. $this->assertTrue($result, 'Save should work.');
  192. }
  193. /**
  194. * Test saving filtered parent associations.
  195. *
  196. * @return void
  197. */
  198. public function testSaveParentsFiltered()
  199. {
  200. $table = $this->getMock('Cake\ORM\Table', [], [[]]);
  201. $mockOne = $this->getMock(
  202. 'Cake\ORM\Association\BelongsTo',
  203. ['saveAssociated'],
  204. ['Parents', [
  205. 'sourceTable' => $table,
  206. ]]
  207. );
  208. $mockTwo = $this->getMock(
  209. 'Cake\ORM\Association\BelongsTo',
  210. ['saveAssociated'],
  211. ['Categories', [
  212. 'sourceTable' => $table
  213. ]]
  214. );
  215. $this->associations->add('Parents', $mockOne);
  216. $this->associations->add('Categories', $mockTwo);
  217. $entity = new Entity();
  218. $entity->set('parent', ['key' => 'value']);
  219. $entity->set('category', ['key' => 'value']);
  220. $options = ['atomic' => true];
  221. $mockOne->expects($this->once())
  222. ->method('saveAssociated')
  223. ->with($entity, ['atomic' => true, 'associated' => ['Others']])
  224. ->will($this->returnValue(true));
  225. $mockTwo->expects($this->never())
  226. ->method('saveAssociated');
  227. $result = $this->associations->saveParents(
  228. $table,
  229. $entity,
  230. ['Parents' => ['associated' => ['Others']]],
  231. $options
  232. );
  233. $this->assertTrue($result, 'Save should work.');
  234. }
  235. /**
  236. * Test saving filtered child associations.
  237. *
  238. * @return void
  239. */
  240. public function testSaveChildrenFiltered()
  241. {
  242. $table = $this->getMock('Cake\ORM\Table', [], [[]]);
  243. $mockOne = $this->getMock(
  244. 'Cake\ORM\Association\HasMany',
  245. ['saveAssociated'],
  246. ['Comments', [
  247. 'sourceTable' => $table,
  248. ]]
  249. );
  250. $mockTwo = $this->getMock(
  251. 'Cake\ORM\Association\HasOne',
  252. ['saveAssociated'],
  253. ['Profiles', [
  254. 'sourceTable' => $table
  255. ]]
  256. );
  257. $this->associations->add('Comments', $mockOne);
  258. $this->associations->add('Profiles', $mockTwo);
  259. $entity = new Entity();
  260. $entity->set('comments', ['key' => 'value']);
  261. $entity->set('profile', ['key' => 'value']);
  262. $options = ['atomic' => true];
  263. $mockOne->expects($this->once())
  264. ->method('saveAssociated')
  265. ->with($entity, $options + ['associated' => ['Other']])
  266. ->will($this->returnValue(true));
  267. $mockTwo->expects($this->never())
  268. ->method('saveAssociated');
  269. $result = $this->associations->saveChildren(
  270. $table,
  271. $entity,
  272. ['Comments' => ['associated' => ['Other']]],
  273. $options
  274. );
  275. $this->assertTrue($result, 'Should succeed.');
  276. }
  277. /**
  278. * Test exceptional case.
  279. *
  280. * @expectedException \InvalidArgumentException
  281. * @expectedExceptionMessage Cannot save Profiles, it is not associated to Users
  282. */
  283. public function testErrorOnUnknownAlias()
  284. {
  285. $table = $this->getMock(
  286. 'Cake\ORM\Table',
  287. ['save'],
  288. [['alias' => 'Users']]
  289. );
  290. $entity = new Entity();
  291. $entity->set('profile', ['key' => 'value']);
  292. $this->associations->saveChildren(
  293. $table,
  294. $entity,
  295. ['Profiles'],
  296. ['atomic' => true]
  297. );
  298. }
  299. /**
  300. * Tests the normalizeKeys method
  301. *
  302. * @return void
  303. */
  304. public function testNormalizeKeys()
  305. {
  306. $this->assertSame([], $this->associations->normalizeKeys([]));
  307. $this->assertSame([], $this->associations->normalizeKeys(false));
  308. $assocs = ['a', 'b', 'd' => ['something']];
  309. $expected = ['a' => [], 'b' => [], 'd' => ['something']];
  310. $this->assertSame($expected, $this->associations->normalizeKeys($assocs));
  311. $belongsTo = new BelongsTo('');
  312. $this->associations->add('users', $belongsTo);
  313. $this->associations->add('categories', $belongsTo);
  314. $expected = ['users' => [], 'categories' => []];
  315. $this->assertSame($expected, $this->associations->normalizeKeys(true));
  316. }
  317. }