From 46973c2f85fe832247ade9e2693b30ee6834c582 Mon Sep 17 00:00:00 2001 From: gbanyan Date: Fri, 13 Feb 2026 12:59:39 +0800 Subject: [PATCH] test(03-01): add feature tests for note history panel - Test notes index returns author name and created_at for display - Test empty state response (empty array when no notes) - Test Blade view renders all Alpine.js history panel directives - Test store endpoint returns complete note data for cache sync - All 11 tests pass (7 existing + 4 new) --- tests/Feature/Admin/MemberNoteTest.php | 83 ++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/tests/Feature/Admin/MemberNoteTest.php b/tests/Feature/Admin/MemberNoteTest.php index 459347c..075fafb 100644 --- a/tests/Feature/Admin/MemberNoteTest.php +++ b/tests/Feature/Admin/MemberNoteTest.php @@ -202,4 +202,87 @@ class MemberNoteTest extends TestCase $this->assertEquals('Middle note', $notes[1]['content']); $this->assertEquals('Oldest note', $notes[2]['content']); } + + public function test_notes_index_returns_author_name_and_created_at(): void + { + $admin = $this->createAdminUser(); + $otherAdmin = User::factory()->create(['name' => '測試管理員']); + $otherAdmin->assignRole('admin'); + $member = Member::factory()->create(); + + Note::factory()->forMember($member)->byAuthor($admin)->create(['content' => 'Note by admin']); + Note::factory()->forMember($member)->byAuthor($otherAdmin)->create(['content' => 'Note by other']); + + $response = $this->actingAs($admin)->getJson( + route('admin.members.notes.index', $member) + ); + + $response->assertStatus(200); + $notes = $response->json('notes'); + + // Each note must have author.name and created_at for display + foreach ($notes as $note) { + $this->assertNotEmpty($note['author']['name']); + $this->assertNotEmpty($note['created_at']); + } + + // Verify different authors are represented + $authorNames = array_column(array_column($notes, 'author'), 'name'); + $this->assertContains($admin->name, $authorNames); + $this->assertContains('測試管理員', $authorNames); + } + + public function test_notes_index_returns_empty_array_for_member_with_no_notes(): void + { + $admin = $this->createAdminUser(); + $member = Member::factory()->create(); + + $response = $this->actingAs($admin)->getJson( + route('admin.members.notes.index', $member) + ); + + $response->assertStatus(200); + $response->assertJson(['notes' => []]); + $this->assertCount(0, $response->json('notes')); + } + + public function test_member_list_renders_history_panel_directives(): void + { + $admin = $this->createAdminUser(); + Member::factory()->create(); + + $response = $this->actingAs($admin)->get(route('admin.members.index')); + + $response->assertStatus(200); + $response->assertSee('toggleHistory', false); + $response->assertSee('historyOpen', false); + $response->assertSee('x-collapse', false); + $response->assertSee('searchQuery', false); + $response->assertSee('filteredNotes', false); + $response->assertSee('尚無備註', false); + $response->assertSee('aria-expanded', false); + $response->assertSee('notes-panel-', false); + } + + public function test_store_note_returns_note_with_author_for_cache_sync(): void + { + $admin = $this->createAdminUser(); + $member = Member::factory()->create(); + + $response = $this->actingAs($admin)->postJson( + route('admin.members.notes.store', $member), + ['content' => 'Cache sync test note'] + ); + + $response->assertStatus(201); + $note = $response->json('note'); + + // All fields needed for frontend cache sync + $this->assertArrayHasKey('id', $note); + $this->assertArrayHasKey('content', $note); + $this->assertArrayHasKey('created_at', $note); + $this->assertArrayHasKey('author', $note); + $this->assertArrayHasKey('name', $note['author']); + $this->assertEquals($admin->name, $note['author']['name']); + } }