SortableTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <?php
  2. namespace Spatie\EloquentSortable\Test;
  3. use Illuminate\Support\Collection;
  4. class SortableTest extends TestCase
  5. {
  6. /** @test */
  7. public function it_sets_the_order_column_on_creation()
  8. {
  9. foreach (Dummy::all() as $dummy) {
  10. $this->assertEquals($dummy->name, $dummy->order_column);
  11. }
  12. }
  13. /** @test */
  14. public function it_can_get_the_highest_order_number()
  15. {
  16. $this->assertEquals(Dummy::all()->count(), (new Dummy())->getHighestOrderNumber());
  17. }
  18. /** @test */
  19. public function it_can_get_the_highest_order_number_with_trashed_models()
  20. {
  21. $this->setUpSoftDeletes();
  22. DummyWithSoftDeletes::first()->delete();
  23. $this->assertEquals(DummyWithSoftDeletes::withTrashed()->count(), (new DummyWithSoftDeletes())->getHighestOrderNumber());
  24. }
  25. /** @test */
  26. public function it_can_set_a_new_order()
  27. {
  28. $newOrder = Collection::make(Dummy::all()->pluck('id'))->shuffle()->toArray();
  29. Dummy::setNewOrder($newOrder);
  30. foreach (Dummy::orderBy('order_column')->get() as $i => $dummy) {
  31. $this->assertEquals($newOrder[$i], $dummy->id);
  32. }
  33. }
  34. /** @test */
  35. public function it_can_set_a_new_order_by_custom_column()
  36. {
  37. $newOrder = Collection::make(Dummy::all()->pluck('custom_column_sort'))->shuffle()->toArray();
  38. Dummy::setNewOrderByCustomColumn('custom_column_sort', $newOrder);
  39. foreach (Dummy::orderBy('order_column')->get() as $i => $dummy) {
  40. $this->assertEquals($newOrder[$i], $dummy->custom_column_sort);
  41. }
  42. }
  43. /** @test */
  44. public function it_can_set_a_new_order_from_collection()
  45. {
  46. $newOrder = Collection::make(Dummy::all()->pluck('id'))->shuffle();
  47. Dummy::setNewOrder($newOrder);
  48. foreach (Dummy::orderBy('order_column')->get() as $i => $dummy) {
  49. $this->assertEquals($newOrder[$i], $dummy->id);
  50. }
  51. }
  52. /** @test */
  53. public function it_can_set_a_new_order_by_custom_column_from_collection()
  54. {
  55. $newOrder = Collection::make(Dummy::all()->pluck('custom_column_sort'))->shuffle();
  56. Dummy::setNewOrderByCustomColumn('custom_column_sort', $newOrder);
  57. foreach (Dummy::orderBy('order_column')->get() as $i => $dummy) {
  58. $this->assertEquals($newOrder[$i], $dummy->custom_column_sort);
  59. }
  60. }
  61. /** @test */
  62. public function it_can_set_a_new_order_with_trashed_models()
  63. {
  64. $this->setUpSoftDeletes();
  65. $dummies = DummyWithSoftDeletes::all();
  66. $dummies->random()->delete();
  67. $newOrder = Collection::make($dummies->pluck('id'))->shuffle();
  68. DummyWithSoftDeletes::setNewOrder($newOrder);
  69. foreach (DummyWithSoftDeletes::withTrashed()->orderBy('order_column')->get() as $i => $dummy) {
  70. $this->assertEquals($newOrder[$i], $dummy->id);
  71. }
  72. }
  73. /** @test */
  74. public function it_can_set_a_new_order_by_custom_column_with_trashed_models()
  75. {
  76. $this->setUpSoftDeletes();
  77. $dummies = DummyWithSoftDeletes::all();
  78. $dummies->random()->delete();
  79. $newOrder = Collection::make($dummies->pluck('custom_column_sort'))->shuffle();
  80. DummyWithSoftDeletes::setNewOrderByCustomColumn('custom_column_sort', $newOrder);
  81. foreach (DummyWithSoftDeletes::withTrashed()->orderBy('order_column')->get() as $i => $dummy) {
  82. $this->assertEquals($newOrder[$i], $dummy->custom_column_sort);
  83. }
  84. }
  85. /** @test */
  86. public function it_can_set_a_new_order_without_trashed_models()
  87. {
  88. $this->setUpSoftDeletes();
  89. DummyWithSoftDeletes::first()->delete();
  90. $newOrder = Collection::make(DummyWithSoftDeletes::pluck('id'))->shuffle();
  91. DummyWithSoftDeletes::setNewOrder($newOrder);
  92. foreach (DummyWithSoftDeletes::orderBy('order_column')->get() as $i => $dummy) {
  93. $this->assertEquals($newOrder[$i], $dummy->id);
  94. }
  95. }
  96. /** @test */
  97. public function it_can_set_a_new_order_by_custom_column_without_trashed_models()
  98. {
  99. $this->setUpSoftDeletes();
  100. DummyWithSoftDeletes::first()->delete();
  101. $newOrder = Collection::make(DummyWithSoftDeletes::pluck('custom_column_sort'))->shuffle();
  102. DummyWithSoftDeletes::setNewOrderByCustomColumn('custom_column_sort', $newOrder);
  103. foreach (DummyWithSoftDeletes::orderBy('order_column')->get() as $i => $dummy) {
  104. $this->assertEquals($newOrder[$i], $dummy->custom_column_sort);
  105. }
  106. }
  107. /** @test */
  108. public function it_will_determine_to_sort_when_creating_if_sortable_attribute_does_not_exist()
  109. {
  110. $model = new Dummy();
  111. $this->assertTrue($model->shouldSortWhenCreating());
  112. }
  113. /** @test */
  114. public function it_will_determine_to_sort_when_creating_if_sort_when_creating_setting_does_not_exist()
  115. {
  116. $model = new class () extends Dummy {
  117. public $sortable = [];
  118. };
  119. $this->assertTrue($model->shouldSortWhenCreating());
  120. }
  121. /** @test */
  122. public function it_will_respect_the_sort_when_creating_setting()
  123. {
  124. $model = new class () extends Dummy {
  125. public $sortable = ['sort_when_creating' => true];
  126. };
  127. $this->assertTrue($model->shouldSortWhenCreating());
  128. $model = new class () extends Dummy {
  129. public $sortable = ['sort_when_creating' => false];
  130. };
  131. $this->assertFalse($model->shouldSortWhenCreating());
  132. }
  133. /** @test */
  134. public function it_provides_an_ordered_trait()
  135. {
  136. $i = 1;
  137. foreach (Dummy::ordered()->get()->pluck('order_column') as $order) {
  138. $this->assertEquals($i++, $order);
  139. }
  140. }
  141. /** @test */
  142. public function it_can_move_the_order_down()
  143. {
  144. $firstModel = Dummy::find(3);
  145. $secondModel = Dummy::find(4);
  146. $this->assertEquals($firstModel->order_column, 3);
  147. $this->assertEquals($secondModel->order_column, 4);
  148. $this->assertNotFalse($firstModel->moveOrderDown());
  149. $firstModel = Dummy::find(3);
  150. $secondModel = Dummy::find(4);
  151. $this->assertEquals($firstModel->order_column, 4);
  152. $this->assertEquals($secondModel->order_column, 3);
  153. }
  154. /** @test */
  155. public function it_will_not_fail_when_it_cant_move_the_order_down()
  156. {
  157. $lastModel = Dummy::all()->last();
  158. $this->assertEquals($lastModel->order_column, 20);
  159. $this->assertEquals($lastModel, $lastModel->moveOrderDown());
  160. }
  161. /** @test */
  162. public function it_can_move_the_order_up()
  163. {
  164. $firstModel = Dummy::find(3);
  165. $secondModel = Dummy::find(4);
  166. $this->assertEquals($firstModel->order_column, 3);
  167. $this->assertEquals($secondModel->order_column, 4);
  168. $this->assertNotFalse($secondModel->moveOrderUp());
  169. $firstModel = Dummy::find(3);
  170. $secondModel = Dummy::find(4);
  171. $this->assertEquals($firstModel->order_column, 4);
  172. $this->assertEquals($secondModel->order_column, 3);
  173. }
  174. /** @test */
  175. public function it_will_not_break_when_it_cant_move_the_order_up()
  176. {
  177. $lastModel = Dummy::first();
  178. $this->assertEquals($lastModel->order_column, 1);
  179. $this->assertEquals($lastModel, $lastModel->moveOrderUp());
  180. }
  181. /** @test */
  182. public function it_can_swap_the_position_of_two_given_models()
  183. {
  184. $firstModel = Dummy::find(3);
  185. $secondModel = Dummy::find(4);
  186. $this->assertEquals($firstModel->order_column, 3);
  187. $this->assertEquals($secondModel->order_column, 4);
  188. Dummy::swapOrder($firstModel, $secondModel);
  189. $this->assertEquals($firstModel->order_column, 4);
  190. $this->assertEquals($secondModel->order_column, 3);
  191. }
  192. /** @test */
  193. public function it_can_swap_itself_with_another_model()
  194. {
  195. $firstModel = Dummy::find(3);
  196. $secondModel = Dummy::find(4);
  197. $this->assertEquals($firstModel->order_column, 3);
  198. $this->assertEquals($secondModel->order_column, 4);
  199. $firstModel->swapOrderWithModel($secondModel);
  200. $this->assertEquals($firstModel->order_column, 4);
  201. $this->assertEquals($secondModel->order_column, 3);
  202. }
  203. /** @test */
  204. public function it_can_move_a_model_to_the_first_place()
  205. {
  206. $position = 3;
  207. $oldModels = Dummy::whereNot('id', $position)->get();
  208. $model = Dummy::find($position);
  209. $this->assertEquals(3, $model->order_column);
  210. $model = $model->moveToStart();
  211. $this->assertEquals(1, $model->order_column);
  212. $oldModels = $oldModels->pluck('order_column', 'id');
  213. $newModels = Dummy::whereNot('id', $position)->get()->pluck('order_column', 'id');
  214. foreach ($oldModels as $key => $oldModel) {
  215. $this->assertEquals($oldModel + 1, $newModels[$key]);
  216. }
  217. }
  218. /**
  219. * @test
  220. */
  221. public function it_can_move_a_model_to_the_last_place()
  222. {
  223. $position = 3;
  224. $oldModels = Dummy::whereNot('id', $position)->get();
  225. $model = Dummy::find($position);
  226. $this->assertNotEquals(20, $model->order_column);
  227. $model = $model->moveToEnd();
  228. $this->assertEquals(20, $model->order_column);
  229. $oldModels = $oldModels->pluck('order_column', 'id');
  230. $newModels = Dummy::whereNot('id', $position)->get()->pluck('order_column', 'id');
  231. foreach ($oldModels as $key => $order) {
  232. if ($order > $position) {
  233. $this->assertEquals($order - 1, $newModels[$key]);
  234. } else {
  235. $this->assertEquals($order, $newModels[$key]);
  236. }
  237. }
  238. }
  239. /** @test */
  240. public function it_can_use_config_properties()
  241. {
  242. config([
  243. 'eloquent-sortable.order_column_name' => 'order_column',
  244. 'eloquent-sortable.sort_when_creating' => true,
  245. ]);
  246. $model = new class () extends Dummy {
  247. public $sortable = [];
  248. };
  249. $this->assertEquals(config('eloquent-sortable.order_column_name'), $model->determineOrderColumnName());
  250. $this->assertEquals(config('eloquent-sortable.sort_when_creating'), $model->shouldSortWhenCreating());
  251. }
  252. /** @test */
  253. public function it_can_override_config_properties()
  254. {
  255. $model = new class () extends Dummy {
  256. public $sortable = [
  257. 'order_column_name' => 'my_custom_order_column',
  258. 'sort_when_creating' => false,
  259. ];
  260. };
  261. $this->assertEquals($model->determineOrderColumnName(), 'my_custom_order_column');
  262. $this->assertFalse($model->shouldSortWhenCreating());
  263. }
  264. /** @test */
  265. public function it_can_tell_if_element_is_first_in_order()
  266. {
  267. $model = (new Dummy())->buildSortQuery()->get();
  268. $this->assertTrue($model[0]->isFirstInOrder());
  269. $this->assertFalse($model[1]->isFirstInOrder());
  270. }
  271. /** @test */
  272. public function it_can_tell_if_element_is_last_in_order()
  273. {
  274. $model = (new Dummy())->buildSortQuery()->get();
  275. $this->assertTrue($model[$model->count() - 1]->isLastInOrder());
  276. $this->assertFalse($model[$model->count() - 2]->isLastInOrder());
  277. }
  278. }