Skip to content

Commit 351463d

Browse files
committed
Enable and test PATCH appending.
1 parent f04b5ef commit 351463d

File tree

9 files changed

+132
-20
lines changed

9 files changed

+132
-20
lines changed

lib/handlers/patch.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ function writeGraph (graph, resource) {
105105
if (err) {
106106
return reject(error(500, 'Failed to write file back after patch: ' + err))
107107
}
108-
debug('PATCH -- applied OK (sync)')
109-
resolve('Patch applied OK\n')
108+
debug('PATCH -- applied successfully')
109+
resolve('Patch applied successfully.\n')
110110
})
111111
})
112112
}

lib/ldp-middleware.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function LdpMiddleware (corsSettings) {
2424
router.copy('/*', acl.allow('Write'), copy)
2525
router.get('/*', index, acl.allow('Read'), get)
2626
router.post('/*', acl.allow('Append'), post)
27-
router.patch('/*', acl.allow('Write'), patch)
27+
router.patch('/*', acl.allow('Append'), patch)
2828
router.put('/*', acl.allow('Write'), put)
2929
router.delete('/*', acl.allow('Write'), del)
3030

test/integration/patch.js

Lines changed: 97 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
// Integration tests for PATCH with text/n3
2-
const assert = require('chai').assert
2+
const { assert } = require('chai')
33
const ldnode = require('../../index')
44
const path = require('path')
55
const supertest = require('supertest')
6+
const { read, rm, backup, restore } = require('../test-utils')
67

78
// Server settings
89
const port = 7777
910
const serverUri = `https://tim.localhost:${port}`
1011
const root = path.join(__dirname, '../resources/patch')
12+
const filePath = 'patch/tim.localhost'
1113
const serverOptions = {
1214
serverUri,
1315
root,
@@ -28,22 +30,6 @@ describe('PATCH', () => {
2830
request = supertest(serverUri)
2931
})
3032

31-
describe('on a resource to which the user has read-only access', () => {
32-
it('returns a 403', () =>
33-
request.patch(`/read-only.ttl`)
34-
.set('Authorization', `Bearer ${userCredentials}`)
35-
.set('Content-Type', 'text/n3')
36-
.send(n3Patch(`
37-
<> a p:Patch;
38-
p:insert { <a> <b> <c>. }.`
39-
))
40-
.expect(403)
41-
.then(response => {
42-
assert.include(response.text, 'Access denied')
43-
})
44-
)
45-
})
46-
4733
describe('with an unsupported request content type', () => {
4834
it('returns a 415', () =>
4935
request.patch(`/read-write.ttl`)
@@ -99,6 +85,100 @@ describe('PATCH', () => {
9985
})
10086
)
10187
})
88+
89+
describe('appending', () => {
90+
describe('to a resource with read-only access', () => {
91+
it('returns a 403', () =>
92+
request.patch(`/read-only.ttl`)
93+
.set('Authorization', `Bearer ${userCredentials}`)
94+
.set('Content-Type', 'text/n3')
95+
.send(n3Patch(`
96+
<> p:patches <https://tim.localhost:7777/read-only.ttl>;
97+
p:insert { <d> <e> <f>. }.`
98+
))
99+
.expect(403)
100+
.then(response => {
101+
assert.include(response.text, 'Access denied')
102+
})
103+
)
104+
105+
it('does not modify the file', () => {
106+
assert.equal(read(`${filePath}/read-only.ttl`),
107+
'<a> <b> <c>.\n')
108+
})
109+
})
110+
111+
describe('to a non-existing file', () => {
112+
after(() => rm(`${filePath}/new.ttl`))
113+
114+
it('returns a 200', () =>
115+
request.patch(`/new.ttl`)
116+
.set('Authorization', `Bearer ${userCredentials}`)
117+
.set('Content-Type', 'text/n3')
118+
.send(n3Patch(`
119+
<> p:patches <https://tim.localhost:7777/new.ttl>;
120+
p:insert { <d> <e> <f>. }.`
121+
))
122+
.expect(200)
123+
.then(response => {
124+
assert.include(response.text, 'Patch applied successfully')
125+
})
126+
)
127+
128+
it('creates the file', () => {
129+
assert.equal(read(`${filePath}/new.ttl`),
130+
'@prefix : </new.ttl#>.\n@prefix tim: </>.\n\ntim:d tim:e tim:f.\n\n')
131+
})
132+
})
133+
134+
describe('to a resource with append access', () => {
135+
before(() => backup(`${filePath}/append-only.ttl`))
136+
after(() => restore(`${filePath}/append-only.ttl`))
137+
138+
it('returns a 200', () =>
139+
request.patch(`/append-only.ttl`)
140+
.set('Authorization', `Bearer ${userCredentials}`)
141+
.set('Content-Type', 'text/n3')
142+
.send(n3Patch(`
143+
<> p:patches <https://tim.localhost:7777/append-only.ttl>;
144+
p:insert { <d> <e> <f>. }.`
145+
))
146+
.expect(200)
147+
.then(response => {
148+
assert.include(response.text, 'Patch applied successfully')
149+
})
150+
)
151+
152+
it('patches the file', () => {
153+
assert.equal(read(`${filePath}/append-only.ttl`),
154+
'@prefix : </append-only.ttl#>.\n@prefix tim: </>.\n\ntim:a tim:b tim:c.\n\ntim:d tim:e tim:f.\n\n')
155+
})
156+
})
157+
158+
describe('to a resource with write access', () => {
159+
before(() => backup(`${filePath}/write-only.ttl`))
160+
after(() => restore(`${filePath}/write-only.ttl`))
161+
162+
it('returns a 200', () =>
163+
request.patch(`/write-only.ttl`)
164+
.set('Authorization', `Bearer ${userCredentials}`)
165+
.set('Content-Type', 'text/n3')
166+
.send(n3Patch(`
167+
<> p:patches <https://tim.localhost:7777/write-only.ttl>;
168+
p:insert { <d> <e> <f>. }.`
169+
))
170+
.expect(200)
171+
.then(response => {
172+
assert.include(response.text, 'Patch applied successfully')
173+
})
174+
)
175+
176+
it('patches the file', () => {
177+
assert.equal(read(`${filePath}/write-only.ttl`),
178+
'@prefix : </write-only.ttl#>.\n@prefix tim: </>.\n\ntim:a tim:b tim:c.\n\ntim:d tim:e tim:f.\n\n')
179+
})
180+
})
181+
})
102182
})
103183

