@@ -284,6 +284,44 @@ describe('みんなの課題 management (issue #1083)', () => {
284284 expect ( queue [ 0 ] . item . title ) . toBe ( 'ねこあつめ入門' ) ;
285285 } ) ;
286286
287+ test ( 'GET detail presigns page images and the starter project' , async ( ) => {
288+ mockSend . mockImplementation ( async ( command : {
289+ constructor : { name : string } ; input ?: { TableName ?: string } ;
290+ } ) => {
291+ const name = command . constructor . name ;
292+ if ( name === 'GetCommand' && command . input ?. TableName ?. includes ( 'Admins' ) ) return adminRow ;
293+ if ( name === 'GetCommand' ) return { Item : sharedItem } ;
294+ return { } ;
295+ } ) ;
296+
297+ const res = await handler ( {
298+ requestContext : { http : { method : 'GET' , path : '/admin/shared-assignments/s1' } } ,
299+ pathParameters : { sharedId : 's1' } ,
300+ headers : { authorization : `Bearer ${ DEV_TOKEN } ` , origin : 'https://smalruby.app' } ,
301+ } ) ;
302+ expect ( res . statusCode ) . toBe ( 200 ) ;
303+ const body = JSON . parse ( res . body as string ) ;
304+ expect ( body . pages [ 0 ] . imageUrl ) . toBe ( 'https://signed.example/get' ) ;
305+ // The starter is moderated content too — the operator gets a download URL.
306+ expect ( body . starterUrl ) . toBe ( 'https://signed.example/get' ) ;
307+
308+ // Without a starterKey the field is null, not a broken link.
309+ mockSend . mockImplementation ( async ( command : {
310+ constructor : { name : string } ; input ?: { TableName ?: string } ;
311+ } ) => {
312+ const name = command . constructor . name ;
313+ if ( name === 'GetCommand' && command . input ?. TableName ?. includes ( 'Admins' ) ) return adminRow ;
314+ if ( name === 'GetCommand' ) return { Item : { ...sharedItem , content : { pages : [ ] } } } ;
315+ return { } ;
316+ } ) ;
317+ const bare = await handler ( {
318+ requestContext : { http : { method : 'GET' , path : '/admin/shared-assignments/s1' } } ,
319+ pathParameters : { sharedId : 's1' } ,
320+ headers : { authorization : `Bearer ${ DEV_TOKEN } ` , origin : 'https://smalruby.app' } ,
321+ } ) ;
322+ expect ( JSON . parse ( bare . body as string ) . starterUrl ) . toBeNull ( ) ;
323+ } ) ;
324+
287325 test ( 'PATCH flips the status and audits the action' , async ( ) => {
288326 const logs : string [ ] = [ ] ;
289327 const spy = jest . spyOn ( console , 'log' ) . mockImplementation ( ( line : string ) => {
0 commit comments