shouldReceive('fetchStaffList') ->once() ->with('2025-2026', [10, 20]) ->andReturn([ [ 'id' => 10, 'firstname' => 'John', 'lastname' => 'Doe', 'roles' => 'teacher_assistant,admin', ], [ 'id' => 20, 'firstname' => 'Sara', 'lastname' => 'Smith', 'roles' => 'staff', ], ]); $lookup->shouldReceive('getLatestClassForUser') ->once() ->with(10, '2025-2026') ->andReturn([ 'class_section_id' => 5, 'class_section_name' => '3-A', ]); $lookup->shouldReceive('getAvailableSchoolYears') ->once() ->andReturn(['2025-2026', '2024-2025']); $service = new BadgeFormDataService($lookup, $formatter); $result = $service->build('2025-2026', [10, 20], 'teacher'); $this->assertSame('2025-2026', $result['selectedYear']); $this->assertSame([10, 20], $result['selectedUserIds']); $this->assertSame('teacher', $result['active_role']); $this->assertCount(2, $result['users']); $this->assertSame(10, $result['users'][0]['user_id']); $this->assertSame('Teacher Assistant, Admin', $result['users'][0]['roles']); $this->assertSame('teacher_assistant', $result['users'][0]['role_name_raw']); $this->assertSame('Teacher Assistant', $result['users'][0]['role_name']); $this->assertSame(5, $result['users'][0]['class_section_id']); $this->assertSame('3-A', $result['users'][0]['class_section_name']); $this->assertSame(20, $result['users'][1]['user_id']); $this->assertSame('Staff', $result['users'][1]['roles']); $this->assertNull($result['users'][1]['class_section_id']); } public function test_build_defaults_invalid_active_role_to_teacher(): void { $lookup = Mockery::mock(BadgeUserLookupService::class); $formatter = new BadgeTextFormatter; $lookup->shouldReceive('fetchStaffList') ->once() ->andReturn([]); $lookup->shouldReceive('getAvailableSchoolYears') ->once() ->andReturn([]); $service = new BadgeFormDataService($lookup, $formatter); $result = $service->build('2025-2026', [], 'invalid-role'); $this->assertSame('teacher', $result['active_role']); } }