From f89d7093d2c576ad5e2b35a6a096fcdaf563d1df Mon Sep 17 00:00:00 2001 From: Nicolas Terray Date: Mon, 30 Sep 2024 12:45:48 +0200 Subject: [PATCH] fix: request #39728: If a user does not have access at all to a tracker, it should not be displayed in the backlog. Change-Id: Ib75b1fc455a9442c30ecb18c63058f429fb1a128 --- .../Planning/PlanningFactory.class.php | 5 +- ...ngFactoryTestGetVirtualTopPlanningTest.php | 62 +++++++++++++++++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/plugins/agiledashboard/include/Planning/PlanningFactory.class.php b/plugins/agiledashboard/include/Planning/PlanningFactory.class.php index 0791da3cb1c..5299c6777fa 100644 --- a/plugins/agiledashboard/include/Planning/PlanningFactory.class.php +++ b/plugins/agiledashboard/include/Planning/PlanningFactory.class.php @@ -173,7 +173,10 @@ public function getVirtualTopPlanning(PFUser $user, $group_id) } foreach ($backlog_tracker_ids as $backlog_tracker_id) { - $backlog_trackers[] = $this->tracker_factory->getTrackerById($backlog_tracker_id); + $tracker = $this->tracker_factory->getTrackerById($backlog_tracker_id); + if ($tracker && $tracker->userCanView($user)) { + $backlog_trackers[] = $tracker; + } } $planning = new Planning( diff --git a/plugins/agiledashboard/tests/unit/AgileDashboard/Planning/PlanningFactoryTestGetVirtualTopPlanningTest.php b/plugins/agiledashboard/tests/unit/AgileDashboard/Planning/PlanningFactoryTestGetVirtualTopPlanningTest.php index b5165599c11..c068e7c6bca 100644 --- a/plugins/agiledashboard/tests/unit/AgileDashboard/Planning/PlanningFactoryTestGetVirtualTopPlanningTest.php +++ b/plugins/agiledashboard/tests/unit/AgileDashboard/Planning/PlanningFactoryTestGetVirtualTopPlanningTest.php @@ -37,17 +37,24 @@ final class PlanningFactoryTestGetVirtualTopPlanningTest extends TestCase { + private const PROJECT_ID = 101; + private const SPRINT_ID = 1000; + private const STORIES_ID = 1001; + private const TOPSECRET_ID = 1002; + private PlanningFactory&MockObject $partial_factory; private TrackerFactory&MockObject $tracker_factory; + private PlanningDao&MockObject $planning_dao; + private PlanningPermissionsManager&MockObject $planning_permissions_manager; protected function setUp(): void { - $planning_dao = $this->createMock(PlanningDao::class); - $this->tracker_factory = $this->createMock(TrackerFactory::class); - $planning_permissions_manager = $this->createMock(PlanningPermissionsManager::class); + $this->planning_dao = $this->createMock(PlanningDao::class); + $this->tracker_factory = $this->createMock(TrackerFactory::class); + $this->planning_permissions_manager = $this->createMock(PlanningPermissionsManager::class); $this->partial_factory = $this->getMockBuilder(PlanningFactory::class) - ->setConstructorArgs([$planning_dao, $this->tracker_factory, $planning_permissions_manager]) + ->setConstructorArgs([$this->planning_dao, $this->tracker_factory, $this->planning_permissions_manager]) ->onlyMethods(['getRootPlanning']) ->getMock(); } @@ -62,8 +69,8 @@ public function testItThrowsAnExceptionIfNoPlanningsExistForProject(): void public function testItCreatesNewPlanningWithValidBacklogAndPlanningTrackers(): void { - $backlog_tracker = TrackerTestBuilder::aTracker()->withId(78)->build(); - $planning_tracker = TrackerTestBuilder::aTracker()->withId(45)->build(); + $backlog_tracker = TrackerTestBuilder::aTracker()->withId(78)->withUserCanView(true)->build(); + $planning_tracker = TrackerTestBuilder::aTracker()->withId(45)->withUserCanView(true)->build(); $my_planning = PlanningBuilder::aPlanning(56) ->withBacklogTrackers($backlog_tracker) @@ -82,4 +89,47 @@ public function testItCreatesNewPlanningWithValidBacklogAndPlanningTrackers(): v $backlog_trackers = $planning->getBacklogTrackers(); self::assertInstanceOf(Tracker::class, $backlog_trackers[0]); } + + public function testGetVirtualTopPlanningExcludesBacklogTrackersUserCannotSeeSoItDoesNotProposeToAddThemInPV2(): void + { + $factory = new PlanningFactory( + $this->planning_dao, + $this->tracker_factory, + $this->planning_permissions_manager, + ); + + $user = UserTestBuilder::buildWithDefaults(); + + $sprint = TrackerTestBuilder::aTracker()->withId(self::SPRINT_ID)->withUserCanView(true)->build(); + $stories = TrackerTestBuilder::aTracker()->withId(self::STORIES_ID)->withUserCanView(true)->build(); + $topsecret = TrackerTestBuilder::aTracker()->withId(self::TOPSECRET_ID)->withUserCanView(false)->build(); + + $this->tracker_factory->method('getTrackerById')->willReturnCallback(static fn($id) => match ($id) { + self::SPRINT_ID => $sprint, + self::STORIES_ID => $stories, + self::TOPSECRET_ID => $topsecret, + }); + $this->tracker_factory->method('getHierarchy')->willReturn(new \Tracker_Hierarchy()); + + $this->planning_dao->method('searchByProjectId')->willReturn([[ + 'id' => 1, + 'name' => 'Sprint planning', + 'group_id' => self::PROJECT_ID, + 'planning_tracker_id' => $sprint->id, + 'backlog_title' => 'backlog', + 'plan_title' => 'milestone', + ], + ]); + $this->planning_dao->method('searchBacklogTrackersByPlanningId')->willReturn([ + ['planning_id' => 1, 'tracker_id' => self::STORIES_ID], + ['planning_id' => 1, 'tracker_id' => self::TOPSECRET_ID], + ]); + + $planning = $factory->getVirtualTopPlanning($user, self::PROJECT_ID); + + self::assertSame( + [$stories], + $planning->getBacklogTrackers(), + ); + } }