diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php new file mode 100644 index 00000000..d8522173 --- /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' => 'required|string', + 'email' => '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/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'; }); diff --git a/routes/api/v1/user.php b/routes/api/v1/user.php new file mode 100644 index 00000000..2c00c9b3 --- /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/{user}', [UserController::class, 'show'])->name('api.v1.users.show'); + 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 new file mode 100644 index 00000000..a706a7b4 --- /dev/null +++ b/tests/Feature/Http/Controllers/UserControllerTest.php @@ -0,0 +1,143 @@ +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', + ]; + + // 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($userData); + } + + /** + * 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.']); + } +}