answers = Mockery::mock(AnswerRepository::class); $this->questions = Mockery::mock(QuestionRepository::class); $this->acceptances = Mockery::mock(AcceptanceRepository::class); $this->policies = Mockery::mock(PolicyRepository::class); $this->versions = Mockery::mock(PolicyVersionRepository::class); $this->detail = new LessonDetail( $this->answers, $this->questions, $this->acceptances, $this->policies, $this->versions ); } public function testAnswersPairEachAnswerWithItsQuestionLabel(): void { $this->answers->shouldReceive('findByRegistration')->once()->with(Answer::REG_LESSON, 7)->andReturn([ new Answer(questionId: 2, registrationType: Answer::REG_LESSON, registrationId: 7, studentId: 5, answerValue: 'Beginner'), new Answer(questionId: 9, registrationType: Answer::REG_LESSON, registrationId: 7, studentId: 5, answerValue: null), ]); $this->questions->shouldReceive('findById')->with(2)->andReturn(new Question(offeringId: 1, label: 'Skill level', id: 2)); $this->questions->shouldReceive('findById')->with(9)->andReturn(null); self::assertSame( [ ['question' => 'Skill level', 'answer' => 'Beginner'], ['question' => '#9', 'answer' => '—'], ], $this->detail->answers(7) ); } public function testAcceptancesResolvePolicyTitleVersionAndAuditTrail(): void { $this->acceptances->shouldReceive('findByRegistration')->once()->with(PolicyAcceptance::REG_LESSON, 7)->andReturn([ new PolicyAcceptance( policyVersionId: 4, studentId: 5, registrationType: PolicyAcceptance::REG_LESSON, registrationId: 7, ipAddress: '1.2.3.4', acceptedAt: '2026-07-01 10:00:00' ), ]); $this->versions->shouldReceive('findById')->with(4)->andReturn(new PolicyVersion(policyId: 3, versionNumber: 2, id: 4)); $this->policies->shouldReceive('findById')->with(3)->andReturn(new Policy(title: 'Cancellation', slug: 'cancellation', id: 3)); self::assertSame( [ [ 'policy' => 'Cancellation', 'version' => 'v2', 'accepted_at' => '2026-07-01 10:00:00', 'ip' => '1.2.3.4', ], ], $this->detail->acceptances(7) ); } }