@@ -198,6 +198,73 @@ describe('Content Negotiation (conneg enabled)', () => {
198198 } ) ;
199199 } ) ;
200200
201+ // Regression coverage for #294 — Solid convention dotfiles (.acl, .meta)
202+ // were excluded from conneg because getContentType() returned
203+ // application/octet-stream for them. Turtle-native clients (umai etc.)
204+ // fetching <container>/.meta got JSON-LD back and errored on parse.
205+ describe ( 'Solid convention dotfiles (#294)' , ( ) => {
206+ const metaData = {
207+ '@context' : { 'ldp' : 'http://www.w3.org/ns/ldp#' } ,
208+ '@id' : '' ,
209+ '@type' : 'ldp:BasicContainer'
210+ } ;
211+
212+ before ( async ( ) => {
213+ // Write a JSON-LD .meta file (the format JSS writes internally).
214+ await request ( '/connegtest/public/.meta' , {
215+ method : 'PUT' ,
216+ headers : { 'Content-Type' : 'application/ld+json' } ,
217+ body : JSON . stringify ( metaData ) ,
218+ auth : 'connegtest'
219+ } ) ;
220+ } ) ;
221+
222+ it ( 'serves .meta as JSON-LD by default' , async ( ) => {
223+ const res = await request ( '/connegtest/public/.meta' , { auth : 'connegtest' } ) ;
224+ assertStatus ( res , 200 ) ;
225+ assertHeaderContains ( res , 'Content-Type' , 'application/ld+json' ) ;
226+ } ) ;
227+
228+ it ( 'serves .meta as Turtle when Accept: text/turtle (the umai case)' , async ( ) => {
229+ const res = await request ( '/connegtest/public/.meta' , {
230+ headers : { 'Accept' : 'text/turtle' } ,
231+ auth : 'connegtest'
232+ } ) ;
233+ assertStatus ( res , 200 ) ;
234+ assertHeaderContains ( res , 'Content-Type' , 'text/turtle' ) ;
235+ const turtle = await res . text ( ) ;
236+ // First byte after the `@prefix` block must parse as Turtle,
237+ // not '{' (the bug signature umai hit).
238+ assert . ok ( ! turtle . trimStart ( ) . startsWith ( '{' ) ,
239+ `response looks like JSON, not Turtle: ${ turtle . slice ( 0 , 60 ) } ` ) ;
240+ } ) ;
241+
242+ it ( 'accepts Turtle PUT to .meta and round-trips to JSON-LD' , async ( ) => {
243+ const turtle = `
244+ @prefix ldp: <http://www.w3.org/ns/ldp#>.
245+ <> a ldp:BasicContainer.
246+ ` ;
247+ const putRes = await request ( '/connegtest/public/.meta' , {
248+ method : 'PUT' ,
249+ headers : { 'Content-Type' : 'text/turtle' } ,
250+ body : turtle ,
251+ auth : 'connegtest'
252+ } ) ;
253+ assert . ok ( putRes . status < 300 , `PUT turtle should succeed, got ${ putRes . status } ` ) ;
254+
255+ // Default GET now serves the converted-and-stored JSON-LD.
256+ const getRes = await request ( '/connegtest/public/.meta' , {
257+ headers : { 'Accept' : 'application/ld+json' } ,
258+ auth : 'connegtest'
259+ } ) ;
260+ assertStatus ( getRes , 200 ) ;
261+ assertHeaderContains ( getRes , 'Content-Type' , 'application/ld+json' ) ;
262+ const body = await getRes . json ( ) ;
263+ assert . ok ( body [ '@context' ] || body [ '@graph' ] || body [ '@type' ] || body [ '@id' ] ,
264+ 'round-tripped JSON-LD should have at least one @-keyword' ) ;
265+ } ) ;
266+ } ) ;
267+
201268 describe ( 'ACL conneg (#327 regression)' , ( ) => {
202269 before ( async ( ) => {
203270 const baseUrl = getBaseUrl ( ) ;
@@ -297,70 +364,6 @@ describe('Content Negotiation (conneg enabled)', () => {
297364 node [ '@type' ] ?. includes ( 'Authorization' ) ||
298365 node [ '@type' ] === 'acl:Authorization'
299366 ) , 'Should have Authorization nodes' ) ;
300- // Regression coverage for #294 — Solid convention dotfiles (.acl, .meta)
301- // were excluded from conneg because getContentType() returned
302- // application/octet-stream for them. Turtle-native clients (umai etc.)
303- // fetching <container>/.meta got JSON-LD back and errored on parse.
304- describe ( 'Solid convention dotfiles (#294)' , ( ) => {
305- const metaData = {
306- '@context' : { 'ldp' : 'http://www.w3.org/ns/ldp#' } ,
307- '@id' : '' ,
308- '@type' : 'ldp:BasicContainer'
309- } ;
310-
311- before ( async ( ) => {
312- // Write a JSON-LD .meta file (the format JSS writes internally).
313- await request ( '/connegtest/public/.meta' , {
314- method : 'PUT' ,
315- headers : { 'Content-Type' : 'application/ld+json' } ,
316- body : JSON . stringify ( metaData ) ,
317- auth : 'connegtest'
318- } ) ;
319- } ) ;
320-
321- it ( 'serves .meta as JSON-LD by default' , async ( ) => {
322- const res = await request ( '/connegtest/public/.meta' , { auth : 'connegtest' } ) ;
323- assertStatus ( res , 200 ) ;
324- assertHeaderContains ( res , 'Content-Type' , 'application/ld+json' ) ;
325- } ) ;
326-
327- it ( 'serves .meta as Turtle when Accept: text/turtle (the umai case)' , async ( ) => {
328- const res = await request ( '/connegtest/public/.meta' , {
329- headers : { 'Accept' : 'text/turtle' } ,
330- auth : 'connegtest'
331- } ) ;
332- assertStatus ( res , 200 ) ;
333- assertHeaderContains ( res , 'Content-Type' , 'text/turtle' ) ;
334- const turtle = await res . text ( ) ;
335- // First byte after the `@prefix` block must parse as Turtle,
336- // not '{' (the bug signature umai hit).
337- assert . ok ( ! turtle . trimStart ( ) . startsWith ( '{' ) ,
338- `response looks like JSON, not Turtle: ${ turtle . slice ( 0 , 60 ) } ` ) ;
339- } ) ;
340-
341- it ( 'accepts Turtle PUT to .meta and round-trips to JSON-LD' , async ( ) => {
342- const turtle = `
343- @prefix ldp: <http://www.w3.org/ns/ldp#>.
344- <> a ldp:BasicContainer.
345- ` ;
346- const putRes = await request ( '/connegtest/public/.meta' , {
347- method : 'PUT' ,
348- headers : { 'Content-Type' : 'text/turtle' } ,
349- body : turtle ,
350- auth : 'connegtest'
351- } ) ;
352- assert . ok ( putRes . status < 300 , `PUT turtle should succeed, got ${ putRes . status } ` ) ;
353-
354- // Default GET now serves the converted-and-stored JSON-LD.
355- const getRes = await request ( '/connegtest/public/.meta' , {
356- headers : { 'Accept' : 'application/ld+json' } ,
357- auth : 'connegtest'
358- } ) ;
359- assertStatus ( getRes , 200 ) ;
360- assertHeaderContains ( getRes , 'Content-Type' , 'application/ld+json' ) ;
361- const body = await getRes . json ( ) ;
362- assert . ok ( body [ '@context' ] || body [ '@graph' ] || body [ '@type' ] || body [ '@id' ] ,
363- 'round-tripped JSON-LD should have at least one @-keyword' ) ;
364367 } ) ;
365368 } ) ;
366369} ) ;
@@ -548,3 +551,4 @@ describe('Content Negotiation — q-weights and HEAD/GET parity (#325)', () => {
548551 } ) ;
549552 } ) ;
550553} ) ;
554+
0 commit comments