@@ -4363,6 +4363,120 @@ module(basename(__filename), function () {
43634363 } ) ;
43644364 } ) ;
43654365
4366+ module ( 'cross-realm file links' , function ( hooks ) {
4367+ // A card instantiated from the catalog (e.g. a blackjack game) keeps a
4368+ // linksTo(FileDef) reference to an image file that lives in the catalog
4369+ // realm. When the card is served from a different realm, loadLinks resolves
4370+ // that reference via the cross-realm fetch path. Regression for CS-11344:
4371+ // that path used to assume every cross-realm link target was a card and
4372+ // threw "instance ... is not a card document" on a file-meta target,
4373+ // surfacing as an HTTP 500.
4374+ const providerRealmURL = 'http://127.0.0.1:5531/test/' ;
4375+ const consumerRealmURL = 'http://127.0.0.1:5532/test/' ;
4376+ let consumerRequest : RealmRequest ;
4377+
4378+ setupPermissionedRealmsCached ( hooks , {
4379+ realms : [
4380+ {
4381+ realmURL : providerRealmURL ,
4382+ permissions : {
4383+ '*' : [ 'read' , 'write' , 'realm-owner' ] ,
4384+ '@node-test_realm:localhost' : [ 'read' , 'realm-owner' ] ,
4385+ } ,
4386+ fileSystem : {
4387+ 'instructions.md' : '# Cross-realm instructions' ,
4388+ } ,
4389+ } ,
4390+ {
4391+ realmURL : consumerRealmURL ,
4392+ permissions : {
4393+ '*' : [ 'read' , 'write' , 'realm-owner' ] ,
4394+ '@node-test_realm:localhost' : [ 'read' , 'realm-owner' ] ,
4395+ } ,
4396+ fileSystem : {
4397+ 'skill-card.gts' : `
4398+ import { CardDef, field, contains, linksTo } from "https://cardstack.com/base/card-api";
4399+ import StringField from "https://cardstack.com/base/string";
4400+ import { MarkdownDef } from "https://cardstack.com/base/markdown-file-def";
4401+
4402+ export class SkillCard extends CardDef {
4403+ @field cardTitle = contains(StringField);
4404+ @field instructionsSource = linksTo(MarkdownDef);
4405+ }
4406+ ` ,
4407+ 'skill.json' : {
4408+ data : {
4409+ attributes : {
4410+ cardTitle : 'Cross-realm skill' ,
4411+ } ,
4412+ relationships : {
4413+ instructionsSource : {
4414+ links : {
4415+ self : `${ providerRealmURL } instructions.md` ,
4416+ } ,
4417+ } ,
4418+ } ,
4419+ meta : {
4420+ adoptsFrom : {
4421+ module : rri ( './skill-card' ) ,
4422+ name : 'SkillCard' ,
4423+ } ,
4424+ } ,
4425+ } ,
4426+ } ,
4427+ } ,
4428+ } ,
4429+ ] ,
4430+ onRealmSetup ( { realms } ) {
4431+ let latestRealms = realms . slice ( - 2 ) ;
4432+ consumerRequest = withRealmPath (
4433+ supertest ( latestRealms [ 1 ] . realmHttpServer ) ,
4434+ new URL ( consumerRealmURL ) ,
4435+ ) ;
4436+ } ,
4437+ } ) ;
4438+
4439+ hooks . afterEach ( ( ) => {
4440+ resetCatalogRealms ( ) ;
4441+ } ) ;
4442+
4443+ test ( 'serves a card linking to a file in another realm' , async function ( assert ) {
4444+ let response = await consumerRequest
4445+ . get ( '/skill' )
4446+ . set ( 'Accept' , 'application/vnd.card+json' ) ;
4447+
4448+ assert . strictEqual (
4449+ response . status ,
4450+ 200 ,
4451+ `HTTP 200 status: ${ response . text } ` ,
4452+ ) ;
4453+
4454+ let doc = response . body as LooseSingleCardDocument ;
4455+ let relationship = doc . data . relationships
4456+ ?. instructionsSource as Relationship ;
4457+ assert . deepEqual (
4458+ relationship ?. data ,
4459+ {
4460+ type : 'file-meta' ,
4461+ id : `${ providerRealmURL } instructions.md` ,
4462+ } ,
4463+ 'cross-realm file relationship references the file-meta target' ,
4464+ ) ;
4465+
4466+ let included = doc . included ?? [ ] ;
4467+ let linkedFile = included . find (
4468+ ( resource ) => resource . id === `${ providerRealmURL } instructions.md` ,
4469+ ) ;
4470+ assert . ok ( linkedFile , 'includes the cross-realm file-meta resource' ) ;
4471+ assert . strictEqual (
4472+ linkedFile ?. type ,
4473+ 'file-meta' ,
4474+ 'cross-realm linked resource is a file-meta resource' ,
4475+ ) ;
4476+ assert . strictEqual ( linkedFile ?. attributes ?. name , 'instructions.md' ) ;
4477+ } ) ;
4478+ } ) ;
4479+
43664480 module ( 'Query-backed relationships runtime resolver' , function ( hooks ) {
43674481 const providerRealmURL = 'http://127.0.0.1:5521/test/' ;
43684482 const consumerRealmURL = 'http://127.0.0.1:5522/test/' ;
0 commit comments