diff --git a/app/Models/Foundation/Summit/Speakers/PresentationSpeaker.php b/app/Models/Foundation/Summit/Speakers/PresentationSpeaker.php index dd01a5946..7f69ae347 100644 --- a/app/Models/Foundation/Summit/Speakers/PresentationSpeaker.php +++ b/app/Models/Foundation/Summit/Speakers/PresentationSpeaker.php @@ -532,6 +532,7 @@ public function getPresentationsBySummitAndRole(Summit $summit, $role) if ($role == self::ROLE_SPEAKER) { $res = $this->presentations->filter(function (PresentationSpeakerAssignment $ps_assignment) use ($summit) { $presentation = $ps_assignment->getPresentation(); + if(is_null($presentation)) return false; if ($presentation->getSummit()->getId() != $summit->getId()) return false; if ($presentation->getModeratorId() == $this->getId()) return false; if ($presentation->getCreatorId() == $this->getMemberId()) return false; diff --git a/tests/Unit/Models/PresentationSpeakerPresentationsByRoleTest.php b/tests/Unit/Models/PresentationSpeakerPresentationsByRoleTest.php new file mode 100644 index 000000000..1a3d78a74 --- /dev/null +++ b/tests/Unit/Models/PresentationSpeakerPresentationsByRoleTest.php @@ -0,0 +1,99 @@ +shouldReceive('getId')->andReturn(self::SUMMIT_ID); + return $summit; + } + + /** + * A presentation the speaker is assigned to as a plain speaker in the given summit. + * Moderator and creator ids are non-zero so they can't match a fresh speaker's ids. + */ + private function presentation(Summit $summit): Presentation + { + $presentation = Mockery::mock(Presentation::class); + $presentation->shouldReceive('getSummit')->andReturn($summit); + $presentation->shouldReceive('getModeratorId')->andReturn(99); + $presentation->shouldReceive('getCreatorId')->andReturn(98); + $presentation->shouldReceive('getSpeakerAssignmentsMaxOrder')->andReturn(0); + return $presentation; + } + + private function addOrphanAssignment(PresentationSpeaker $speaker): void + { + $assignment = new PresentationSpeakerAssignment(Mockery::mock(Presentation::class), $speaker, 1); + + $presentation_field = new \ReflectionProperty(PresentationSpeakerAssignment::class, 'presentation'); + $presentation_field->setValue($assignment, null); + + $assignments_field = new \ReflectionProperty(PresentationSpeaker::class, 'presentations'); + $assignments_field->getValue($speaker)->add($assignment); + } + + public function testSkipsAssignmentWithNullPresentationAndKeepsValidOne(): void + { + $summit = $this->summit(); + $presentation = $this->presentation($summit); + + $speaker = new PresentationSpeaker(); + $speaker->addPresentation($presentation); + $this->addOrphanAssignment($speaker); + + $result = $speaker->getPresentationsBySummitAndRole($summit, PresentationSpeaker::ROLE_SPEAKER); + + $this->assertSame([$presentation], array_values($result)); + } + + public function testReturnsEmptyWhenOnlyAssignmentHasNullPresentation(): void + { + $speaker = new PresentationSpeaker(); + $this->addOrphanAssignment($speaker); + + $result = $speaker->getPresentationsBySummitAndRole($this->summit(), PresentationSpeaker::ROLE_SPEAKER); + + $this->assertSame([], $result); + } +}