ScopedNodeTest.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <?php
  2. use Illuminate\Database\Capsule\Manager as Capsule;
  3. use Kalnoy\Nestedset\NestedSet;
  4. class ScopedNodeTest extends PHPUnit\Framework\TestCase
  5. {
  6. public static function setUpBeforeClass(): void
  7. {
  8. $schema = Capsule::schema();
  9. $schema->dropIfExists('menu_items');
  10. Capsule::disableQueryLog();
  11. $schema->create('menu_items', function (\Illuminate\Database\Schema\Blueprint $table) {
  12. $table->increments('id');
  13. $table->unsignedInteger('menu_id');
  14. $table->string('title')->nullable();
  15. NestedSet::columns($table);
  16. });
  17. Capsule::enableQueryLog();
  18. }
  19. public function setUp(): void
  20. {
  21. $data = include __DIR__.'/data/menu_items.php';
  22. Capsule::table('menu_items')->insert($data);
  23. Capsule::flushQueryLog();
  24. MenuItem::resetActionsPerformed();
  25. date_default_timezone_set('America/Denver');
  26. }
  27. public function tearDown(): void
  28. {
  29. Capsule::table('menu_items')->truncate();
  30. }
  31. public function assertTreeNotBroken($menuId)
  32. {
  33. $this->assertFalse(MenuItem::scoped([ 'menu_id' => $menuId ])->isBroken());
  34. }
  35. public function testNotBroken()
  36. {
  37. $this->assertTreeNotBroken(1);
  38. $this->assertTreeNotBroken(2);
  39. }
  40. public function testMovingNodeNotAffectingOtherMenu()
  41. {
  42. $node = MenuItem::where('menu_id', '=', 1)->first();
  43. $node->down();
  44. $node = MenuItem::where('menu_id', '=', 2)->first();
  45. $this->assertEquals(1, $node->getLft());
  46. }
  47. public function testScoped()
  48. {
  49. $node = MenuItem::scoped([ 'menu_id' => 2 ])->first();
  50. $this->assertEquals(3, $node->getKey());
  51. }
  52. public function testSiblings()
  53. {
  54. $node = MenuItem::find(1);
  55. $result = $node->getSiblings();
  56. $this->assertEquals(1, $result->count());
  57. $this->assertEquals(2, $result->first()->getKey());
  58. $result = $node->getNextSiblings();
  59. $this->assertEquals(2, $result->first()->getKey());
  60. $node = MenuItem::find(2);
  61. $result = $node->getPrevSiblings();
  62. $this->assertEquals(1, $result->first()->getKey());
  63. }
  64. public function testDescendants()
  65. {
  66. $node = MenuItem::find(2);
  67. $result = $node->getDescendants();
  68. $this->assertEquals(1, $result->count());
  69. $this->assertEquals(5, $result->first()->getKey());
  70. $node = MenuItem::scoped([ 'menu_id' => 1 ])->with('descendants')->find(2);
  71. $result = $node->descendants;
  72. $this->assertEquals(1, $result->count());
  73. $this->assertEquals(5, $result->first()->getKey());
  74. }
  75. public function testAncestors()
  76. {
  77. $node = MenuItem::find(5);
  78. $result = $node->getAncestors();
  79. $this->assertEquals(1, $result->count());
  80. $this->assertEquals(2, $result->first()->getKey());
  81. $node = MenuItem::scoped([ 'menu_id' => 1 ])->with('ancestors')->find(5);
  82. $result = $node->ancestors;
  83. $this->assertEquals(1, $result->count());
  84. $this->assertEquals(2, $result->first()->getKey());
  85. }
  86. public function testDepth()
  87. {
  88. $node = MenuItem::scoped([ 'menu_id' => 1 ])->withDepth()->where('id', '=', 5)->first();
  89. $this->assertEquals(1, $node->depth);
  90. $node = MenuItem::find(2);
  91. $result = $node->children()->withDepth()->get();
  92. $this->assertEquals(1, $result->first()->depth);
  93. }
  94. public function testSaveAsRoot()
  95. {
  96. $node = MenuItem::find(5);
  97. $node->saveAsRoot();
  98. $this->assertEquals(5, $node->getLft());
  99. $this->assertEquals(null, $node->parent_id);
  100. $this->assertOtherScopeNotAffected();
  101. }
  102. public function testInsertion()
  103. {
  104. $node = MenuItem::create([ 'menu_id' => 1, 'parent_id' => 5 ]);
  105. $this->assertEquals(5, $node->parent_id);
  106. $this->assertEquals(5, $node->getLft());
  107. $this->assertOtherScopeNotAffected();
  108. }
  109. public function testInsertionToParentFromOtherScope()
  110. {
  111. $this->expectException(\Illuminate\Database\Eloquent\ModelNotFoundException::class);
  112. $node = MenuItem::create([ 'menu_id' => 2, 'parent_id' => 5 ]);
  113. }
  114. public function testDeletion()
  115. {
  116. $node = MenuItem::find(2)->delete();
  117. $node = MenuItem::find(1);
  118. $this->assertEquals(2, $node->getRgt());
  119. $this->assertOtherScopeNotAffected();
  120. }
  121. public function testMoving()
  122. {
  123. $node = MenuItem::find(1);
  124. $this->assertTrue($node->down());
  125. $this->assertOtherScopeNotAffected();
  126. }
  127. protected function assertOtherScopeNotAffected()
  128. {
  129. $node = MenuItem::find(3);
  130. $this->assertEquals(1, $node->getLft());
  131. }
  132. // Commented, cause there is no assertion here and otherwise the test is marked as risky in PHPUnit 7.
  133. // What's the purpose of this method? @todo: remove/update?
  134. /*public function testRebuildsTree()
  135. {
  136. $data = [];
  137. MenuItem::scoped([ 'menu_id' => 2 ])->rebuildTree($data);
  138. }*/
  139. public function testAppendingToAnotherScopeFails()
  140. {
  141. $this->expectException(LogicException::class);
  142. $a = MenuItem::find(1);
  143. $b = MenuItem::find(3);
  144. $a->appendToNode($b)->save();
  145. }
  146. public function testInsertingBeforeAnotherScopeFails()
  147. {
  148. $this->expectException(LogicException::class);
  149. $a = MenuItem::find(1);
  150. $b = MenuItem::find(3);
  151. $a->insertAfterNode($b);
  152. }
  153. public function testEagerLoadingAncestorsWithScope()
  154. {
  155. $filteredNodes = MenuItem::where('title', 'menu item 3')->with(['ancestors'])->get();
  156. $this->assertEquals(2, $filteredNodes->find(5)->ancestors[0]->id);
  157. $this->assertEquals(4, $filteredNodes->find(6)->ancestors[0]->id);
  158. }
  159. public function testEagerLoadingDescendantsWithScope()
  160. {
  161. $filteredNodes = MenuItem::where('title', 'menu item 2')->with(['descendants'])->get();
  162. $this->assertEquals(5, $filteredNodes->find(2)->descendants[0]->id);
  163. $this->assertEquals(6, $filteredNodes->find(4)->descendants[0]->id);
  164. }
  165. }