seed(RoleUserSeeder::class); $this->kaunter = User::where('email', 'kaunter@koipb.test')->first(); } public function test_kaunter_can_record_attendance(): void { $member = Member::factory()->create(); $res = $this->actingAs($this->kaunter)->postJson(route('counter.store'), ['member_id' => $member->id]); $res->assertOk()->assertJson(['status' => 'ok']); $this->assertDatabaseHas('attendance_records', ['member_id' => $member->id]); } public function test_attendance_cannot_be_duplicated(): void { $member = Member::factory()->create(); AttendanceRecord::create(['member_id' => $member->id, 'attended_at' => now()]); $res = $this->actingAs($this->kaunter)->postJson(route('counter.store'), ['member_id' => $member->id]); $res->assertOk()->assertJson(['status' => 'already']); $this->assertEquals(1, AttendanceRecord::where('member_id', $member->id)->count()); } public function test_unique_constraint_blocks_double_attendance_at_db_level(): void { $member = Member::factory()->create(); AttendanceRecord::create(['member_id' => $member->id, 'attended_at' => now()]); $this->expectException(\Illuminate\Database\UniqueConstraintViolationException::class); AttendanceRecord::create(['member_id' => $member->id, 'attended_at' => now()]); } public function test_search_finds_member_and_reports_not_found(): void { $member = Member::factory()->create(['nama' => 'Zulkifli Bin Hassan', 'no_pekerja' => 'MBIP54321']); $this->actingAs($this->kaunter)->getJson(route('counter.search', ['q' => 'Zulkifli'])) ->assertOk()->assertJsonFragment(['nama' => 'Zulkifli Bin Hassan']); $this->actingAs($this->kaunter)->getJson(route('counter.search', ['q' => 'TiadaOrangIni'])) ->assertOk()->assertJsonFragment(['message' => 'Rekod tidak dijumpai. Individu ini bukan anggota koperasi yang berdaftar.']); } }