@@ -87,7 +87,7 @@ describe('PATCH', () => {
8787 } )
8888
8989 describe ( 'appending' , ( ) => {
90- describe ( 'to a resource with read-only access' , ( ) => {
90+ describe ( 'on a resource with read-only access' , ( ) => {
9191 it ( 'returns a 403' , ( ) =>
9292 request . patch ( '/read-only.ttl' )
9393 . set ( 'Authorization' , `Bearer ${ userCredentials } ` )
@@ -108,7 +108,7 @@ describe('PATCH', () => {
108108 } )
109109 } )
110110
111- describe ( 'to a non-existing file' , ( ) => {
111+ describe ( 'on a non-existing file' , ( ) => {
112112 after ( ( ) => rm ( 'patch/new.ttl' ) )
113113
114114 it ( 'returns a 200' , ( ) =>
@@ -131,7 +131,7 @@ describe('PATCH', () => {
131131 } )
132132 } )
133133
134- describe ( 'to a resource with append access' , ( ) => {
134+ describe ( 'on a resource with append access' , ( ) => {
135135 before ( ( ) => backup ( 'patch/append-only.ttl' ) )
136136 after ( ( ) => restore ( 'patch/append-only.ttl' ) )
137137
@@ -155,7 +155,7 @@ describe('PATCH', () => {
155155 } )
156156 } )
157157
158- describe ( 'to a resource with write access' , ( ) => {
158+ describe ( 'on a resource with write access' , ( ) => {
159159 before ( ( ) => backup ( 'patch/write-only.ttl' ) )
160160 after ( ( ) => restore ( 'patch/write-only.ttl' ) )
161161
@@ -181,7 +181,7 @@ describe('PATCH', () => {
181181 } )
182182
183183 describe ( 'deleting' , ( ) => {
184- describe ( 'from a resource with read-only access' , ( ) => {
184+ describe ( 'on a resource with read-only access' , ( ) => {
185185 it ( 'returns a 403' , ( ) =>
186186 request . patch ( '/read-only.ttl' )
187187 . set ( 'Authorization' , `Bearer ${ userCredentials } ` )
@@ -202,7 +202,7 @@ describe('PATCH', () => {
202202 } )
203203 } )
204204
205- describe ( 'from a non-existing file' , ( ) => {
205+ describe ( 'on a non-existing file' , ( ) => {
206206 after ( ( ) => rm ( 'patch/new.ttl' ) )
207207
208208 it ( 'returns a 409' , ( ) =>
@@ -224,7 +224,7 @@ describe('PATCH', () => {
224224 } )
225225 } )
226226
227- describe . skip ( 'from a resource with append-only access' , ( ) => {
227+ describe . skip ( 'on a resource with append-only access' , ( ) => {
228228 before ( ( ) => backup ( 'patch/append-only.ttl' ) )
229229 after ( ( ) => restore ( 'patch/append-only.ttl' ) )
230230
@@ -248,7 +248,7 @@ describe('PATCH', () => {
248248 } )
249249 } )
250250
251- describe . skip ( 'from a resource with write-only access' , ( ) => {
251+ describe . skip ( 'on a resource with write-only access' , ( ) => {
252252 before ( ( ) => backup ( 'patch/write-only.ttl' ) )
253253 after ( ( ) => restore ( 'patch/write-only.ttl' ) )
254254
@@ -275,7 +275,7 @@ describe('PATCH', () => {
275275 } )
276276 } )
277277
278- describe ( 'from a resource with read-write access' , ( ) => {
278+ describe ( 'on a resource with read-write access' , ( ) => {
279279 describe ( 'with a patch for existing data' , ( ) => {
280280 before ( ( ) => backup ( 'patch/read-write.ttl' ) )
281281 after ( ( ) => restore ( 'patch/read-write.ttl' ) )
@@ -325,6 +325,173 @@ describe('PATCH', () => {
325325 } )
326326 } )
327327 } )
328+
329+ describe ( 'deleting and inserting' , ( ) => {
330+ describe ( 'on a resource with read-only access' , ( ) => {
331+ it ( 'returns a 403' , ( ) =>
332+ request . patch ( '/read-only.ttl' )
333+ . set ( 'Authorization' , `Bearer ${ userCredentials } ` )
334+ . set ( 'Content-Type' , 'text/n3' )
335+ . send ( n3Patch ( `
336+ <> p:patches <https://tim.localhost:7777/read-only.ttl>;
337+ p:insert { <x> <y> <z>. };
338+ p:delete { <a> <b> <c>. }.`
339+ ) )
340+ . expect ( 403 )
341+ . then ( response => {
342+ assert . include ( response . text , 'Access denied' )
343+ } )
344+ )
345+
346+ it ( 'does not modify the file' , ( ) => {
347+ assert . equal ( read ( 'patch/read-only.ttl' ) ,
348+ '<a> <b> <c>.\n<d> <e> <f>.\n' )
349+ } )
350+ } )
351+
352+ describe ( 'on a non-existing file' , ( ) => {
353+ after ( ( ) => rm ( 'patch/new.ttl' ) )
354+
355+ it ( 'returns a 409' , ( ) =>
356+ request . patch ( '/new.ttl' )
357+ . set ( 'Authorization' , `Bearer ${ userCredentials } ` )
358+ . set ( 'Content-Type' , 'text/n3' )
359+ . send ( n3Patch ( `
360+ <> p:patches <https://tim.localhost:7777/new.ttl>;
361+ p:insert { <x> <y> <z>. };
362+ p:delete { <a> <b> <c>. }.`
363+ ) )
364+ . expect ( 409 )
365+ . then ( response => {
366+ assert . include ( response . text , 'The patch could not be applied' )
367+ } )
368+ )
369+
370+ it ( 'does not create the file' , ( ) => {
371+ assert . isFalse ( fs . existsSync ( 'patch/new.ttl' ) )
372+ } )
373+ } )
374+
375+ describe . skip ( 'on a resource with append-only access' , ( ) => {
376+ before ( ( ) => backup ( 'patch/append-only.ttl' ) )
377+ after ( ( ) => restore ( 'patch/append-only.ttl' ) )
378+
379+ it ( 'returns a 403' , ( ) =>
380+ request . patch ( '/append-only.ttl' )
381+ . set ( 'Authorization' , `Bearer ${ userCredentials } ` )
382+ . set ( 'Content-Type' , 'text/n3' )
383+ . send ( n3Patch ( `
384+ <> p:patches <https://tim.localhost:7777/append-only.ttl>;
385+ p:insert { <x> <y> <z>. };
386+ p:delete { <a> <b> <c>. }.`
387+ ) )
388+ . expect ( 403 )
389+ . then ( response => {
390+ assert . include ( response . text , 'Access denied' )
391+ } )
392+ )
393+
394+ it ( 'does not modify the file' , ( ) => {
395+ assert . equal ( read ( 'patch/append-only.ttl' ) ,
396+ '<a> <b> <c>.\n<d> <e> <f>.\n' )
397+ } )
398+ } )
399+
400+ describe . skip ( 'on a resource with write-only access' , ( ) => {
401+ before ( ( ) => backup ( 'patch/write-only.ttl' ) )
402+ after ( ( ) => restore ( 'patch/write-only.ttl' ) )
403+
404+ // Allowing the delete would either return 200 or 409,
405+ // thereby incorrectly giving the user (guess-based) read access;
406+ // therefore, we need to return 403.
407+ it ( 'returns a 403' , ( ) =>
408+ request . patch ( '/write-only.ttl' )
409+ . set ( 'Authorization' , `Bearer ${ userCredentials } ` )
410+ . set ( 'Content-Type' , 'text/n3' )
411+ . send ( n3Patch ( `
412+ <> p:patches <https://tim.localhost:7777/write-only.ttl>;
413+ p:insert { <x> <y> <z>. };
414+ p:delete { <a> <b> <c>. }.`
415+ ) )
416+ . expect ( 403 )
417+ . then ( response => {
418+ assert . include ( response . text , 'Access denied' )
419+ } )
420+ )
421+
422+ it ( 'does not modify the file' , ( ) => {
423+ assert . equal ( read ( 'patch/append-only.ttl' ) ,
424+ '<a> <b> <c>.\n<d> <e> <f>.\n' )
425+ } )
426+ } )
427+
428+ describe ( 'on a resource with read-write access' , ( ) => {
429+ describe ( 'with a patch for existing data' , ( ) => {
430+ before ( ( ) => backup ( 'patch/read-write.ttl' ) )
431+ after ( ( ) => restore ( 'patch/read-write.ttl' ) )
432+
433+ it ( 'returns a 200' , ( ) =>
434+ request . patch ( '/read-write.ttl' )
435+ . set ( 'Authorization' , `Bearer ${ userCredentials } ` )
436+ . set ( 'Content-Type' , 'text/n3' )
437+ . send ( n3Patch ( `
438+ <> p:patches <https://tim.localhost:7777/read-write.ttl>;
439+ p:insert { <x> <y> <z>. };
440+ p:delete { <a> <b> <c>. }.`
441+ ) )
442+ . expect ( 200 )
443+ . then ( response => {
444+ assert . include ( response . text , 'Patch applied successfully' )
445+ } )
446+ )
447+
448+ it ( 'patches the file' , ( ) => {
449+ assert . equal ( read ( 'patch/read-write.ttl' ) ,
450+ '@prefix : </read-write.ttl#>.\n@prefix tim: </>.\n\ntim:d tim:e tim:f.\n\ntim:x tim:y tim:z.\n\n' )
451+ } )
452+ } )
453+
454+ describe ( 'with a patch for non-existing data' , ( ) => {
455+ before ( ( ) => backup ( 'patch/read-write.ttl' ) )
456+ after ( ( ) => restore ( 'patch/read-write.ttl' ) )
457+
458+ it ( 'returns a 409' , ( ) =>
459+ request . patch ( '/read-write.ttl' )
460+ . set ( 'Authorization' , `Bearer ${ userCredentials } ` )
461+ . set ( 'Content-Type' , 'text/n3' )
462+ . send ( n3Patch ( `
463+ <> p:patches <https://tim.localhost:7777/read-write.ttl>;
464+ p:insert { <x> <y> <z>. };
465+ p:delete { <q> <s> <s>. }.`
466+ ) )
467+ . expect ( 409 )
468+ . then ( response => {
469+ assert . include ( response . text , 'The patch could not be applied' )
470+ } )
471+ )
472+
473+ it ( 'does not change the file' , ( ) => {
474+ assert . equal ( read ( 'patch/read-write.ttl' ) ,
475+ '<a> <b> <c>.\n<d> <e> <f>.\n' )
476+ } )
477+ } )
478+
479+ it ( 'executes deletes before inserts' , ( ) =>
480+ request . patch ( '/read-write.ttl' )
481+ . set ( 'Authorization' , `Bearer ${ userCredentials } ` )
482+ . set ( 'Content-Type' , 'text/n3' )
483+ . send ( n3Patch ( `
484+ <> p:patches <https://tim.localhost:7777/read-write.ttl>;
485+ p:insert { <x> <y> <z>. };
486+ p:delete { <x> <y> <z>. }.`
487+ ) )
488+ . expect ( 409 )
489+ . then ( response => {
490+ assert . include ( response . text , 'The patch could not be applied' )
491+ } )
492+ )
493+ } )
494+ } )
328495} )
329496
330497function n3Patch ( contents ) {
0 commit comments