@@ -134,6 +134,32 @@ public function testZip() {
134134 $ this ->assertStringContainsString ('<title>Week 2</title> ' , $ save );
135135 $ this ->assertStringContainsString ('<item identifier=" ' . $ assignmentId . '" identifierref=" ' . $ assignmentIdRef . '"> ' , $ save );
136136 $ this ->assertStringContainsString ('<title>Quiz: Single Table SQL</title> ' , $ save );
137+
138+ // Canvas requires LTI resources to be referenced in the organizations tree
139+ // Verify that a nested item referencing the LTI resource exists under the assignment item
140+ // The nested item should have identifierref matching an LTI resource (LT_*_R pattern)
141+ // and title "(hidden)"
142+ $ this ->assertStringContainsString ('(hidden) ' , $ save , 'Should contain hidden LTI item title ' );
143+
144+ // Verify the LTI resource exists in the manifest (created by zip_add_lti_outcome_to_module)
145+ // The LTI resource should have type "imsbasiclti_xmlv1p0" and identifier matching LT_*_R pattern
146+ $ this ->assertMatchesRegularExpression (
147+ '/<resource identifier="LT_[^"]+_R" type="imsbasiclti_xmlv1p0">/ ' ,
148+ $ save ,
149+ 'Should contain LTI resource for the assignment '
150+ );
151+
152+ // Verify nested item structure: assignment item should contain a nested item
153+ // The nested item should reference the LTI resource via identifierref
154+ // Pattern: <item identifier="ASSIGNMENT_ID" identifierref="ASSIGNMENT_ID_R">...<item identifier="LT_..." identifierref="LT_..._R">
155+ $ assignmentItemPattern = '<item identifier=" ' . preg_quote ($ assignmentId , '/ ' ) . '" ' ;
156+ $ nestedLtiItemPattern = '<item[^>]*identifierref="LT_[^"]+_R" ' ;
157+ $ this ->assertMatchesRegularExpression (
158+ '/ ' . preg_quote ($ assignmentItemPattern , '/ ' ) . '[^>]*>.*? ' . $ nestedLtiItemPattern . '/s ' ,
159+ $ save ,
160+ 'Assignment item should contain nested LTI item with identifierref pointing to LTI resource '
161+ );
162+
137163 $ this ->assertStringContainsString ('<item identifier=" ' . $ topicId . '" identifierref=" ' . $ topicIdRef . '"> ' , $ save );
138164 $ this ->assertStringContainsString ('<title>Discuss: Single Table SQL</title> ' , $ save );
139165 $ this ->assertStringContainsString ('<resource identifier=" ' . $ webLinkIdRef . '" type="imswl_xmlv1p1"> ' , $ save );
@@ -162,8 +188,8 @@ public function testZip() {
162188 $ this ->assertStringContainsString ('<item identifier=" ' . $ assignmentId . '"> ' , $ meta );
163189 $ this ->assertStringContainsString ('<content_type>Assignment</content_type> ' , $ meta );
164190 $ this ->assertStringContainsString ('<title>Quiz: Single Table SQL</title> ' , $ meta );
165- // Canvas assignments use the file path as identifierref, not the _R format
166- $ this ->assertStringContainsString ('<identifierref> ' . $ assignmentFile . '</identifierref> ' , $ meta );
191+ // Canvas assignments use the assignment resource identifier ( _R format)
192+ $ this ->assertStringContainsString ('<identifierref> ' . $ assignmentIdRef . '</identifierref> ' , $ meta );
167193 $ this ->assertStringContainsString ('<item identifier=" ' . $ topicId . '"> ' , $ meta );
168194 $ this ->assertStringContainsString ('<content_type>DiscussionTopic</content_type> ' , $ meta );
169195 $ this ->assertStringContainsString ('<title>Discuss: Single Table SQL</title> ' , $ meta );
0 commit comments