@@ -12,7 +12,7 @@ import {
1212 getTestCanvasJwks ,
1313 signCanvasIdToken ,
1414} from './test_helpers/lti.ts' ;
15- import { withFetchStub } from './app_test_support.ts' ;
15+ import { withFetchStub , withRuntimeOriginEnv } from './app_test_support.ts' ;
1616
1717Deno . test ( 'POST /lti/launch accepts a signed Moodle resource-link launch and records shared audit evidence' , async ( ) => {
1818 const repository = createInMemoryPackageReviewRepository ( {
@@ -72,49 +72,51 @@ Deno.test('POST /lti/launch accepts a signed Moodle resource-link launch and rec
7272 } ) ,
7373 ) ;
7474
75- await withFetchStub (
76- ( ) =>
77- Promise . resolve (
78- new Response ( JSON . stringify ( getTestCanvasJwks ( ) ) , {
79- status : 200 ,
80- headers : { 'content-type' : 'application/json' } ,
81- } ) ,
82- ) ,
83- async ( ) => {
84- const response = await createApp ( {
85- getRepository : ( ) => repository ,
86- } ) . request ( 'http://localhost/lti/launch' , {
87- method : 'POST' ,
88- body : formData ,
89- } ) ;
90-
91- assertEquals ( response . status , 303 ) ;
92- const location = response . headers . get ( 'location' ) ;
93-
94- if ( ! location ) {
95- throw new Error ( 'Expected runtime-session handoff redirect.' ) ;
96- }
97-
98- const sessionId = location . match ( / \/ r u n t i m e \/ s e s s i o n s \/ ( [ ^ ? ] + ) / ) ?. [ 1 ] ;
99-
100- if ( ! sessionId ) {
101- throw new Error ( 'Expected runtime session id in redirect.' ) ;
102- }
103-
104- const saved = await repository . getRuntimeSessionById ( sessionId ) ;
105- const auditEvents = await repository . listAuditEventsByEventType ( 'launch.accepted' ) ;
106-
107- assertEquals ( saved ?. deploymentRecordId , 13 ) ;
108- assertEquals ( saved ?. launch . courseId , 'moodle-course-42' ) ;
109- assertEquals ( auditEvents . length , 1 ) ;
110- assertEquals ( auditEvents [ 0 ] ?. detail . lms , 'moodle' ) ;
111- assertEquals ( auditEvents [ 0 ] ?. detail . issuer , 'https://moodle.example' ) ;
112- assertEquals ( auditEvents [ 0 ] ?. detail . clientId , 'moodle-client-123' ) ;
113- assertEquals ( auditEvents [ 0 ] ?. detail . deploymentId , 'moodle-deployment-123' ) ;
114- assertEquals ( auditEvents [ 0 ] ?. detail . resourceLinkId , 'moodle-resource-link' ) ;
115- assertEquals ( auditEvents [ 0 ] ?. detail . contextId , 'moodle-course-42' ) ;
116- } ,
117- ) ;
75+ await withRuntimeOriginEnv ( async ( ) => {
76+ await withFetchStub (
77+ ( ) =>
78+ Promise . resolve (
79+ new Response ( JSON . stringify ( getTestCanvasJwks ( ) ) , {
80+ status : 200 ,
81+ headers : { 'content-type' : 'application/json' } ,
82+ } ) ,
83+ ) ,
84+ async ( ) => {
85+ const response = await createApp ( {
86+ getRepository : ( ) => repository ,
87+ } ) . request ( 'http://localhost/lti/launch' , {
88+ method : 'POST' ,
89+ body : formData ,
90+ } ) ;
91+
92+ assertEquals ( response . status , 303 ) ;
93+ const location = response . headers . get ( 'location' ) ;
94+
95+ if ( ! location ) {
96+ throw new Error ( 'Expected runtime-session handoff redirect.' ) ;
97+ }
98+
99+ const sessionId = location . match ( / \/ r u n t i m e \/ s e s s i o n s \/ ( [ ^ ? ] + ) / ) ?. [ 1 ] ;
100+
101+ if ( ! sessionId ) {
102+ throw new Error ( 'Expected runtime session id in redirect.' ) ;
103+ }
104+
105+ const saved = await repository . getRuntimeSessionById ( sessionId ) ;
106+ const auditEvents = await repository . listAuditEventsByEventType ( 'launch.accepted' ) ;
107+
108+ assertEquals ( saved ?. deploymentRecordId , 13 ) ;
109+ assertEquals ( saved ?. launch . courseId , 'moodle-course-42' ) ;
110+ assertEquals ( auditEvents . length , 1 ) ;
111+ assertEquals ( auditEvents [ 0 ] ?. detail . lms , 'moodle' ) ;
112+ assertEquals ( auditEvents [ 0 ] ?. detail . issuer , 'https://moodle.example' ) ;
113+ assertEquals ( auditEvents [ 0 ] ?. detail . clientId , 'moodle-client-123' ) ;
114+ assertEquals ( auditEvents [ 0 ] ?. detail . deploymentId , 'moodle-deployment-123' ) ;
115+ assertEquals ( auditEvents [ 0 ] ?. detail . resourceLinkId , 'moodle-resource-link' ) ;
116+ assertEquals ( auditEvents [ 0 ] ?. detail . contextId , 'moodle-course-42' ) ;
117+ } ,
118+ ) ;
119+ } ) ;
118120} ) ;
119121
120122Deno . test ( 'POST /lti/launch accepts a signed Sakai resource-link launch and records shared audit evidence' , async ( ) => {
@@ -175,47 +177,49 @@ Deno.test('POST /lti/launch accepts a signed Sakai resource-link launch and reco
175177 } ) ,
176178 ) ;
177179
178- await withFetchStub (
179- ( ) =>
180- Promise . resolve (
181- new Response ( JSON . stringify ( getTestCanvasJwks ( ) ) , {
182- status : 200 ,
183- headers : { 'content-type' : 'application/json' } ,
184- } ) ,
185- ) ,
186- async ( ) => {
187- const response = await createApp ( {
188- getRepository : ( ) => repository ,
189- } ) . request ( 'http://localhost/lti/launch' , {
190- method : 'POST' ,
191- body : formData ,
192- } ) ;
193-
194- assertEquals ( response . status , 303 ) ;
195- const location = response . headers . get ( 'location' ) ;
196-
197- if ( ! location ) {
198- throw new Error ( 'Expected runtime-session handoff redirect.' ) ;
199- }
200-
201- const sessionId = location . match ( / \/ r u n t i m e \/ s e s s i o n s \/ ( [ ^ ? ] + ) / ) ?. [ 1 ] ;
202-
203- if ( ! sessionId ) {
204- throw new Error ( 'Expected runtime session id in redirect.' ) ;
205- }
206-
207- const saved = await repository . getRuntimeSessionById ( sessionId ) ;
208- const auditEvents = await repository . listAuditEventsByEventType ( 'launch.accepted' ) ;
209-
210- assertEquals ( saved ?. deploymentRecordId , 17 ) ;
211- assertEquals ( saved ?. launch . courseId , 'sakai-course-42' ) ;
212- assertEquals ( auditEvents . length , 1 ) ;
213- assertEquals ( auditEvents [ 0 ] ?. detail . lms , 'sakai' ) ;
214- assertEquals ( auditEvents [ 0 ] ?. detail . issuer , 'https://sakai.example' ) ;
215- assertEquals ( auditEvents [ 0 ] ?. detail . clientId , 'sakai-client-123' ) ;
216- assertEquals ( auditEvents [ 0 ] ?. detail . deploymentId , 'sakai-deployment-123' ) ;
217- assertEquals ( auditEvents [ 0 ] ?. detail . resourceLinkId , 'sakai-resource-link' ) ;
218- assertEquals ( auditEvents [ 0 ] ?. detail . contextId , 'sakai-course-42' ) ;
219- } ,
220- ) ;
180+ await withRuntimeOriginEnv ( async ( ) => {
181+ await withFetchStub (
182+ ( ) =>
183+ Promise . resolve (
184+ new Response ( JSON . stringify ( getTestCanvasJwks ( ) ) , {
185+ status : 200 ,
186+ headers : { 'content-type' : 'application/json' } ,
187+ } ) ,
188+ ) ,
189+ async ( ) => {
190+ const response = await createApp ( {
191+ getRepository : ( ) => repository ,
192+ } ) . request ( 'http://localhost/lti/launch' , {
193+ method : 'POST' ,
194+ body : formData ,
195+ } ) ;
196+
197+ assertEquals ( response . status , 303 ) ;
198+ const location = response . headers . get ( 'location' ) ;
199+
200+ if ( ! location ) {
201+ throw new Error ( 'Expected runtime-session handoff redirect.' ) ;
202+ }
203+
204+ const sessionId = location . match ( / \/ r u n t i m e \/ s e s s i o n s \/ ( [ ^ ? ] + ) / ) ?. [ 1 ] ;
205+
206+ if ( ! sessionId ) {
207+ throw new Error ( 'Expected runtime session id in redirect.' ) ;
208+ }
209+
210+ const saved = await repository . getRuntimeSessionById ( sessionId ) ;
211+ const auditEvents = await repository . listAuditEventsByEventType ( 'launch.accepted' ) ;
212+
213+ assertEquals ( saved ?. deploymentRecordId , 17 ) ;
214+ assertEquals ( saved ?. launch . courseId , 'sakai-course-42' ) ;
215+ assertEquals ( auditEvents . length , 1 ) ;
216+ assertEquals ( auditEvents [ 0 ] ?. detail . lms , 'sakai' ) ;
217+ assertEquals ( auditEvents [ 0 ] ?. detail . issuer , 'https://sakai.example' ) ;
218+ assertEquals ( auditEvents [ 0 ] ?. detail . clientId , 'sakai-client-123' ) ;
219+ assertEquals ( auditEvents [ 0 ] ?. detail . deploymentId , 'sakai-deployment-123' ) ;
220+ assertEquals ( auditEvents [ 0 ] ?. detail . resourceLinkId , 'sakai-resource-link' ) ;
221+ assertEquals ( auditEvents [ 0 ] ?. detail . contextId , 'sakai-course-42' ) ;
222+ } ,
223+ ) ;
224+ } ) ;
221225} ) ;
0 commit comments