TreeBehaviorNumberTest.php 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510
  1. <?php
  2. /**
  3. * TreeBehaviorNumberTest file
  4. *
  5. * This is the basic Tree behavior test
  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.Model.Behavior
  17. * @since CakePHP(tm) v 1.2.0.5330
  18. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  19. */
  20. App::uses('Model', 'Model');
  21. App::uses('AppModel', 'Model');
  22. require_once dirname(dirname(__FILE__)) . DS . 'models.php';
  23. /**
  24. * TreeBehaviorNumberTest class
  25. *
  26. * @package Cake.Test.Case.Model.Behavior
  27. */
  28. class TreeBehaviorNumberTest extends CakeTestCase {
  29. /**
  30. * Whether backup global state for each test method or not
  31. *
  32. * @var bool
  33. */
  34. public $backupGlobals = false;
  35. /**
  36. * settings property
  37. *
  38. * @var array
  39. */
  40. public $settings = array(
  41. 'modelClass' => 'NumberTree',
  42. 'leftField' => 'lft',
  43. 'rightField' => 'rght',
  44. 'parentField' => 'parent_id'
  45. );
  46. /**
  47. * fixtures property
  48. *
  49. * @var array
  50. */
  51. public $fixtures = array('core.number_tree', 'core.person');
  52. /**
  53. * testInitialize method
  54. *
  55. * @return void
  56. */
  57. public function testInitialize() {
  58. extract($this->settings);
  59. $this->Tree = new $modelClass();
  60. $this->Tree->initialize(2, 2);
  61. $result = $this->Tree->find('count');
  62. $this->assertEquals(7, $result);
  63. $validTree = $this->Tree->verify();
  64. $this->assertTrue($validTree);
  65. }
  66. /**
  67. * testDetectInvalidLeft method
  68. *
  69. * @return void
  70. */
  71. public function testDetectInvalidLeft() {
  72. extract($this->settings);
  73. $this->Tree = new $modelClass();
  74. $this->Tree->initialize(2, 2);
  75. $result = $this->Tree->findByName('1.1');
  76. $save[$modelClass]['id'] = $result[$modelClass]['id'];
  77. $save[$modelClass][$leftField] = 0;
  78. $this->Tree->create();
  79. $this->Tree->save($save);
  80. $result = $this->Tree->verify();
  81. $this->assertNotSame(true, $result);
  82. $result = $this->Tree->recover();
  83. $this->assertTrue($result);
  84. $result = $this->Tree->verify();
  85. $this->assertTrue($result);
  86. }
  87. /**
  88. * testDetectInvalidRight method
  89. *
  90. * @return void
  91. */
  92. public function testDetectInvalidRight() {
  93. extract($this->settings);
  94. $this->Tree = new $modelClass();
  95. $this->Tree->initialize(2, 2);
  96. $result = $this->Tree->findByName('1.1');
  97. $save[$modelClass]['id'] = $result[$modelClass]['id'];
  98. $save[$modelClass][$rightField] = 0;
  99. $this->Tree->create();
  100. $this->Tree->save($save);
  101. $result = $this->Tree->verify();
  102. $this->assertNotSame(true, $result);
  103. $result = $this->Tree->recover();
  104. $this->assertTrue($result);
  105. $result = $this->Tree->verify();
  106. $this->assertTrue($result);
  107. }
  108. /**
  109. * testDetectInvalidParent method
  110. *
  111. * @return void
  112. */
  113. public function testDetectInvalidParent() {
  114. extract($this->settings);
  115. $this->Tree = new $modelClass();
  116. $this->Tree->initialize(2, 2);
  117. $result = $this->Tree->findByName('1.1');
  118. // Bypass behavior and any other logic
  119. $this->Tree->updateAll(array($parentField => null), array('id' => $result[$modelClass]['id']));
  120. $result = $this->Tree->verify();
  121. $this->assertNotSame(true, $result);
  122. $result = $this->Tree->recover();
  123. $this->assertTrue($result);
  124. $result = $this->Tree->verify();
  125. $this->assertTrue($result);
  126. }
  127. /**
  128. * testDetectNoneExistentParent method
  129. *
  130. * @return void
  131. */
  132. public function testDetectNoneExistentParent() {
  133. extract($this->settings);
  134. $this->Tree = new $modelClass();
  135. $this->Tree->initialize(2, 2);
  136. $result = $this->Tree->findByName('1.1');
  137. $this->Tree->updateAll(array($parentField => 999999), array('id' => $result[$modelClass]['id']));
  138. $result = $this->Tree->verify();
  139. $this->assertNotSame(true, $result);
  140. $result = $this->Tree->recover('MPTT');
  141. $this->assertTrue($result);
  142. $result = $this->Tree->verify();
  143. $this->assertTrue($result);
  144. }
  145. /**
  146. * testRecoverUsingParentMode method
  147. *
  148. * @return void
  149. */
  150. public function testRecoverUsingParentMode() {
  151. extract($this->settings);
  152. $this->Tree = new $modelClass();
  153. $this->Tree->Behaviors->disable('Tree');
  154. $this->Tree->create();
  155. $this->Tree->save(array('name' => 'Main', $parentField => null, $leftField => 0, $rightField => 0));
  156. $node1 = $this->Tree->id;
  157. $this->Tree->create();
  158. $this->Tree->save(array('name' => 'About Us', $parentField => $node1, $leftField => 0, $rightField => 0));
  159. $node11 = $this->Tree->id;
  160. $this->Tree->create();
  161. $this->Tree->save(array('name' => 'Programs', $parentField => $node1, $leftField => 0, $rightField => 0));
  162. $node12 = $this->Tree->id;
  163. $this->Tree->create();
  164. $this->Tree->save(array('name' => 'Mission and History', $parentField => $node11, $leftField => 0, $rightField => 0));
  165. $this->Tree->create();
  166. $this->Tree->save(array('name' => 'Overview', $parentField => $node12, $leftField => 0, $rightField => 0));
  167. $this->Tree->Behaviors->enable('Tree');
  168. $result = $this->Tree->verify();
  169. $this->assertNotSame(true, $result);
  170. $result = $this->Tree->recover();
  171. $this->assertTrue($result);
  172. $result = $this->Tree->verify();
  173. $this->assertTrue($result);
  174. $result = $this->Tree->find('first', array(
  175. 'fields' => array('name', $parentField, $leftField, $rightField),
  176. 'conditions' => array('name' => 'Main'),
  177. 'recursive' => -1
  178. ));
  179. $expected = array(
  180. $modelClass => array(
  181. 'name' => 'Main',
  182. $parentField => null,
  183. $leftField => 1,
  184. $rightField => 10
  185. )
  186. );
  187. $this->assertEquals($expected, $result);
  188. }
  189. /**
  190. * testRecoverUsingParentModeAndDelete method
  191. *
  192. * @return void
  193. */
  194. public function testRecoverUsingParentModeAndDelete() {
  195. extract($this->settings);
  196. $this->Tree = new $modelClass();
  197. $this->Tree->Behaviors->disable('Tree');
  198. $this->Tree->create();
  199. $this->Tree->save(array('name' => 'Main', $parentField => null, $leftField => 0, $rightField => 0));
  200. $node1 = $this->Tree->id;
  201. $this->Tree->create();
  202. $this->Tree->save(array('name' => 'About Us', $parentField => $node1, $leftField => 0, $rightField => 0));
  203. $node11 = $this->Tree->id;
  204. $this->Tree->create();
  205. $this->Tree->save(array('name' => 'Programs', $parentField => $node1, $leftField => 0, $rightField => 0));
  206. $node12 = $this->Tree->id;
  207. $this->Tree->create();
  208. $this->Tree->save(array('name' => 'Mission and History', $parentField => $node11, $leftField => 0, $rightField => 0));
  209. $this->Tree->create();
  210. $this->Tree->save(array('name' => 'Overview', $parentField => $node12, $leftField => 0, $rightField => 0));
  211. $this->Tree->create();
  212. $this->Tree->save(array('name' => 'Lost', $parentField => 9, $leftField => 0, $rightField => 0));
  213. $this->Tree->Behaviors->enable('Tree');
  214. $this->Tree->bindModel(array('belongsTo' => array('Parent' => array(
  215. 'className' => $this->Tree->name,
  216. 'foreignKey' => $parentField
  217. ))));
  218. $this->Tree->bindModel(array('hasMany' => array('Child' => array(
  219. 'className' => $this->Tree->name,
  220. 'foreignKey' => $parentField
  221. ))));
  222. $result = $this->Tree->verify();
  223. $this->assertNotSame(true, $result);
  224. $count = $this->Tree->find('count');
  225. $this->assertEquals(6, $count);
  226. $result = $this->Tree->recover('parent', 'delete');
  227. $this->assertTrue($result);
  228. $result = $this->Tree->verify();
  229. $this->assertTrue($result);
  230. $count = $this->Tree->find('count');
  231. $this->assertEquals(5, $count);
  232. $result = $this->Tree->find('first', array(
  233. 'fields' => array('name', $parentField, $leftField, $rightField),
  234. 'conditions' => array('name' => 'Main'),
  235. 'recursive' => -1
  236. ));
  237. $expected = array(
  238. $modelClass => array(
  239. 'name' => 'Main',
  240. $parentField => null,
  241. $leftField => 1,
  242. $rightField => 10
  243. )
  244. );
  245. $this->assertEquals($expected, $result);
  246. }
  247. /**
  248. * testRecoverFromMissingParent method
  249. *
  250. * @return void
  251. */
  252. public function testRecoverFromMissingParent() {
  253. extract($this->settings);
  254. $this->Tree = new $modelClass();
  255. $this->Tree->initialize(2, 2);
  256. $result = $this->Tree->findByName('1.1');
  257. $this->Tree->updateAll(array($parentField => 999999), array('id' => $result[$modelClass]['id']));
  258. $result = $this->Tree->verify();
  259. $this->assertNotSame(true, $result);
  260. $result = $this->Tree->recover();
  261. $this->assertTrue($result);
  262. $result = $this->Tree->verify();
  263. $this->assertTrue($result);
  264. }
  265. /**
  266. * testDetectInvalidParents method
  267. *
  268. * @return void
  269. */
  270. public function testDetectInvalidParents() {
  271. extract($this->settings);
  272. $this->Tree = new $modelClass();
  273. $this->Tree->initialize(2, 2);
  274. $this->Tree->updateAll(array($parentField => null));
  275. $result = $this->Tree->verify();
  276. $this->assertNotSame(true, $result);
  277. $result = $this->Tree->recover();
  278. $this->assertTrue($result);
  279. $result = $this->Tree->verify();
  280. $this->assertTrue($result);
  281. }
  282. /**
  283. * testDetectInvalidLftsRghts method
  284. *
  285. * @return void
  286. */
  287. public function testDetectInvalidLftsRghts() {
  288. extract($this->settings);
  289. $this->Tree = new $modelClass();
  290. $this->Tree->initialize(2, 2);
  291. $this->Tree->updateAll(array($leftField => 0, $rightField => 0));
  292. $result = $this->Tree->verify();
  293. $this->assertNotSame(true, $result);
  294. $this->Tree->recover();
  295. $result = $this->Tree->verify();
  296. $this->assertTrue($result);
  297. }
  298. /**
  299. * Reproduces a situation where a single node has lft= rght, and all other lft and rght fields follow sequentially
  300. *
  301. * @return void
  302. */
  303. public function testDetectEqualLftsRghts() {
  304. extract($this->settings);
  305. $this->Tree = new $modelClass();
  306. $this->Tree->initialize(1, 3);
  307. $result = $this->Tree->findByName('1.1');
  308. $this->Tree->updateAll(array($rightField => $result[$modelClass][$leftField]), array('id' => $result[$modelClass]['id']));
  309. $this->Tree->updateAll(array($leftField => $this->Tree->escapeField($leftField) . ' -1'),
  310. array($leftField . ' >' => $result[$modelClass][$leftField]));
  311. $this->Tree->updateAll(array($rightField => $this->Tree->escapeField($rightField) . ' -1'),
  312. array($rightField . ' >' => $result[$modelClass][$leftField]));
  313. $result = $this->Tree->verify();
  314. $this->assertNotSame(true, $result);
  315. $result = $this->Tree->recover();
  316. $this->assertTrue($result);
  317. $result = $this->Tree->verify();
  318. $this->assertTrue($result);
  319. }
  320. /**
  321. * testAddOrphan method
  322. *
  323. * @return void
  324. */
  325. public function testAddOrphan() {
  326. extract($this->settings);
  327. $this->Tree = new $modelClass();
  328. $this->Tree->initialize(2, 2);
  329. $this->Tree->create();
  330. $this->Tree->save(array($modelClass => array('name' => 'testAddOrphan', $parentField => null)));
  331. $result = $this->Tree->find('first', array('fields' => array('name', $parentField), 'order' => $modelClass . '.' . $leftField . ' desc'));
  332. $expected = array($modelClass => array('name' => 'testAddOrphan', $parentField => null));
  333. $this->assertEquals($expected, $result);
  334. $validTree = $this->Tree->verify();
  335. $this->assertTrue($validTree);
  336. }
  337. /**
  338. * testAddMiddle method
  339. *
  340. * @return void
  341. */
  342. public function testAddMiddle() {
  343. extract($this->settings);
  344. $this->Tree = new $modelClass();
  345. $this->Tree->initialize(2, 2);
  346. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
  347. $initialCount = $this->Tree->find('count');
  348. $this->Tree->create();
  349. $result = $this->Tree->save(array($modelClass => array('name' => 'testAddMiddle', $parentField => $data[$modelClass]['id'])));
  350. $expected = array_merge(array($modelClass => array('name' => 'testAddMiddle', $parentField => '2')), $result);
  351. $this->assertSame($expected, $result);
  352. $laterCount = $this->Tree->find('count');
  353. $this->assertEquals($initialCount + 1, $laterCount);
  354. $children = $this->Tree->children($data[$modelClass]['id'], true, array('name'));
  355. $expected = array(array($modelClass => array('name' => '1.1.1')),
  356. array($modelClass => array('name' => '1.1.2')),
  357. array($modelClass => array('name' => 'testAddMiddle')));
  358. $this->assertSame($expected, $children);
  359. $validTree = $this->Tree->verify();
  360. $this->assertTrue($validTree);
  361. }
  362. /**
  363. * testAddWithPreSpecifiedId method
  364. *
  365. * @return void
  366. */
  367. public function testAddWithPreSpecifiedId() {
  368. extract($this->settings);
  369. $this->Tree = new $modelClass();
  370. $this->Tree->initialize(2, 2);
  371. $data = $this->Tree->find('first', array(
  372. 'fields' => array('id'),
  373. 'conditions' => array($modelClass . '.name' => '1.1')
  374. ));
  375. $this->Tree->create();
  376. $result = $this->Tree->save(array($modelClass => array(
  377. 'id' => 100,
  378. 'name' => 'testAddMiddle',
  379. $parentField => $data[$modelClass]['id'])
  380. ));
  381. $expected = array_merge(
  382. array($modelClass => array('id' => 100, 'name' => 'testAddMiddle', $parentField => '2')),
  383. $result
  384. );
  385. $this->assertSame($expected, $result);
  386. $this->assertTrue($this->Tree->verify());
  387. }
  388. /**
  389. * testAddInvalid method
  390. *
  391. * @return void
  392. */
  393. public function testAddInvalid() {
  394. extract($this->settings);
  395. $this->Tree = new $modelClass();
  396. $this->Tree->initialize(2, 2);
  397. $this->Tree->id = null;
  398. $initialCount = $this->Tree->find('count');
  399. //$this->expectError('Trying to save a node under a none-existant node in TreeBehavior::beforeSave');
  400. $this->Tree->create();
  401. $saveSuccess = $this->Tree->save(array($modelClass => array('name' => 'testAddInvalid', $parentField => 99999)));
  402. $this->assertFalse($saveSuccess);
  403. $laterCount = $this->Tree->find('count');
  404. $this->assertSame($initialCount, $laterCount);
  405. $validTree = $this->Tree->verify();
  406. $this->assertTrue($validTree);
  407. }
  408. /**
  409. * testAddNotIndexedByModel method
  410. *
  411. * @return void
  412. */
  413. public function testAddNotIndexedByModel() {
  414. extract($this->settings);
  415. $this->Tree = new $modelClass();
  416. $this->Tree->initialize(2, 2);
  417. $this->Tree->create();
  418. $this->Tree->save(array('name' => 'testAddNotIndexed', $parentField => null));
  419. $result = $this->Tree->find('first', array('fields' => array('name', $parentField), 'order' => $modelClass . '.' . $leftField . ' desc'));
  420. $expected = array($modelClass => array('name' => 'testAddNotIndexed', $parentField => null));
  421. $this->assertEquals($expected, $result);
  422. $validTree = $this->Tree->verify();
  423. $this->assertTrue($validTree);
  424. }
  425. /**
  426. * testMovePromote method
  427. *
  428. * @return void
  429. */
  430. public function testMovePromote() {
  431. extract($this->settings);
  432. $this->Tree = new $modelClass();
  433. $this->Tree->initialize(2, 2);
  434. $this->Tree->id = null;
  435. $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
  436. $parentId = $parent[$modelClass]['id'];
  437. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
  438. $this->Tree->id = $data[$modelClass]['id'];
  439. $this->Tree->saveField($parentField, $parentId);
  440. $direct = $this->Tree->children($parentId, true, array('id', 'name', $parentField, $leftField, $rightField));
  441. $expected = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 5)),
  442. array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 6, $rightField => 11)),
  443. array($modelClass => array('id' => 3, 'name' => '1.1.1', $parentField => 1, $leftField => 12, $rightField => 13)));
  444. $this->assertEquals($expected, $direct);
  445. $validTree = $this->Tree->verify();
  446. $this->assertTrue($validTree);
  447. }
  448. /**
  449. * testMoveWithWhitelist method
  450. *
  451. * @return void
  452. */
  453. public function testMoveWithWhitelist() {
  454. extract($this->settings);
  455. $this->Tree = new $modelClass();
  456. $this->Tree->initialize(2, 2);
  457. $this->Tree->id = null;
  458. $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
  459. $parentId = $parent[$modelClass]['id'];
  460. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
  461. $this->Tree->id = $data[$modelClass]['id'];
  462. $this->Tree->whitelist = array($parentField, 'name', 'description');
  463. $this->Tree->saveField($parentField, $parentId);
  464. $result = $this->Tree->children($parentId, true, array('id', 'name', $parentField, $leftField, $rightField));
  465. $expected = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 5)),
  466. array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 6, $rightField => 11)),
  467. array($modelClass => array('id' => 3, 'name' => '1.1.1', $parentField => 1, $leftField => 12, $rightField => 13)));
  468. $this->assertEquals($expected, $result);
  469. $this->assertTrue($this->Tree->verify());
  470. }
  471. /**
  472. * testInsertWithWhitelist method
  473. *
  474. * @return void
  475. */
  476. public function testInsertWithWhitelist() {
  477. extract($this->settings);
  478. $this->Tree = new $modelClass();
  479. $this->Tree->initialize(2, 2);
  480. $this->Tree->whitelist = array('name', $parentField);
  481. $this->Tree->create();
  482. $this->Tree->save(array($modelClass => array('name' => 'testAddOrphan', $parentField => null)));
  483. $result = $this->Tree->findByName('testAddOrphan', array('name', $parentField, $leftField, $rightField));
  484. $expected = array('name' => 'testAddOrphan', $parentField => null, $leftField => '15', $rightField => 16);
  485. $this->assertEquals($expected, $result[$modelClass]);
  486. $this->assertTrue($this->Tree->verify());
  487. }
  488. /**
  489. * testMoveBefore method
  490. *
  491. * @return void
  492. */
  493. public function testMoveBefore() {
  494. extract($this->settings);
  495. $this->Tree = new $modelClass();
  496. $this->Tree->initialize(2, 2);
  497. $this->Tree->id = null;
  498. $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.1')));
  499. $parentId = $parent[$modelClass]['id'];
  500. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.2')));
  501. $this->Tree->id = $data[$modelClass]['id'];
  502. $this->Tree->saveField($parentField, $parentId);
  503. $result = $this->Tree->children($parentId, true, array('name'));
  504. $expected = array(array($modelClass => array('name' => '1.1.1')),
  505. array($modelClass => array('name' => '1.1.2')),
  506. array($modelClass => array('name' => '1.2')));
  507. $this->assertEquals($expected, $result);
  508. $validTree = $this->Tree->verify();
  509. $this->assertTrue($validTree);
  510. }
  511. /**
  512. * testMoveAfter method
  513. *
  514. * @return void
  515. */
  516. public function testMoveAfter() {
  517. extract($this->settings);
  518. $this->Tree = new $modelClass();
  519. $this->Tree->initialize(2, 2);
  520. $this->Tree->id = null;
  521. $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.2')));
  522. $parentId = $parent[$modelClass]['id'];
  523. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
  524. $this->Tree->id = $data[$modelClass]['id'];
  525. $this->Tree->saveField($parentField, $parentId);
  526. $result = $this->Tree->children($parentId, true, array('name'));
  527. $expected = array(array($modelClass => array('name' => '1.2.1')),
  528. array($modelClass => array('name' => '1.2.2')),
  529. array($modelClass => array('name' => '1.1')));
  530. $this->assertEquals($expected, $result);
  531. $validTree = $this->Tree->verify();
  532. $this->assertTrue($validTree);
  533. }
  534. /**
  535. * testMoveDemoteInvalid method
  536. *
  537. * @return void
  538. */
  539. public function testMoveDemoteInvalid() {
  540. extract($this->settings);
  541. $this->Tree = new $modelClass();
  542. $this->Tree->initialize(2, 2);
  543. $this->Tree->id = null;
  544. $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
  545. $parentId = $parent[$modelClass]['id'];
  546. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
  547. $expected = $this->Tree->find('all');
  548. $before = $this->Tree->read(null, $data[$modelClass]['id']);
  549. $this->Tree->id = $parentId;
  550. $this->Tree->saveField($parentField, $data[$modelClass]['id']);
  551. $results = $this->Tree->find('all');
  552. $after = $this->Tree->read(null, $data[$modelClass]['id']);
  553. $this->assertEquals($expected, $results);
  554. $this->assertEquals($before, $after);
  555. $validTree = $this->Tree->verify();
  556. $this->assertTrue($validTree);
  557. }
  558. /**
  559. * testMoveInvalid method
  560. *
  561. * @return void
  562. */
  563. public function testMoveInvalid() {
  564. extract($this->settings);
  565. $this->Tree = new $modelClass();
  566. $this->Tree->initialize(2, 2);
  567. $this->Tree->id = null;
  568. $initialCount = $this->Tree->find('count');
  569. $data = $this->Tree->findByName('1.1');
  570. $this->Tree->id = $data[$modelClass]['id'];
  571. $this->Tree->saveField($parentField, 999999);
  572. $laterCount = $this->Tree->find('count');
  573. $this->assertSame($initialCount, $laterCount);
  574. $validTree = $this->Tree->verify();
  575. $this->assertTrue($validTree);
  576. }
  577. /**
  578. * testMoveSelfInvalid method
  579. *
  580. * @return void
  581. */
  582. public function testMoveSelfInvalid() {
  583. extract($this->settings);
  584. $this->Tree = new $modelClass();
  585. $this->Tree->initialize(2, 2);
  586. $this->Tree->id = null;
  587. $initialCount = $this->Tree->find('count');
  588. $data = $this->Tree->findByName('1.1');
  589. $this->Tree->id = $data[$modelClass]['id'];
  590. $saveSuccess = $this->Tree->saveField($parentField, $this->Tree->id);
  591. $this->assertFalse($saveSuccess);
  592. $laterCount = $this->Tree->find('count');
  593. $this->assertSame($initialCount, $laterCount);
  594. $validTree = $this->Tree->verify();
  595. $this->assertTrue($validTree);
  596. }
  597. /**
  598. * testMoveUpSuccess method
  599. *
  600. * @return void
  601. */
  602. public function testMoveUpSuccess() {
  603. extract($this->settings);
  604. $this->Tree = new $modelClass();
  605. $this->Tree->initialize(2, 2);
  606. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.2')));
  607. $this->Tree->moveUp($data[$modelClass]['id']);
  608. $parent = $this->Tree->findByName('1. Root', array('id'));
  609. $this->Tree->id = $parent[$modelClass]['id'];
  610. $result = $this->Tree->children(null, true, array('name'));
  611. $expected = array(array($modelClass => array('name' => '1.2')),
  612. array($modelClass => array('name' => '1.1')));
  613. $this->assertSame($expected, $result);
  614. }
  615. /**
  616. * testMoveUpFail method
  617. *
  618. * @return void
  619. */
  620. public function testMoveUpFail() {
  621. extract($this->settings);
  622. $this->Tree = new $modelClass();
  623. $this->Tree->initialize(2, 2);
  624. $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.1')));
  625. $this->Tree->moveUp($data[$modelClass]['id']);
  626. $parent = $this->Tree->findByName('1. Root', array('id'));
  627. $this->Tree->id = $parent[$modelClass]['id'];
  628. $result = $this->Tree->children(null, true, array('name'));
  629. $expected = array(array($modelClass => array('name' => '1.1')),
  630. array($modelClass => array('name' => '1.2')));
  631. $this->assertSame($expected, $result);
  632. }
  633. /**
  634. * testMoveUp2 method
  635. *
  636. * @return void
  637. */
  638. public function testMoveUp2() {
  639. extract($this->settings);
  640. $this->Tree = new $modelClass();
  641. $this->Tree->initialize(1, 10);
  642. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
  643. $this->Tree->moveUp($data[$modelClass]['id'], 2);
  644. $parent = $this->Tree->findByName('1. Root', array('id'));
  645. $this->Tree->id = $parent[$modelClass]['id'];
  646. $result = $this->Tree->children(null, true, array('name'));
  647. $expected = array(
  648. array($modelClass => array('name' => '1.1')),
  649. array($modelClass => array('name' => '1.2')),
  650. array($modelClass => array('name' => '1.5')),
  651. array($modelClass => array('name' => '1.3')),
  652. array($modelClass => array('name' => '1.4')),
  653. array($modelClass => array('name' => '1.6')),
  654. array($modelClass => array('name' => '1.7')),
  655. array($modelClass => array('name' => '1.8')),
  656. array($modelClass => array('name' => '1.9')),
  657. array($modelClass => array('name' => '1.10')));
  658. $this->assertSame($expected, $result);
  659. }
  660. /**
  661. * testMoveUpFirst method
  662. *
  663. * @return void
  664. */
  665. public function testMoveUpFirst() {
  666. extract($this->settings);
  667. $this->Tree = new $modelClass();
  668. $this->Tree->initialize(1, 10);
  669. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
  670. $this->Tree->moveUp($data[$modelClass]['id'], true);
  671. $parent = $this->Tree->findByName('1. Root', array('id'));
  672. $this->Tree->id = $parent[$modelClass]['id'];
  673. $result = $this->Tree->children(null, true, array('name'));
  674. $expected = array(
  675. array($modelClass => array('name' => '1.5')),
  676. array($modelClass => array('name' => '1.1')),
  677. array($modelClass => array('name' => '1.2')),
  678. array($modelClass => array('name' => '1.3')),
  679. array($modelClass => array('name' => '1.4')),
  680. array($modelClass => array('name' => '1.6')),
  681. array($modelClass => array('name' => '1.7')),
  682. array($modelClass => array('name' => '1.8')),
  683. array($modelClass => array('name' => '1.9')),
  684. array($modelClass => array('name' => '1.10')));
  685. $this->assertSame($expected, $result);
  686. }
  687. /**
  688. * testMoveDownSuccess method
  689. *
  690. * @return void
  691. */
  692. public function testMoveDownSuccess() {
  693. extract($this->settings);
  694. $this->Tree = new $modelClass();
  695. $this->Tree->initialize(2, 2);
  696. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
  697. $this->Tree->moveDown($data[$modelClass]['id']);
  698. $parent = $this->Tree->findByName('1. Root', array('id'));
  699. $this->Tree->id = $parent[$modelClass]['id'];
  700. $result = $this->Tree->children(null, true, array('name'));
  701. $expected = array(array($modelClass => array('name' => '1.2')),
  702. array($modelClass => array('name' => '1.1')));
  703. $this->assertSame($expected, $result);
  704. }
  705. /**
  706. * testMoveDownFail method
  707. *
  708. * @return void
  709. */
  710. public function testMoveDownFail() {
  711. extract($this->settings);
  712. $this->Tree = new $modelClass();
  713. $this->Tree->initialize(2, 2);
  714. $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.2')));
  715. $this->Tree->moveDown($data[$modelClass]['id']);
  716. $parent = $this->Tree->findByName('1. Root', array('id'));
  717. $this->Tree->id = $parent[$modelClass]['id'];
  718. $result = $this->Tree->children(null, true, array('name'));
  719. $expected = array(array($modelClass => array('name' => '1.1')),
  720. array($modelClass => array('name' => '1.2')));
  721. $this->assertSame($expected, $result);
  722. }
  723. /**
  724. * testMoveDownLast method
  725. *
  726. * @return void
  727. */
  728. public function testMoveDownLast() {
  729. extract($this->settings);
  730. $this->Tree = new $modelClass();
  731. $this->Tree->initialize(1, 10);
  732. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
  733. $this->Tree->moveDown($data[$modelClass]['id'], true);
  734. $parent = $this->Tree->findByName('1. Root', array('id'));
  735. $this->Tree->id = $parent[$modelClass]['id'];
  736. $result = $this->Tree->children(null, true, array('name'));
  737. $expected = array(
  738. array($modelClass => array('name' => '1.1')),
  739. array($modelClass => array('name' => '1.2')),
  740. array($modelClass => array('name' => '1.3')),
  741. array($modelClass => array('name' => '1.4')),
  742. array($modelClass => array('name' => '1.6')),
  743. array($modelClass => array('name' => '1.7')),
  744. array($modelClass => array('name' => '1.8')),
  745. array($modelClass => array('name' => '1.9')),
  746. array($modelClass => array('name' => '1.10')),
  747. array($modelClass => array('name' => '1.5')));
  748. $this->assertSame($expected, $result);
  749. }
  750. /**
  751. * testMoveDown2 method
  752. *
  753. * @return void
  754. */
  755. public function testMoveDown2() {
  756. extract($this->settings);
  757. $this->Tree = new $modelClass();
  758. $this->Tree->initialize(1, 10);
  759. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
  760. $this->Tree->moveDown($data[$modelClass]['id'], 2);
  761. $parent = $this->Tree->findByName('1. Root', array('id'));
  762. $this->Tree->id = $parent[$modelClass]['id'];
  763. $result = $this->Tree->children(null, true, array('name'));
  764. $expected = array(
  765. array($modelClass => array('name' => '1.1')),
  766. array($modelClass => array('name' => '1.2')),
  767. array($modelClass => array('name' => '1.3')),
  768. array($modelClass => array('name' => '1.4')),
  769. array($modelClass => array('name' => '1.6')),
  770. array($modelClass => array('name' => '1.7')),
  771. array($modelClass => array('name' => '1.5')),
  772. array($modelClass => array('name' => '1.8')),
  773. array($modelClass => array('name' => '1.9')),
  774. array($modelClass => array('name' => '1.10')));
  775. $this->assertSame($expected, $result);
  776. }
  777. /**
  778. * testSaveNoMove method
  779. *
  780. * @return void
  781. */
  782. public function testSaveNoMove() {
  783. extract($this->settings);
  784. $this->Tree = new $modelClass();
  785. $this->Tree->initialize(1, 10);
  786. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
  787. $this->Tree->id = $data[$modelClass]['id'];
  788. $this->Tree->saveField('name', 'renamed');
  789. $parent = $this->Tree->findByName('1. Root', array('id'));
  790. $this->Tree->id = $parent[$modelClass]['id'];
  791. $result = $this->Tree->children(null, true, array('name'));
  792. $expected = array(
  793. array($modelClass => array('name' => '1.1')),
  794. array($modelClass => array('name' => '1.2')),
  795. array($modelClass => array('name' => '1.3')),
  796. array($modelClass => array('name' => '1.4')),
  797. array($modelClass => array('name' => 'renamed')),
  798. array($modelClass => array('name' => '1.6')),
  799. array($modelClass => array('name' => '1.7')),
  800. array($modelClass => array('name' => '1.8')),
  801. array($modelClass => array('name' => '1.9')),
  802. array($modelClass => array('name' => '1.10')));
  803. $this->assertSame($expected, $result);
  804. }
  805. /**
  806. * testMoveToRootAndMoveUp method
  807. *
  808. * @return void
  809. */
  810. public function testMoveToRootAndMoveUp() {
  811. extract($this->settings);
  812. $this->Tree = new $modelClass();
  813. $this->Tree->initialize(1, 1);
  814. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
  815. $this->Tree->id = $data[$modelClass]['id'];
  816. $this->Tree->save(array($parentField => null));
  817. $result = $this->Tree->verify();
  818. $this->assertTrue($result);
  819. $this->Tree->moveUp();
  820. $result = $this->Tree->find('all', array('fields' => 'name', 'order' => $modelClass . '.' . $leftField . ' ASC'));
  821. $expected = array(array($modelClass => array('name' => '1.1')),
  822. array($modelClass => array('name' => '1. Root')));
  823. $this->assertSame($expected, $result);
  824. }
  825. /**
  826. * testDelete method
  827. *
  828. * @return void
  829. */
  830. public function testDelete() {
  831. extract($this->settings);
  832. $this->Tree = new $modelClass();
  833. $this->Tree->initialize(2, 2);
  834. $initialCount = $this->Tree->find('count');
  835. $result = $this->Tree->findByName('1.1.1');
  836. $return = $this->Tree->delete($result[$modelClass]['id']);
  837. $this->assertEquals(true, $return);
  838. $laterCount = $this->Tree->find('count');
  839. $this->assertEquals($initialCount - 1, $laterCount);
  840. $validTree = $this->Tree->verify();
  841. $this->assertTrue($validTree);
  842. $initialCount = $this->Tree->find('count');
  843. $result = $this->Tree->findByName('1.1');
  844. $return = $this->Tree->delete($result[$modelClass]['id']);
  845. $this->assertEquals(true, $return);
  846. $laterCount = $this->Tree->find('count');
  847. $this->assertEquals($initialCount - 2, $laterCount);
  848. $validTree = $this->Tree->verify();
  849. $this->assertTrue($validTree);
  850. }
  851. /**
  852. * Test deleting a record that doesn't exist.
  853. *
  854. * @return void
  855. */
  856. public function testDeleteDoesNotExist() {
  857. extract($this->settings);
  858. $this->Tree = new $modelClass();
  859. $this->Tree->initialize(2, 2);
  860. $this->Tree->delete(99999);
  861. }
  862. /**
  863. * testRemove method
  864. *
  865. * @return void
  866. */
  867. public function testRemove() {
  868. extract($this->settings);
  869. $this->Tree = new $modelClass();
  870. $this->Tree->initialize(2, 2);
  871. $initialCount = $this->Tree->find('count');
  872. $result = $this->Tree->findByName('1.1');
  873. $this->Tree->removeFromTree($result[$modelClass]['id']);
  874. $laterCount = $this->Tree->find('count');
  875. $this->assertEquals($initialCount, $laterCount);
  876. $children = $this->Tree->children($result[$modelClass][$parentField], true, array('name'));
  877. $expected = array(array($modelClass => array('name' => '1.1.1')),
  878. array($modelClass => array('name' => '1.1.2')),
  879. array($modelClass => array('name' => '1.2')));
  880. $this->assertEquals($expected, $children);
  881. $topNodes = $this->Tree->children(false, true, array('name'));
  882. $expected = array(array($modelClass => array('name' => '1. Root')),
  883. array($modelClass => array('name' => '1.1')));
  884. $this->assertEquals($expected, $topNodes);
  885. $validTree = $this->Tree->verify();
  886. $this->assertTrue($validTree);
  887. }
  888. /**
  889. * testRemoveLastTopParent method
  890. *
  891. * @return void
  892. */
  893. public function testRemoveLastTopParent() {
  894. extract($this->settings);
  895. $this->Tree = new $modelClass();
  896. $this->Tree->initialize(2, 2);
  897. $initialCount = $this->Tree->find('count');
  898. $initialTopNodes = $this->Tree->childCount(false);
  899. $result = $this->Tree->findByName('1. Root');
  900. $this->Tree->removeFromTree($result[$modelClass]['id']);
  901. $laterCount = $this->Tree->find('count');
  902. $laterTopNodes = $this->Tree->childCount(false);
  903. $this->assertEquals($initialCount, $laterCount);
  904. $this->assertEquals($initialTopNodes, $laterTopNodes);
  905. $topNodes = $this->Tree->children(false, true, array('name'));
  906. $expected = array(array($modelClass => array('name' => '1.1')),
  907. array($modelClass => array('name' => '1.2')),
  908. array($modelClass => array('name' => '1. Root')));
  909. $this->assertEquals($expected, $topNodes);
  910. $validTree = $this->Tree->verify();
  911. $this->assertTrue($validTree);
  912. }
  913. /**
  914. * testRemoveNoChildren method
  915. *
  916. * @return void
  917. */
  918. public function testRemoveNoChildren() {
  919. extract($this->settings);
  920. $this->Tree = new $modelClass();
  921. $this->Tree->initialize(2, 2);
  922. $initialCount = $this->Tree->find('count');
  923. $result = $this->Tree->findByName('1.1.1');
  924. $this->Tree->removeFromTree($result[$modelClass]['id']);
  925. $laterCount = $this->Tree->find('count');
  926. $this->assertEquals($initialCount, $laterCount);
  927. $nodes = $this->Tree->find('list', array('order' => $leftField));
  928. $expected = array(
  929. 1 => '1. Root',
  930. 2 => '1.1',
  931. 4 => '1.1.2',
  932. 5 => '1.2',
  933. 6 => '1.2.1',
  934. 7 => '1.2.2',
  935. 3 => '1.1.1',
  936. );
  937. $this->assertEquals($expected, $nodes);
  938. $validTree = $this->Tree->verify();
  939. $this->assertTrue($validTree);
  940. }
  941. /**
  942. * testRemoveAndDelete method
  943. *
  944. * @return void
  945. */
  946. public function testRemoveAndDelete() {
  947. extract($this->settings);
  948. $this->Tree = new $modelClass();
  949. $this->Tree->initialize(2, 2);
  950. $initialCount = $this->Tree->find('count');
  951. $result = $this->Tree->findByName('1.1');
  952. $this->Tree->removeFromTree($result[$modelClass]['id'], true);
  953. $laterCount = $this->Tree->find('count');
  954. $this->assertEquals($initialCount - 1, $laterCount);
  955. $children = $this->Tree->children($result[$modelClass][$parentField], true, array('name'), $leftField . ' asc');
  956. $expected = array(
  957. array($modelClass => array('name' => '1.1.1')),
  958. array($modelClass => array('name' => '1.1.2')),
  959. array($modelClass => array('name' => '1.2'))
  960. );
  961. $this->assertEquals($expected, $children);
  962. $topNodes = $this->Tree->children(false, true, array('name'));
  963. $expected = array(array($modelClass => array('name' => '1. Root')));
  964. $this->assertEquals($expected, $topNodes);
  965. $validTree = $this->Tree->verify();
  966. $this->assertTrue($validTree);
  967. }
  968. /**
  969. * testRemoveAndDeleteNoChildren method
  970. *
  971. * @return void
  972. */
  973. public function testRemoveAndDeleteNoChildren() {
  974. extract($this->settings);
  975. $this->Tree = new $modelClass();
  976. $this->Tree->initialize(2, 2);
  977. $initialCount = $this->Tree->find('count');
  978. $result = $this->Tree->findByName('1.1.1');
  979. $this->Tree->removeFromTree($result[$modelClass]['id'], true);
  980. $laterCount = $this->Tree->find('count');
  981. $this->assertEquals($initialCount - 1, $laterCount);
  982. $nodes = $this->Tree->find('list', array('order' => $leftField));
  983. $expected = array(
  984. 1 => '1. Root',
  985. 2 => '1.1',
  986. 4 => '1.1.2',
  987. 5 => '1.2',
  988. 6 => '1.2.1',
  989. 7 => '1.2.2',
  990. );
  991. $this->assertEquals($expected, $nodes);
  992. $validTree = $this->Tree->verify();
  993. $this->assertTrue($validTree);
  994. }
  995. /**
  996. * testChildren method
  997. *
  998. * @return void
  999. */
  1000. public function testChildren() {
  1001. extract($this->settings);
  1002. $this->Tree = new $modelClass();
  1003. $this->Tree->initialize(2, 2);
  1004. $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
  1005. $this->Tree->id = $data[$modelClass]['id'];
  1006. $direct = $this->Tree->children(null, true, array('id', 'name', $parentField, $leftField, $rightField));
  1007. $expected = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 7)),
  1008. array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 8, $rightField => 13)));
  1009. $this->assertEquals($expected, $direct);
  1010. $total = $this->Tree->children(null, null, array('id', 'name', $parentField, $leftField, $rightField));
  1011. $expected = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 7)),
  1012. array($modelClass => array('id' => 3, 'name' => '1.1.1', $parentField => 2, $leftField => 3, $rightField => 4)),
  1013. array($modelClass => array('id' => 4, 'name' => '1.1.2', $parentField => 2, $leftField => 5, $rightField => 6)),
  1014. array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 8, $rightField => 13)),
  1015. array($modelClass => array('id' => 6, 'name' => '1.2.1', $parentField => 5, $leftField => 9, $rightField => 10)),
  1016. array($modelClass => array('id' => 7, 'name' => '1.2.2', $parentField => 5, $leftField => 11, $rightField => 12)));
  1017. $this->assertEquals($expected, $total);
  1018. $this->assertEquals(array(), $this->Tree->children(10000));
  1019. }
  1020. /**
  1021. * testCountChildren method
  1022. *
  1023. * @return void
  1024. */
  1025. public function testCountChildren() {
  1026. extract($this->settings);
  1027. $this->Tree = new $modelClass();
  1028. $this->Tree->initialize(2, 2);
  1029. $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
  1030. $this->Tree->id = $data[$modelClass]['id'];
  1031. $direct = $this->Tree->childCount(null, true);
  1032. $this->assertEquals(2, $direct);
  1033. $total = $this->Tree->childCount();
  1034. $this->assertEquals(6, $total);
  1035. $this->Tree->read(null, $data[$modelClass]['id']);
  1036. $id = $this->Tree->field('id', array($modelClass . '.name' => '1.2'));
  1037. $total = $this->Tree->childCount($id);
  1038. $this->assertEquals(2, $total);
  1039. }
  1040. /**
  1041. * testGetParentNode method
  1042. *
  1043. * @return void
  1044. */
  1045. public function testGetParentNode() {
  1046. extract($this->settings);
  1047. $this->Tree = new $modelClass();
  1048. $this->Tree->initialize(2, 2);
  1049. $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.2.2')));
  1050. $this->Tree->id = $data[$modelClass]['id'];
  1051. $result = $this->Tree->getParentNode(null, array('name'));
  1052. $expected = array($modelClass => array('name' => '1.2'));
  1053. $this->assertSame($expected, $result);
  1054. }
  1055. /**
  1056. * testGetPath method
  1057. *
  1058. * @return void
  1059. */
  1060. public function testGetPath() {
  1061. extract($this->settings);
  1062. $this->Tree = new $modelClass();
  1063. $this->Tree->initialize(2, 2);
  1064. $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.2.2')));
  1065. $this->Tree->id = $data[$modelClass]['id'];
  1066. $result = $this->Tree->getPath(null, array('name'));
  1067. $expected = array(array($modelClass => array('name' => '1. Root')),
  1068. array($modelClass => array('name' => '1.2')),
  1069. array($modelClass => array('name' => '1.2.2')));
  1070. $this->assertSame($expected, $result);
  1071. }
  1072. /**
  1073. * testNoAmbiguousColumn method
  1074. *
  1075. * @return void
  1076. */
  1077. public function testNoAmbiguousColumn() {
  1078. extract($this->settings);
  1079. $this->Tree = new $modelClass();
  1080. $this->Tree->bindModel(array('belongsTo' => array('Dummy' =>
  1081. array('className' => $modelClass, 'foreignKey' => $parentField, 'conditions' => array('Dummy.id' => null)))), false);
  1082. $this->Tree->initialize(2, 2);
  1083. $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
  1084. $this->Tree->id = $data[$modelClass]['id'];
  1085. $direct = $this->Tree->children(null, true, array('id', 'name', $parentField, $leftField, $rightField));
  1086. $expected = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 7)),
  1087. array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 8, $rightField => 13)));
  1088. $this->assertEquals($expected, $direct);
  1089. $total = $this->Tree->children(null, null, array('id', 'name', $parentField, $leftField, $rightField));
  1090. $expected = array(
  1091. array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 7)),
  1092. array($modelClass => array('id' => 3, 'name' => '1.1.1', $parentField => 2, $leftField => 3, $rightField => 4)),
  1093. array($modelClass => array('id' => 4, 'name' => '1.1.2', $parentField => 2, $leftField => 5, $rightField => 6)),
  1094. array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 8, $rightField => 13)),
  1095. array($modelClass => array('id' => 6, 'name' => '1.2.1', $parentField => 5, $leftField => 9, $rightField => 10)),
  1096. array($modelClass => array('id' => 7, 'name' => '1.2.2', $parentField => 5, $leftField => 11, $rightField => 12))
  1097. );
  1098. $this->assertEquals($expected, $total);
  1099. }
  1100. /**
  1101. * testReorderTree method
  1102. *
  1103. * @return void
  1104. */
  1105. public function testReorderTree() {
  1106. extract($this->settings);
  1107. $this->Tree = new $modelClass();
  1108. $this->Tree->initialize(3, 3);
  1109. $nodes = $this->Tree->find('list', array('order' => $leftField));
  1110. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
  1111. $this->Tree->moveDown($data[$modelClass]['id']);
  1112. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.2.1')));
  1113. $this->Tree->moveDown($data[$modelClass]['id']);
  1114. $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.3.2.2')));
  1115. $this->Tree->moveDown($data[$modelClass]['id']);
  1116. $unsortedNodes = $this->Tree->find('list', array('order' => $leftField));
  1117. $this->assertEquals($nodes, $unsortedNodes);
  1118. $this->assertNotEquals(array_keys($nodes), array_keys($unsortedNodes));
  1119. $this->Tree->reorder();
  1120. $sortedNodes = $this->Tree->find('list', array('order' => $leftField));
  1121. $this->assertSame($nodes, $sortedNodes);
  1122. }
  1123. /**
  1124. * test reordering large-ish trees with cacheQueries = true.
  1125. * This caused infinite loops when moving down elements as stale data is returned
  1126. * from the memory cache
  1127. *
  1128. * @return void
  1129. */
  1130. public function testReorderBigTreeWithQueryCaching() {
  1131. extract($this->settings);
  1132. $this->Tree = new $modelClass();
  1133. $this->Tree->initialize(2, 10);
  1134. $original = $this->Tree->cacheQueries;
  1135. $this->Tree->cacheQueries = true;
  1136. $this->Tree->reorder(array('field' => 'name', 'direction' => 'DESC'));
  1137. $this->assertTrue($this->Tree->cacheQueries, 'cacheQueries was not restored after reorder(). %s');
  1138. $this->Tree->cacheQueries = $original;
  1139. }
  1140. /**
  1141. * testGenerateTreeListWithSelfJoin method
  1142. *
  1143. * @return void
  1144. */
  1145. public function testGenerateTreeListWithSelfJoin() {
  1146. extract($this->settings);
  1147. $this->Tree = new $modelClass();
  1148. $this->Tree->bindModel(array('belongsTo' => array('Dummy' =>
  1149. array('className' => $modelClass, 'foreignKey' => $parentField, 'conditions' => array('Dummy.id' => null)))), false);
  1150. $this->Tree->initialize(2, 2);
  1151. $result = $this->Tree->generateTreeList();
  1152. $expected = array(1 => '1. Root', 2 => '_1.1', 3 => '__1.1.1', 4 => '__1.1.2', 5 => '_1.2', 6 => '__1.2.1', 7 => '__1.2.2');
  1153. $this->assertSame($expected, $result);
  1154. }
  1155. /**
  1156. * Test the formatting options of generateTreeList()
  1157. *
  1158. * @return void
  1159. */
  1160. public function testGenerateTreeListFormatting() {
  1161. extract($this->settings);
  1162. $this->Tree = new $modelClass();
  1163. $this->Tree->initialize(2, 2);
  1164. $result = $this->Tree->generateTreeList(
  1165. null,
  1166. "{n}.$modelClass.id",
  1167. array('%s - %s', "{n}.$modelClass.id", "{n}.$modelClass.name")
  1168. );
  1169. $this->assertEquals('1 - 1. Root', $result[1]);
  1170. $this->assertEquals('_2 - 1.1', $result[2]);
  1171. $this->assertEquals('__3 - 1.1.1', $result[3]);
  1172. }
  1173. /**
  1174. * testArraySyntax method
  1175. *
  1176. * @return void
  1177. */
  1178. public function testArraySyntax() {
  1179. extract($this->settings);
  1180. $this->Tree = new $modelClass();
  1181. $this->Tree->initialize(3, 3);
  1182. $this->assertSame($this->Tree->childCount(2), $this->Tree->childCount(array('id' => 2)));
  1183. $this->assertSame($this->Tree->getParentNode(2), $this->Tree->getParentNode(array('id' => 2)));
  1184. $this->assertSame($this->Tree->getPath(4), $this->Tree->getPath(array('id' => 4)));
  1185. }
  1186. /**
  1187. * testFindThreaded method
  1188. *
  1189. * @return void
  1190. */
  1191. public function testFindThreaded() {
  1192. $Model = new Person();
  1193. $Model->recursive = -1;
  1194. $Model->Behaviors->load('Tree', array('parent' => 'mother_id'));
  1195. $result = $Model->find('threaded');
  1196. $expected = array(
  1197. array(
  1198. 'Person' => array(
  1199. 'id' => '4',
  1200. 'name' => 'mother - grand mother',
  1201. 'mother_id' => '0',
  1202. 'father_id' => '0'
  1203. ),
  1204. 'children' => array(
  1205. array(
  1206. 'Person' => array(
  1207. 'id' => '2',
  1208. 'name' => 'mother',
  1209. 'mother_id' => '4',
  1210. 'father_id' => '5'
  1211. ),
  1212. 'children' => array(
  1213. array(
  1214. 'Person' => array(
  1215. 'id' => '1',
  1216. 'name' => 'person',
  1217. 'mother_id' => '2',
  1218. 'father_id' => '3'
  1219. ),
  1220. 'children' => array()
  1221. )
  1222. )
  1223. )
  1224. )
  1225. ),
  1226. array(
  1227. 'Person' => array(
  1228. 'id' => '5',
  1229. 'name' => 'mother - grand father',
  1230. 'mother_id' => '0',
  1231. 'father_id' => '0'
  1232. ),
  1233. 'children' => array()
  1234. ),
  1235. array(
  1236. 'Person' => array(
  1237. 'id' => '6',
  1238. 'name' => 'father - grand mother',
  1239. 'mother_id' => '0',
  1240. 'father_id' => '0'
  1241. ),
  1242. 'children' => array(
  1243. array(
  1244. 'Person' => array(
  1245. 'id' => '3',
  1246. 'name' => 'father',
  1247. 'mother_id' => '6',
  1248. 'father_id' => '7'
  1249. ),
  1250. 'children' => array()
  1251. )
  1252. )
  1253. ),
  1254. array(
  1255. 'Person' => array(
  1256. 'id' => '7',
  1257. 'name' => 'father - grand father',
  1258. 'mother_id' => '0',
  1259. 'father_id' => '0'
  1260. ),
  1261. 'children' => array()
  1262. )
  1263. );
  1264. $this->assertEquals($expected, $result);
  1265. }
  1266. }