TreeBehaviorNumberTest.php 47 KB

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