@@ -535,6 +535,7 @@ public function __construct() {
535535 /**
536536 * Test renderDiscussions() flattening logic - extracts discussions from items array
537537 * This tests the new functionality added to support items array format
538+ * IMPORTANT: When items array exists, discussions array should NOT be scanned to avoid duplicates
538539 */
539540 public function testRenderDiscussionsFlattensItemsArray () {
540541 $ lessons2 = new class extends \Tsugi \UI \Lessons2 {
@@ -553,19 +554,25 @@ public function testFlattenDiscussions() {
553554
554555 foreach ($ this ->lessons ->modules as $ module ) {
555556 if ( isset ($ module ->hidden ) && $ module ->hidden ) continue ;
556- if ( isset ($ module ->discussions ) && is_array ($ module ->discussions ) ) {
557- foreach ($ module ->discussions as $ discussion ) {
558- $ discussions [] = $ discussion ;
559- }
560- }
561- // Scan items array for discussion items (Lessons 2 format)
562- if ( isset ($ module ->items ) && is_array ($ module ->items ) ) {
557+
558+ // Check if module uses items array (new format)
559+ $ has_items = isset ($ module ->items ) && is_array ($ module ->items ) && count ($ module ->items ) > 0 ;
560+
561+ if ( $ has_items ) {
562+ // New format: scan items array for discussion items
563563 foreach ($ module ->items as $ item ) {
564564 $ item_obj = is_array ($ item ) ? (object )$ item : $ item ;
565565 if ( isset ($ item_obj ->type ) && $ item_obj ->type == 'discussion ' ) {
566566 $ discussions [] = $ item_obj ;
567567 }
568568 }
569+ } else {
570+ // Legacy format: scan discussions array
571+ if ( isset ($ module ->discussions ) && is_array ($ module ->discussions ) ) {
572+ foreach ($ module ->discussions as $ discussion ) {
573+ $ discussions [] = $ discussion ;
574+ }
575+ }
569576 }
570577 }
571578 return $ discussions ;
@@ -604,20 +611,31 @@ public function testFlattenDiscussions() {
604611 'items ' => [
605612 ['type ' => 'discussion ' , 'title ' => 'Array Discussion ' , 'resource_link_id ' => 'rlid6 ' ] // Array format
606613 ]
614+ ],
615+ (object )[
616+ 'title ' => 'Module 4 ' ,
617+ 'anchor ' => 'mod4 ' ,
618+ // No items array - should use legacy discussions array
619+ 'discussions ' => [
620+ (object )['title ' => 'Legacy Discussion ' , 'resource_link_id ' => 'rlid7 ' ]
621+ ]
607622 ]
608623 ];
609624
610625 $ flattened = $ lessons2 ->testFlattenDiscussions ();
611626
612- // Should include top-level discussion
627+ // Should include: top-level (1) + Module 1 items (1) + Module 3 items (1) + Module 4 legacy (1) = 4
613628 $ this ->assertCount (4 , $ flattened , 'Should flatten all discussions from various sources ' );
614629
615630 // Verify all discussions are included
616631 $ titles = array_map (function ($ d ) { return $ d ->title ; }, $ flattened );
617632 $ this ->assertContains ('Top Level Discussion ' , $ titles , 'Should include top-level discussions ' );
618- $ this ->assertContains ('Module Discussion ' , $ titles , 'Should include module discussions ' );
619633 $ this ->assertContains ('Item Discussion ' , $ titles , 'Should include discussions from items array ' );
620634 $ this ->assertContains ('Array Discussion ' , $ titles , 'Should handle array format items ' );
635+ $ this ->assertContains ('Legacy Discussion ' , $ titles , 'Should include legacy discussions when no items array ' );
636+
637+ // Should NOT include Module Discussion from Module 1 (has items array, so discussions array is skipped)
638+ $ this ->assertNotContains ('Module Discussion ' , $ titles , 'Should NOT scan discussions array when items array exists (avoids duplicates) ' );
621639
622640 // Should NOT include hidden module discussions
623641 $ this ->assertNotContains ('Hidden Discussion ' , $ titles , 'Should skip discussions from hidden modules ' );
0 commit comments