From ad6553fa00b648512ddadf6ef29c21120e214a64 Mon Sep 17 00:00:00 2001 From: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> Date: Wed, 13 Dec 2023 02:18:04 +0100 Subject: [PATCH 1/6] add user routes Signed-off-by: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> --- routes/api.php | 1 + 1 file changed, 1 insertion(+) diff --git a/routes/api.php b/routes/api.php index 8ad25252..6015235b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -22,4 +22,5 @@ */ Route::group(['prefix' => 'v1'], function () { require __DIR__ . '/api/v1/auth.php'; + require __DIR__ . '/api/v1/user.php'; }); From d5fea78f405dabe1c0bbf958285c5b9cbedce8b1 Mon Sep 17 00:00:00 2001 From: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> Date: Wed, 13 Dec 2023 02:18:16 +0100 Subject: [PATCH 2/6] define user routes Signed-off-by: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> --- routes/api/v1/user.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 routes/api/v1/user.php diff --git a/routes/api/v1/user.php b/routes/api/v1/user.php new file mode 100644 index 00000000..4118f25a --- /dev/null +++ b/routes/api/v1/user.php @@ -0,0 +1,12 @@ + 'auth:sanctum'], function () { + Route::get('/users', [UserController::class, 'index'])->name('api.v1.users.index'); + Route::post('/users', [UserController::class, 'store'])->name('api.v1.users.store'); + Route::get('/users/{id}', [UserController::class, 'show'])->name('api.v1.users.show'); + Route::patch('/users/{id}', [UserController::class, 'update'])->name('api.v1.users.update'); + Route::delete('/users/{id}', [UserController::class, 'destroy'])->name('api.v1.users.destroy'); +}); From 5e7c6576bfcf211a500ca69431d7b7446e3082ec Mon Sep 17 00:00:00 2001 From: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> Date: Wed, 13 Dec 2023 04:55:23 +0100 Subject: [PATCH 3/6] update routes to simplify identification Signed-off-by: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> --- routes/api/v1/user.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/routes/api/v1/user.php b/routes/api/v1/user.php index 4118f25a..87b9dd89 100644 --- a/routes/api/v1/user.php +++ b/routes/api/v1/user.php @@ -6,7 +6,7 @@ Route::group(['middleware' => 'auth:sanctum'], function () { Route::get('/users', [UserController::class, 'index'])->name('api.v1.users.index'); Route::post('/users', [UserController::class, 'store'])->name('api.v1.users.store'); - Route::get('/users/{id}', [UserController::class, 'show'])->name('api.v1.users.show'); - Route::patch('/users/{id}', [UserController::class, 'update'])->name('api.v1.users.update'); - Route::delete('/users/{id}', [UserController::class, 'destroy'])->name('api.v1.users.destroy'); + Route::get('/users/{user}', [UserController::class, 'show'])->name('api.v1.users.show'); + Route::patch('/users/{user}', [UserController::class, 'update'])->name('api.v1.users.update'); + Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('api.v1.users.destroy'); }); From 506002b4099a6a503b02d6d017a656a777be284b Mon Sep 17 00:00:00 2001 From: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> Date: Wed, 13 Dec 2023 04:55:42 +0100 Subject: [PATCH 4/6] add UserController Signed-off-by: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> --- app/Http/Controllers/UserController.php | 73 +++++++++ .../Http/Controllers/UserControllerTest.php | 140 ++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 app/Http/Controllers/UserController.php create mode 100644 tests/Feature/Http/Controllers/UserControllerTest.php diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php new file mode 100644 index 00000000..a79372f5 --- /dev/null +++ b/app/Http/Controllers/UserController.php @@ -0,0 +1,73 @@ +has('size') ? request()->size : 15 + ); + + return new ApiSuccessResponse($users); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|email|unique:users,email', + 'password' => 'required|string|min:8|confirmed', + ]); + + $user = User::create($validated); + + return new ApiSuccessResponse($user, Response::HTTP_CREATED); + } + + /** + * Display the specified resource. + */ + public function show(User $user) + { + return new ApiSuccessResponse($user); + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, User $user) + { + $validated = $request->validate([ + 'name' => 'sometimes|required|string', + 'email' => "sometimes|required|email|unique:users,email", + 'password' => 'sometimes|required|min:8|confirmed', + ]); + + $user->update($validated); + + return new ApiSuccessResponse($user); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(User $user) + { + $user->delete(); + + return new ApiSuccessResponse("User deleted successfully."); + } +} diff --git a/tests/Feature/Http/Controllers/UserControllerTest.php b/tests/Feature/Http/Controllers/UserControllerTest.php new file mode 100644 index 00000000..fe7ce748 --- /dev/null +++ b/tests/Feature/Http/Controllers/UserControllerTest.php @@ -0,0 +1,140 @@ +count(10)->create(); + + Sanctum::actingAs( + User::factory()->create() + ); + + // Send a GET request to the index endpoint + $response = $this->get('/api/v1/users'); + + // Assert that the response has a successful status code + $response->assertStatus(200); + + // Assert that the response contains the paginated users + $response->assertJsonFragment(User::paginate(15)->toArray()); + } + + /** + * Test the store method. + */ + public function test_create_user(): void + { + Sanctum::actingAs( + User::factory()->create() + ); + + $userData = [ + 'name' => 'John Doe', + 'email' => 'john.doe@example.com', + 'password' => 'password', + 'password_confirmation' => 'password', + ]; + + // Send a POST request to the store endpoint + $response = $this->post('/api/v1/users', $userData); + + // Assert that the response has a successful status code + $response->assertStatus(201); + + // Assert that the database has the user + $this->assertDatabaseHas('users', [ + 'name' => $userData['name'], + 'email' => $userData['email'], + ]); + + // Assert that the response contains the user data + $response->assertJsonFragment([ + 'name' => $userData['name'], + 'email' => $userData['email'], + ]); + } + + /** + * Test the show method. + */ + public function test_users_show(): void + { + Sanctum::actingAs( + User::factory()->create() + ); + + $user = User::factory()->create(); + + // Send a GET request to the show endpoint + $response = $this->get('/api/v1/users/' . $user->id); + + // Assert that the response has a successful status code + $response->assertStatus(200); + + // Assert that the response contains the user data + $response->assertJsonFragment($user->toArray()); + } + + /** + * Test the update method. + */ + public function test_users_update(): void + { + Sanctum::actingAs( + User::factory()->create() + ); + + $user = User::factory()->create(); + + $userData = [ + 'name' => 'Updated Name', + 'email' => 'updated.email@example.com', + ]; + + $newUserData = array_merge($user->toArray(), $userData); + + // Send a PATCH request to the update endpoint + $response = $this->patch('/api/v1/users/' . $user->id, $userData); + + // Assert that the response has a successful status code + $response->assertStatus(200); + + // Assert that the response contains the updated user data + $response->assertJsonFragment($newUserData); + } + + /** + * Test the destroy method. + */ + public function test_users_destroy(): void + { + Sanctum::actingAs( + User::factory()->create() + ); + + $user = User::factory()->create(); + + // Send a DELETE request to the destroy endpoint + $response = $this->delete('/api/v1/users/' . $user->id); + + // Assert that the response has a successful status code + $response->assertStatus(200); + + // Assert that the response contains the success message + $response->assertJsonFragment(['data' => 'User deleted successfully.']); + } +} From 3a50530edda2998212fc4452cbf9e53fed7603b1 Mon Sep 17 00:00:00 2001 From: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> Date: Wed, 13 Dec 2023 05:02:11 +0100 Subject: [PATCH 5/6] change to put Signed-off-by: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> --- app/Http/Controllers/UserController.php | 4 ++-- routes/api/v1/user.php | 2 +- tests/Feature/Http/Controllers/UserControllerTest.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index a79372f5..d8522173 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -51,8 +51,8 @@ public function show(User $user) public function update(Request $request, User $user) { $validated = $request->validate([ - 'name' => 'sometimes|required|string', - 'email' => "sometimes|required|email|unique:users,email", + 'name' => 'required|string', + 'email' => 'required|email|unique:users,email', 'password' => 'sometimes|required|min:8|confirmed', ]); diff --git a/routes/api/v1/user.php b/routes/api/v1/user.php index 87b9dd89..2c00c9b3 100644 --- a/routes/api/v1/user.php +++ b/routes/api/v1/user.php @@ -7,6 +7,6 @@ Route::get('/users', [UserController::class, 'index'])->name('api.v1.users.index'); Route::post('/users', [UserController::class, 'store'])->name('api.v1.users.store'); Route::get('/users/{user}', [UserController::class, 'show'])->name('api.v1.users.show'); - Route::patch('/users/{user}', [UserController::class, 'update'])->name('api.v1.users.update'); + Route::put('/users/{user}', [UserController::class, 'update'])->name('api.v1.users.update'); Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('api.v1.users.destroy'); }); diff --git a/tests/Feature/Http/Controllers/UserControllerTest.php b/tests/Feature/Http/Controllers/UserControllerTest.php index fe7ce748..947800ce 100644 --- a/tests/Feature/Http/Controllers/UserControllerTest.php +++ b/tests/Feature/Http/Controllers/UserControllerTest.php @@ -108,7 +108,7 @@ public function test_users_update(): void $newUserData = array_merge($user->toArray(), $userData); // Send a PATCH request to the update endpoint - $response = $this->patch('/api/v1/users/' . $user->id, $userData); + $response = $this->put('/api/v1/users/' . $user->id, $userData); // Assert that the response has a successful status code $response->assertStatus(200); From 34e70fc427d2a7bbd3d83ad69cb07f1ac44226e4 Mon Sep 17 00:00:00 2001 From: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> Date: Wed, 13 Dec 2023 19:50:10 +0100 Subject: [PATCH 6/6] change update test Signed-off-by: Valentin Sickert <17144397+Lapotor@users.noreply.github.com> --- tests/Feature/Http/Controllers/UserControllerTest.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/Feature/Http/Controllers/UserControllerTest.php b/tests/Feature/Http/Controllers/UserControllerTest.php index 947800ce..a706a7b4 100644 --- a/tests/Feature/Http/Controllers/UserControllerTest.php +++ b/tests/Feature/Http/Controllers/UserControllerTest.php @@ -105,16 +105,19 @@ public function test_users_update(): void 'email' => 'updated.email@example.com', ]; - $newUserData = array_merge($user->toArray(), $userData); - // Send a PATCH request to the update endpoint $response = $this->put('/api/v1/users/' . $user->id, $userData); // Assert that the response has a successful status code $response->assertStatus(200); + $this->assertDatabaseHas('users', [ + 'name' => $userData['name'], + 'email' => $userData['email'], + ]); + // Assert that the response contains the updated user data - $response->assertJsonFragment($newUserData); + $response->assertJsonFragment($userData); } /**