TreeBehaviorNumberTest.php 47 KB

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