UNPKG

11.3 kBJavaScriptView Raw
1process.env.NODE_TLS_REJECT_UNAUTHORIZED=0
2const Promise = require('bluebird');
3const oada = require('../build/index')
4const _ = require('lodash');
5var chai = require('chai');
6var chaiAsPromised = require("chai-as-promised");
7chai.use(chaiAsPromised);
8var expect = chai.expect;
9const {token, domain} = require('./config.js');
10const {tree, putResource, getConnections} = require('./utils.js');
11
12var connections;
13var resources = [];
14
15describe(`------------DELETE-----------------`, async function() {
16 before(`Create connection types`, async function() {
17 connections = await getConnections({
18 domain,
19 token
20 })
21 connections = Object.values(connections)
22 })
23
24 for (let i = 0; i < 4; i++) {
25 describe(`Testing connection ${i+1}`, async function() {
26
27 it(`Should error when neither 'url' nor 'path' are supplied`, async function() {
28 console.log(`Cache: ${connections[i].cache ? true : false}; Websocket: ${connections[i].websocket ? true : false}`)
29 await connections[i].resetCache()
30 await connections[i].delete({path:'/bookmarks/test', tree})
31 await putResource({'something': 'b'}, '/bookmarks/test')
32
33 return expect(
34 connections[i].delete({
35 type: 'application/json'
36 })
37 ).to.be.rejectedWith(Error, 'Either path or url must be specified.')
38 })
39
40 it(`Shouldn't error when the 'Content-Type' header can be derived from the 'type' key`, async function() {
41 await connections[i].resetCache()
42 await connections[i].delete({path:'/bookmarks/test', tree})
43 await putResource({'something': 'b'}, '/bookmarks/test')
44 var response = await connections[i].delete({
45 path: '/bookmarks/test',
46 type: 'application/json'
47 })
48 expect(response.status).to.equal(204)
49 })
50
51 it(`Shouldn't error when 'Content-Type' header is specified.`, async function() {
52 await connections[i].resetCache()
53 await connections[i].delete({path:'/bookmarks/test', tree})
54 await putResource({'something': 'b'}, '/bookmarks/test')
55 var response = await connections[i].delete({
56 path: '/bookmarks/test',
57 headers: {'content-type': 'application/json'}
58 })
59 expect(response.status).to.equal(204)
60 })
61
62 it(`Should error when _type cannot be derived from the above tested sources`, async function() {
63 await connections[i].resetCache()
64 await connections[i].delete({path:'/bookmarks/test', tree})
65 await putResource({'something': 'b'}, '/bookmarks/test')
66 return expect(
67 connections[i].delete({
68 path: '/bookmarks/test',
69 })
70 ).to.be.rejectedWith(Error, `content-type header must be specified.`)
71 })
72
73 it(`Should produce a 403 error when using a content-type header for which your token does not have access to read/write`, async function() {
74 this.timeout(4000);
75 await connections[i].resetCache()
76 await connections[i].delete({path:'/bookmarks/test', tree})
77 await putResource({'something': 'b'}, '/bookmarks/test')
78 return expect(
79 connections[i].delete({
80 path: '/bookmarks/test',
81 headers: {'content-type': 'application/vnd.oada.foobar.1+json'},
82 })
83 ).to.be.rejectedWith(Error, `Request failed with status code 403`)
84 })
85
86 it(`Should allow us to delete only a resource and leave the link alone`, async function() {
87 this.timeout(4000);
88 await connections[i].resetCache()
89 await connections[i].delete({path:'/bookmarks/test', tree})
90 var result = await putResource({'something': 'b'}, '/bookmarks/test')
91 var deleteResponse = await connections[i].delete({
92 path: result.resource.headers['content-location'],
93 headers: {'content-type': 'application/json'}
94 })
95 expect(deleteResponse.status).to.equal(204);
96 var response = await connections[i].get({
97 path: '/bookmarks/test'
98 })
99 expect(response.status).to.equal(200);
100 expect(response.data).to.include.keys(['_id', '_rev'])
101 expect(response.data).to.not.include.keys(['_meta', '_type', 'something'])
102 })
103
104 it(`Should allow us to delete only a link and leave the resource alone`, async function() {
105 this.timeout(4000);
106 await connections[i].resetCache()
107 await connections[i].delete({path:'/bookmarks/test', tree})
108 var result = await putResource({'something': 'b'}, '/bookmarks/test')
109 var deleteResponse = await connections[i].delete({
110 path: '/bookmarks/test',
111 headers: {'content-type': 'application/json'}
112 })
113 expect(deleteResponse.status).to.equal(204);
114 var response = await connections[i].get({
115 path: result.resource.headers['content-location'],
116 })
117 expect(response.status).to.equal(200);
118 })
119
120 it(`Should handle a two deletes in series`, async function() {
121 this.timeout(4000);
122 await connections[i].resetCache()
123 await connections[i].delete({path:'/bookmarks/test', tree})
124 var result = await putResource({'something': 'b'}, '/bookmarks/test')
125 var deleteOne = await connections[i].delete({
126 path: '/bookmarks/test',
127 headers: {'content-type': 'application/json'}
128 })
129 expect(deleteOne.status).to.equal(204)
130 var deleteTwo = await connections[i].delete({
131 path: '/bookmarks/test',
132 headers: {'content-type': 'application/json'}
133 })
134 expect(deleteTwo.status).to.equal(204)
135 })
136
137 it(`Should handle concurrent deletes, ultimately deleting the target endpoint as intended`, async function() {
138 this.timeout(4000);
139 await connections[i].resetCache()
140 await connections[i].delete({path:'/bookmarks/test', tree})
141 var result = await putResource({'something': 'b'}, '/bookmarks/test')
142 var deleteOne = connections[i].delete({
143 path: '/bookmarks/test',
144 headers: {'content-type': 'application/json'}
145 })
146 var deleteTwo = connections[i].delete({
147 path: '/bookmarks/test',
148 headers: {'content-type': 'application/json'}
149 })
150 var deleteThree = connections[i].delete({
151 path: '/bookmarks/test',
152 headers: {'content-type': 'application/json'}
153 })
154 await Promise.join(deleteOne, deleteTwo, deleteThree, async function(deleteOne, deleteTwo, deleteThree) {
155 expect(deleteOne.status).to.equal(204)
156 expect(deleteTwo.status).to.equal(204)
157 expect(deleteThree.status).to.equal(204)
158 return expect(connections[i].get({
159 path: '/bookmarks/test',
160 })).to.be.rejectedWith(Error, 'Request failed with status code 404');
161 })
162 })
163
164 it(`Should produce a 412 if the 'If-Match' precondition fails`, async function() {
165 this.timeout(4000);
166 await connections[i].resetCache();
167 await connections[i].delete({path:'/bookmarks/test', tree})
168 var result = await putResource({foo: 'bar'}, '/bookmarks/test');
169 return expect(connections[i].delete({
170 path: '/bookmarks/test',
171 headers: {
172 'If-Match': '2-foobar',
173 'content-type': 'application/json'
174 }
175 })).to.be.rejectedWith(Error, 'Request failed with status code 412')
176 })
177
178 it(`Should succeed in deleting a link if a valid 'If-Match' header which matches the current resource's _rev is supplied`, async function() {
179 var result = await putResource({something: 'else'}, '/bookmarks/test');
180 var response = await connections[i].delete({
181 path: '/bookmarks/test',
182 headers: {
183 'if-match': result.link.headers['x-oada-rev'],
184 'content-type': 'application/json'
185 }
186 })
187 expect(response.status).to.equal(204)
188 })
189
190 it(`Should succeed in deleting a resource if a valid 'If-Match' header which matches the current resource's _rev is supplied`, async function() {
191 var result = await putResource({foo: 'bar'}, '/bookmarks/test');
192 var response = await connections[i].delete({
193 path: result.resource.headers['content-location'],
194 headers: {
195 'if-match': result.resource.headers['x-oada-rev'],
196 'content-type': 'application/json'
197 }
198 })
199 expect(response.status).to.equal(204)
200 })
201
202 it(`Should delete an entire tree of links and resources when the 'tree' option is supplied`, async function() {
203 var test = await putResource({foo: 'bar'}, '/bookmarks/test');
204 var aaa = await putResource({foo: 'bar'}, '/bookmarks/test/aaa');
205 var bbb = await putResource({foo: 'bar'}, '/bookmarks/test/aaa/bbb');
206 var ccc = await putResource({foo: 'bar'}, '/bookmarks/test/aaa/bbb/index-one/ccc');
207 var response = await connections[i].delete({
208 path: '/bookmarks/test',
209 tree
210 })
211 expect(response.status).to.equal(204)
212 return Promise.each([
213 test.resource.headers['content-location'],
214 aaa.link.headers['content-location'],
215 aaa.resource.headers['content-location'],
216 bbb.link.headers['content-location'],
217 bbb.resource.headers['content-location'],
218 ccc.link.headers['content-location'],
219 ccc.resource.headers['content-location'],
220 ], (path) => {
221 if (/^\/resources/.test(path)) {
222 return expect(connections[i].get({path})).to.be.rejectedWith(Error, 'Request failed with status code 403');
223 } else {
224 return expect(connections[i].get({path})).to.be.rejectedWith(Error, 'Request failedf with status code 404');
225 }
226 })
227 })
228
229 it(`Should gracefully handle a sequence of PUT, DELETE, PUT executed in series`, async function() {
230 var putOne = await connections[i].put({
231 path: '/bookmarks/test/aaa',
232 tree,
233 data: {putOne: 'putOne'}
234 })
235 expect(putOne.status).to.equal(204)
236
237 var putTwo = await connections[i].put({
238 path: '/bookmarks/test/aaa/bbb',
239 tree,
240 data: {putTwo: 'putTwo'}
241 })
242 expect(putTwo.status).to.equal(204)
243
244 var deleteOne = await connections[i].delete({
245 path: '/bookmarks/test',
246 tree,
247 })
248 expect(deleteOne.status).to.equal(204)
249
250 var putThree = await connections[i].put({
251 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
252 tree,
253 data: {putThree: 'putThree'}
254 })
255 expect(putThree.status).to.equal(204)
256
257 var getOne = await connections[i].get({
258 path: '/bookmarks/test',
259 tree
260 })
261 expect(getOne.status).to.equal(200)
262 expect(getOne.data.aaa).to.not.include.key('putOne')
263 expect(getOne.data.aaa.bbb).to.not.include.key('putTwo')
264 expect(getOne.data.aaa.bbb['index-one'].ccc).to.include.key('putThree')
265 })
266
267 it(`Should gracefully handle a concurrent sequence of PUT, DELETE, PUT`, async function() {
268 var putOne = connections[i].put({
269 path: '/bookmarks/test/aaa',
270 tree,
271 data: {putOne: 'putOne'}
272 })
273 var putTwo = connections[i].put({
274 path: '/bookmarks/test/aaa/bbb',
275 tree,
276 data: {putTwo: 'putTwo'}
277 })
278 var deleteOne = connections[i].delete({
279 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
280 tree,
281 })
282 var putThree = connections[i].put({
283 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
284 tree,
285 data: {putThree: 'putThree'}
286 })
287 var result = Promise.join(
288 putOne,
289 putTwo,
290 deleteOne,
291 putThree,
292 async function(putOne,putTwo,deleteOne,putThree) {
293 expect(putOne.status).to.equal(204)
294 expect(putTwo.status).to.equal(204)
295 expect(deleteOne.status).to.equal(204)
296 expect(putThree.status).to.equal(204)
297 }
298 )
299 })
300
301 it('Now clean up', async function() {
302 await connections[i].resetCache();
303 await connections[i].delete({path:'/bookmarks/test', tree})
304 })
305 })
306 }
307})