@@ -54,4 +54,65 @@ public function test_module_extends_navigation(): void {
5454 $ this ->assertTrue ($ node ->exposed_module_extends_navigation ('data ' ));
5555 $ this ->assertFalse ($ node ->exposed_module_extends_navigation ('test1 ' ));
5656 }
57+
58+ /**
59+ * Test that subsections with hidden restrictions are not shown in the navigation block.
60+ */
61+ public function test_load_section_activities_navigation_hidden_subsection_visibility (): void {
62+ global $ PAGE , $ CFG ;
63+ require_once ($ CFG ->dirroot . '/course/lib.php ' );
64+
65+ $ this ->resetAfterTest ();
66+ $ this ->setAdminUser ();
67+ set_config ('enableavailability ' , 1 );
68+
69+ $ generator = $ this ->getDataGenerator ();
70+ $ course = $ generator ->create_course (['numsections ' => 1 ]);
71+
72+ $ student = $ generator ->create_user ();
73+ $ generator ->enrol_user ($ student ->id , $ course ->id , 'student ' );
74+
75+ // Date condition far in the future: restriction can never be met.
76+ // showc:[false] = eye closed (restriction hidden from students).
77+ $ eyeclosed = '{"op":"&","c":[{"type":"date","d":">=","t":9999999999}],"showc":[false]} ' ;
78+ // showc:[true] = eye open (restriction visible to students, MDL-87671 scenario).
79+ $ eyeopen = '{"op":"&","c":[{"type":"date","d":">=","t":9999999999}],"showc":[true]} ' ;
80+
81+ $ hiddensubsection = $ generator ->create_module ('subsection ' , [
82+ 'course ' => $ course ->id ,
83+ 'section ' => 1 ,
84+ 'availability ' => $ eyeclosed ,
85+ ]);
86+ $ visiblesubsection = $ generator ->create_module ('subsection ' , [
87+ 'course ' => $ course ->id ,
88+ 'section ' => 1 ,
89+ 'availability ' => $ eyeopen ,
90+ ]);
91+
92+ rebuild_course_cache ($ course ->id , true );
93+ $ course = get_course ($ course ->id );
94+
95+ $ this ->setUser ($ student );
96+ $ PAGE ->set_url ('/course/view.php ' , ['id ' => $ course ->id ]);
97+ $ PAGE ->set_course ($ course );
98+ $ PAGE ->set_context (\core \context \course::instance ($ course ->id ));
99+
100+ $ modinfo = get_fast_modinfo ($ course );
101+ $ section1 = $ modinfo ->get_section_info (1 );
102+ $ hiddeninfo = $ modinfo ->get_section_info_by_component ('mod_subsection ' , $ hiddensubsection ->id );
103+ $ visibleinfo = $ modinfo ->get_section_info_by_component ('mod_subsection ' , $ visiblesubsection ->id );
104+
105+ $ nav = new exposed_global_navigation ($ PAGE );
106+ $ nav ->set_initialised ();
107+
108+ [, $ activities ] = $ nav ->exposed_generate_sections_and_activities ($ course );
109+
110+ $ sectionnode = $ nav ->add ('Section 1 ' , null , navigation_node::TYPE_SECTION , null , $ section1 ->id );
111+ $ nav ->exposed_load_section_activities_navigation ($ sectionnode , $ section1 , $ activities );
112+
113+ // Eye-closed restricted subsection must NOT appear in the navigation block.
114+ $ this ->assertFalse ($ sectionnode ->find ($ hiddeninfo ->id , navigation_node::TYPE_SECTION ));
115+ // Eye-open restricted subsection MUST appear in navigation (MDL-87671 behaviour).
116+ $ this ->assertNotFalse ($ sectionnode ->find ($ visibleinfo ->id , navigation_node::TYPE_SECTION ));
117+ }
57118}
0 commit comments