diff --git a/src/Http/Controllers/CP/Collections/ReorderEntriesController.php b/src/Http/Controllers/CP/Collections/ReorderEntriesController.php index 2e8c2da9ac8..5c713883664 100644 --- a/src/Http/Controllers/CP/Collections/ReorderEntriesController.php +++ b/src/Http/Controllers/CP/Collections/ReorderEntriesController.php @@ -15,8 +15,8 @@ public function __invoke(Request $request, $collection) $request->validate([ 'ids' => 'required|array', - 'page' => 'required|integer', - 'perPage' => 'required|integer', + 'page' => 'required|integer|min:1', + 'perPage' => 'required|integer|min:1', 'site' => 'required', ]); diff --git a/tests/Feature/Entries/ReorderEntriesTest.php b/tests/Feature/Entries/ReorderEntriesTest.php index 0f5e7c98fc3..9a3e236ed29 100644 --- a/tests/Feature/Entries/ReorderEntriesTest.php +++ b/tests/Feature/Entries/ReorderEntriesTest.php @@ -211,6 +211,64 @@ public function it_doesnt_reorder_when_the_submitted_entries_arent_on_the_page_b $this->assertEquals($tree, $this->structure->in('en')->tree()); } + #[Test] + public function it_doesnt_reorder_when_the_page_is_zero() + { + EntryFactory::id('1')->slug('one')->collection('test')->create(); + EntryFactory::id('2')->slug('two')->collection('test')->create(); + EntryFactory::id('3')->slug('three')->collection('test')->create(); + EntryFactory::id('4')->slug('four')->collection('test')->create(); + + $tree = [ + ['entry' => '1'], + ['entry' => '2'], + ['entry' => '3'], + ['entry' => '4'], + ]; + + $this->structure->in('en')->tree($tree)->save(); + + $this->setTestRoles(['test' => ['access cp', 'reorder test entries']]); + $user = tap(User::make()->assignRole('test'))->save(); + + // A zero page would otherwise give a negative offset, which slices the last + // entries off the tree and then writes negative keys back onto it. + $this + ->actingAs($user) + ->reorder(['page' => 0, 'perPage' => 2, 'ids' => [4, 3]]) + ->assertSessionHasErrors('page'); + + $this->assertEquals($tree, $this->structure->in('en')->tree()); + } + + #[Test] + public function it_doesnt_reorder_when_the_per_page_is_zero() + { + EntryFactory::id('1')->slug('one')->collection('test')->create(); + EntryFactory::id('2')->slug('two')->collection('test')->create(); + EntryFactory::id('3')->slug('three')->collection('test')->create(); + EntryFactory::id('4')->slug('four')->collection('test')->create(); + + $tree = [ + ['entry' => '1'], + ['entry' => '2'], + ['entry' => '3'], + ['entry' => '4'], + ]; + + $this->structure->in('en')->tree($tree)->save(); + + $this->setTestRoles(['test' => ['access cp', 'reorder test entries']]); + $user = tap(User::make()->assignRole('test'))->save(); + + $this + ->actingAs($user) + ->reorder(['page' => 1, 'perPage' => 0, 'ids' => [4, 3]]) + ->assertSessionHasErrors('perPage'); + + $this->assertEquals($tree, $this->structure->in('en')->tree()); + } + #[Test] public function creating_an_entry_gives_it_the_correct_order_when_the_tree_has_already_been_read() {