postJson('/api/v1/register', [ 'name' => 'Test User', 'email' => 'newuser@example.com', 'password' => 'password123', ]); $response->assertStatus(201) ->assertJsonPath('status', 'success') ->assertJsonStructure(['data' => ['user', 'token']]); }); test('register rejects duplicate email', function () { User::factory()->create(['email' => 'existing@example.com']); $this->postJson('/api/v1/register', [ 'name' => 'Another', 'email' => 'existing@example.com', 'password' => 'password123', ])->assertStatus(422); }); // ── Login ──────────────────────────────────────────────────────────────────── test('user can login with valid credentials', function () { $user = User::factory()->create([ 'password' => Hash::make('secret123'), 'is_active' => true, ]); $user->assignRole('User'); $this->postJson('/api/v1/login', [ 'email' => $user->email, 'password' => 'secret123', ])->assertOk() ->assertJsonPath('status', 'success') ->assertJsonStructure(['data' => ['token']]); }); test('login rejects wrong password', function () { $user = User::factory()->create(['password' => Hash::make('correct')]); $this->postJson('/api/v1/login', [ 'email' => $user->email, 'password' => 'wrong', ])->assertUnauthorized() ->assertJsonPath('status', 'error'); }); test('login rejects inactive user', function () { $user = User::factory()->create([ 'password' => Hash::make('password'), 'is_active' => false, ]); $this->postJson('/api/v1/login', [ 'email' => $user->email, 'password' => 'password', ])->assertForbidden(); }); // ── Logout ─────────────────────────────────────────────────────────────────── test('authenticated user can logout', function () { $user = User::factory()->create(); $token = $user->createToken('test')->plainTextToken; $this->withHeader('Authorization', "Bearer {$token}") ->postJson('/api/v1/logout') ->assertOk() ->assertJsonPath('status', 'success'); }); test('unauthenticated request to logout returns 401', function () { $this->postJson('/api/v1/logout')->assertUnauthorized(); }); // ── Get User ───────────────────────────────────────────────────────────────── test('authenticated user can fetch own profile', function () { $user = User::factory()->create(); $this->actingAs($user, 'sanctum') ->getJson('/api/v1/user') ->assertOk() ->assertJsonPath('status', 'success') ->assertJsonPath('data.user.email', $user->email); });