104184
function n3Patch (contents) {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
2+
3+
<#Owner> a acl:Authorization;
4+
acl:accessTo </>;
5+
acl:defaultForNew </>;
6+
acl:agent <https://tim.localhost:7777/profile/card#me>;
7+
acl:mode acl:Read, acl:Write, acl:Control.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<a> <b> <c>.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
2+
3+
<#Owner> a acl:Authorization;
4+
acl:accessTo <./append-only.ttl>;
5+
acl:agent <https://tim.localhost:7777/profile/card#me>;
6+
acl:mode acl:Append.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<a> <b> <c>.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
2+
3+
<#Owner> a acl:Authorization;
4+
acl:accessTo <./write-only.ttl>;
5+
acl:agent <https://tim.localhost:7777/profile/card#me>;
6+
acl:mode acl:Write.

test/test-utils.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,14 @@ exports.read = function (file) {
2222
'encoding': 'utf8'
2323
})
2424
}
25+
26+
// Backs up the given file
27+
exports.backup = function (src) {
28+
exports.cp(src, src + '.bak')
29+
}
30+
31+
// Restores a backup of the given file
32+
exports.restore = function (src) {
33+
exports.cp(src + '.bak', src)
34+
exports.rm(src + '.bak')
35+
}

0 commit comments

Comments
 (0)