From 0c89550dfe89c43364e99fc0db7937174d88dcea Mon Sep 17 00:00:00 2001 From: Romulus21 Date: Fri, 24 Apr 2020 08:10:54 +0200 Subject: [PATCH] first work on to do orders --- app/Http/Controllers/ToDoController.php | 14 ++ app/Http/Resources/ToDo.php | 2 +- app/Models/ToDoList.php | 2 +- database/factories/ToDoItemFactory.php | 16 +++ .../2020_04_19_190733_create_to_dos_table.php | 2 +- tests/Feature/ToDoItemsTest.php | 132 +++++++++++++++++- 6 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 database/factories/ToDoItemFactory.php diff --git a/app/Http/Controllers/ToDoController.php b/app/Http/Controllers/ToDoController.php index 9b3f6a6..892e151 100644 --- a/app/Http/Controllers/ToDoController.php +++ b/app/Http/Controllers/ToDoController.php @@ -14,6 +14,10 @@ class ToDoController extends Controller { $this->authorize('create', ToDoList::class); + $lastToDo = $toDoList->toDos()->orderBy('order', 'desc')->first(); + + request()['order'] = ($lastToDo) ? $lastToDo->order + 1 : 1; + $toDo = $toDoList->toDos()->create($this->validateData()); return (new ToDoResource($toDo)) @@ -32,10 +36,20 @@ class ToDoController extends Controller ->setStatusCode(200); } + public function destroy(ToDoList $toDoList, ToDo $toDo) + { + $this->authorize('delete', $toDoList); + + $toDo->delete(); + + return response([], 204); + } + private function validateData() { return request()->validate([ 'name' => 'required', + 'order' => 'integer|min:1|max:1000000' ]); } } diff --git a/app/Http/Resources/ToDo.php b/app/Http/Resources/ToDo.php index 6341a48..0fbf4c0 100644 --- a/app/Http/Resources/ToDo.php +++ b/app/Http/Resources/ToDo.php @@ -21,7 +21,7 @@ class ToDo extends JsonResource 'attributes' => [ 'data' => [ 'name' => $this->name, - 'order' => $this->order, + 'order' => (int) $this->order, 'checked_at' => optional($this->checked_at)->diffForHumans(), 'last_updated' => $this->updated_at->diffForHumans(), ] diff --git a/app/Models/ToDoList.php b/app/Models/ToDoList.php index c258cbc..e2cbb44 100644 --- a/app/Models/ToDoList.php +++ b/app/Models/ToDoList.php @@ -16,7 +16,7 @@ class ToDoList extends Model return '/to-do-lists/' . $this->id; } - public function users(): BelongsTo + public function author(): BelongsTo { return $this->belongsTo(User::class); } diff --git a/database/factories/ToDoItemFactory.php b/database/factories/ToDoItemFactory.php new file mode 100644 index 0000000..6a3e32a --- /dev/null +++ b/database/factories/ToDoItemFactory.php @@ -0,0 +1,16 @@ +define(ToDo::class, function (Faker $faker) { + $toDoList = factory(\App\Models\ToDoList::class); + return [ + 'to_do_list_id' => $toDoList, + 'name' => $faker->words(3, [false]), + // 'order' => $toDoList->toDos->orderBy('id', 'desc')->first()->order + 1, +// 'checket_at' => now(), + ]; +}); diff --git a/database/migrations/2020_04_19_190733_create_to_dos_table.php b/database/migrations/2020_04_19_190733_create_to_dos_table.php index 75061c7..caf9e56 100644 --- a/database/migrations/2020_04_19_190733_create_to_dos_table.php +++ b/database/migrations/2020_04_19_190733_create_to_dos_table.php @@ -17,7 +17,7 @@ class CreateToDosTable extends Migration $table->id(); $table->unsignedBigInteger('to_do_list_id'); $table->string('name'); - $table->integer('order')->default(0); + $table->integer('order')->default(1); $table->timestamp('checked_at')->nullable(); $table->timestamps(); }); diff --git a/tests/Feature/ToDoItemsTest.php b/tests/Feature/ToDoItemsTest.php index 9a1069c..7a93107 100644 --- a/tests/Feature/ToDoItemsTest.php +++ b/tests/Feature/ToDoItemsTest.php @@ -34,7 +34,7 @@ class ToDoItemsTest extends TestCase 'attributes' => [ 'data' => [ 'name' => $toDo->name, - 'order' => 0, + 'order' => 1, ] ], ], @@ -78,6 +78,11 @@ class ToDoItemsTest extends TestCase [ 'data' => [ 'to_do_id' => $toDoList->toDos[0]->id, + 'attributes' => [ + 'data' => [ + 'name' => $toDoList->toDos[0]->name, + ] + ] ] ] ], @@ -89,6 +94,87 @@ class ToDoItemsTest extends TestCase ]); } + /** @test */ + public function a_new_to_do_must_have_order_of_the_previous_to_do() + { + $this->actingAs($user = factory(User::class)->create(), 'api'); + $toDoList = factory(ToDoList::class)->create(['id' => 123, 'user_id' => $user->id]); + $toDo = factory(ToDo::class)->create(['to_do_list_id' => 123]); + + $response = $this->post('/api/to-do-lists/123/to-do', [ + 'name' => 'New To Do' + ])->assertStatus(201); + + $toDo = ToDo::first(); + $newToDo = ToDo::orderBy('id', 'desc')->first(); + + $this->assertEquals('New To Do', $newToDo->name); + $this->assertEquals($toDo->order + 1, $newToDo->order); + } + + /** @test */ + public function a_second_to_do_as_next_order_of_list() + { + $this->actingAs($user = factory(User::class)->create(), 'api'); + $toDoList = factory(ToDoList::class)->create(['id' => 123, 'user_id' => $user->id]); + $this->post('/api/to-do-lists/123/to-do', ['name' => 'Test name to do']); + $this->post('/api/to-do-lists/123/to-do', ['name' => 'Test 2 name to do']); + $this->post('/api/to-do-lists/123/to-do', ['name' => 'Test 3 name to do']); + + $response = $this->get('/api/to-do-lists/' . $toDoList->id ); + + $response->assertJson([ + 'data' => [ + 'to_do_list_id' => $toDoList->id, + 'attributes' => [ + 'data' => [ + 'name' => $toDoList->name, + 'last_updated' => $toDoList->updated_at->diffForHumans(), + 'to_dos' => [ + 'data' => [ + [ + 'data' => [ + 'to_do_id' => $toDoList->toDos[0]->id, + 'attributes' => [ + 'data' => [ + 'name' => $toDoList->toDos[0]->name, + 'order' => 1, + ] + ] + ], + + ], + [ + 'data' => [ + 'to_do_id' => $toDoList->toDos[1]->id, + 'attributes' => [ + 'data' => [ + 'name' => $toDoList->toDos[1]->name, + 'order' => 2, + ] + ] + ] + ], + [ + 'data' => [ + 'to_do_id' => $toDoList->toDos[2]->id, + 'attributes' => [ + 'data' => [ + 'name' => $toDoList->toDos[2]->name, + 'order' => 3, + ] + ] + ] + ] + ], + 'to_dos_count' => 3, + ] + ] + ], + ] + ]); + } + /** @test */ public function a_to_do_can_be_patch() { @@ -101,7 +187,6 @@ class ToDoItemsTest extends TestCase ]); $toDoList = $toDoList->fresh(); -// $toDoList = ToDoList::first(); $response = $this->patch('/api/to-do-lists/123/to-do/'. $toDoList->toDos[0]->id, [ 'name' => 'To Do update' @@ -121,4 +206,47 @@ class ToDoItemsTest extends TestCase ] ]); } + + /** @test */ + public function only_the_owner_can_patch_the_to_do() + { + $user = factory(User::class)->create(); + $toDoList = factory(ToDoList::class)->create(['id' => 123, 'user_id' => $user->id]); + $toDo = factory(ToDo::class)->create(['to_do_list_id' => 123, 'name' => 'Test name to do']); + + $this->actingAs($anotherUser = factory(User::class)->create(), 'api'); + + $this->patch('/api/to-do-lists/'. $toDoList->id .'/to-do/'. $toDoList->toDos[0]->id, ['name' => 'Name changed']) + ->assertStatus(403); + } + + /** @test */ + public function a_to_do_list_can_be_delete() + { + $this->withoutExceptionHandling(); + $this->actingAs($user = factory(User::class)->create(), 'api'); + + $toDoList = factory(ToDoList::class)->create(['user_id' => $user->id]); + $toDo = factory(ToDo::class)->create(['to_do_list_id' => $toDoList->id]); + + $response = $this->delete('/api/to-do-lists/'. $toDoList->id . '/to-do/' . $toDo->id); + + $this->assertCount(0, ToDo::all()); + + $response->assertStatus(204); + } + + /** @test */ + public function only_the_owner_can_delete_the_to_do_list() + { + $user = factory(User::class)->create(); + $toDoList = factory(ToDoList::class)->create(['user_id' => $user->id]); + $toDo = factory(ToDo::class)->create(['to_do_list_id' => $toDoList->id]); + + $this->actingAs($anotherUser = factory(User::class)->create(), 'api'); + + $response = $this->delete('/api/to-do-lists/'. $toDoList->id . '/to-do/' . $toDo->id); + + $response->assertStatus(403); + } }