seed([RoleSeeder::class, SamplePsgcSeeder::class]); $this->admin = User::factory()->create([ 'role' => User::ROLE_ADMIN, 'status' => User::STATUS_ACTIVE, ]); } public function test_admin_can_create_service_area_with_barangays(): void { Sanctum::actingAs($this->admin); $barangays = Barangay::limit(3)->pluck('id')->all(); $response = $this->postJson('/api/v1/service-areas', [ 'name' => 'QC Pilot', 'code' => 'QC-PILOT', 'description' => 'Pilot area covering 3 QC barangays', 'barangay_ids' => $barangays, ]); $response->assertCreated() ->assertJsonPath('data.code', 'QC-PILOT') ->assertJsonPath('data.barangay_count', 3); $this->assertDatabaseHas('service_areas', ['code' => 'QC-PILOT']); $this->assertDatabaseCount('service_area_barangay', 3); } public function test_resident_cannot_create_service_area(): void { $resident = User::factory()->create([ 'role' => User::ROLE_RESIDENT, 'status' => User::STATUS_ACTIVE, ]); Sanctum::actingAs($resident); $response = $this->postJson('/api/v1/service-areas', [ 'name' => 'Sneaky', 'code' => 'SNK', ]); $response->assertStatus(403); } public function test_unauthenticated_blocked(): void { $this->getJson('/api/v1/service-areas')->assertStatus(401); } public function test_duplicate_code_rejected(): void { Sanctum::actingAs($this->admin); ServiceArea::factory()->create(['code' => 'DUP']); $response = $this->postJson('/api/v1/service-areas', [ 'name' => 'Other', 'code' => 'DUP', ]); $response->assertStatus(422) ->assertJsonValidationErrors(['code']); } public function test_admin_can_attach_barangays(): void { Sanctum::actingAs($this->admin); $area = ServiceArea::factory()->create(); $barangays = Barangay::limit(2)->pluck('id')->all(); $response = $this->postJson("/api/v1/service-areas/{$area->uuid}/barangays", [ 'barangay_ids' => $barangays, ]); $response->assertOk() ->assertJsonPath('data.barangay_count', 2); } public function test_admin_can_detach_barangay(): void { Sanctum::actingAs($this->admin); $area = ServiceArea::factory()->create(); $barangay = Barangay::first(); $area->barangays()->attach($barangay->id); $response = $this->deleteJson("/api/v1/service-areas/{$area->uuid}/barangays/{$barangay->id}"); $response->assertOk(); $this->assertDatabaseMissing('service_area_barangay', [ 'service_area_id' => $area->id, 'barangay_id' => $barangay->id, ]); } public function test_admin_can_update_service_area(): void { Sanctum::actingAs($this->admin); $area = ServiceArea::factory()->create(['name' => 'Old']); $response = $this->patchJson("/api/v1/service-areas/{$area->uuid}", [ 'name' => 'New Name', 'status' => 'inactive', ]); $response->assertOk() ->assertJsonPath('data.name', 'New Name') ->assertJsonPath('data.status', 'inactive'); } public function test_admin_can_delete_service_area(): void { Sanctum::actingAs($this->admin); $area = ServiceArea::factory()->create(); $response = $this->deleteJson("/api/v1/service-areas/{$area->uuid}"); $response->assertOk(); $this->assertSoftDeleted('service_areas', ['id' => $area->id]); } public function test_admin_can_list_with_filter(): void { Sanctum::actingAs($this->admin); ServiceArea::factory()->create(['code' => 'A', 'status' => 'active']); ServiceArea::factory()->create(['code' => 'B', 'status' => 'inactive']); $response = $this->getJson('/api/v1/service-areas?status=active'); $response->assertOk(); $codes = collect($response->json('data'))->pluck('code')->all(); $this->assertContains('A', $codes); $this->assertNotContains('B', $codes); } }