Skip to content

Commit cef5a5f

Browse files
committed
First part of schemas PUT
1 parent 6db40f0 commit cef5a5f

File tree

2 files changed

+148
-20
lines changed

2 files changed

+148
-20
lines changed

spec/schemas.spec.js

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ describe('schemas', () => {
9494
headers: restKeyHeaders,
9595
}, (error, response, body) => {
9696
expect(response.statusCode).toEqual(401);
97-
expect(body.error).toEqual('unauthorized');
97+
expect(body.error).toEqual('master key not specified');
9898
done();
9999
});
100100
});
@@ -318,4 +318,101 @@ describe('schemas', () => {
318318
done();
319319
});
320320
});
321+
322+
it('requires the master key to modify schemas', done => {
323+
request.post({
324+
url: 'http://localhost:8378/1/schemas/NewClass',
325+
headers: masterKeyHeaders,
326+
json: true,
327+
body: {},
328+
}, (error, response, body) => {
329+
request.put({
330+
url: 'http://localhost:8378/1/schemas/NewClass',
331+
headers: noAuthHeaders,
332+
json: true,
333+
body: {},
334+
}, (error, response, body) => {
335+
expect(response.statusCode).toEqual(403);
336+
expect(body.error).toEqual('unauthorized');
337+
done();
338+
});
339+
});
340+
});
341+
342+
it('rejects class name mis-matches', done => {
343+
request.put({
344+
url: 'http://localhost:8378/1/schemas/NewClass',
345+
headers: masterKeyHeaders,
346+
json: true,
347+
body: {className: 'WrongClassName'}
348+
}, (error, response, body) => {
349+
expect(response.statusCode).toEqual(400);
350+
expect(body.code).toEqual(Parse.Error.INVALID_CLASS_NAME);
351+
expect(body.error).toEqual('class name mismatch between WrongClassName and NewClass');
352+
});
353+
});
354+
355+
it('refuses to add fields to non-existent classes', done => {
356+
request.put({
357+
url: 'http://localhost:8378/1/schemas/NoClass',
358+
headers: masterKeyHeaders,
359+
json: true,
360+
body: {
361+
fields: {
362+
newField: {type: 'String'}
363+
}
364+
}
365+
}, (error, response, body) => {
366+
expect(response.statusCode).toEqual(400);
367+
expect(body.code).toEqual(Parse.Error.INVALID_CLASS_NAME);
368+
expect(body.error).toEqual('class NoClass does not exist');
369+
done();
370+
});
371+
});
372+
373+
it('put with no modifications returns all fields', done => {
374+
var obj = hasAllPODobject();
375+
obj.save()
376+
.then(() => {
377+
request.put({
378+
url: 'http://localhost:8378/1/schemas/HasAllPOD'
379+
headers: masterKeyHeaders,
380+
json: true,
381+
body: {},
382+
}, (error, response, body) => {
383+
expect(body).toEqual(plainOldDataSchema);
384+
done();
385+
});
386+
});
387+
});
388+
389+
it('lets you add fields', done => {
390+
request.post({
391+
url: 'http://localhost:8378/1/schemas/NewClass',
392+
headers: masterKeyHeaders,
393+
json: true,
394+
body: {},
395+
}, (error, response, body) => {
396+
request.put({
397+
url: 'http://localhost:8378/1/schemas/NewClass',
398+
headers: masterKeyHeaders,
399+
json: true,
400+
body: {
401+
fields: {
402+
newField: {type: 'String'}
403+
}
404+
}
405+
}, (error, response, body) => {
406+
expect(body).toEqual('blah');
407+
request.get({
408+
url: 'http://localhost:8378/1/schemas/NewClass',
409+
headers: masterKeyHeaders,
410+
json: true,
411+
}, (error, response, body) => {
412+
expect(body).toEqual('blah');
413+
done();
414+
});
415+
});
416+
})
417+
});
321418
});

src/schemas.js

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ var express = require('express'),
77

88
var router = new PromiseRouter();
99

10+
function masterKeyRequiredResponse() {
11+
return Promise.resolve({
12+
status: 401,
13+
response: {error: 'master key not specified'},
14+
})
15+
}
16+
17+
function classNameMismatchResponse(bodyClass, pathClass) {
18+
return Promise.resolve({
19+
status: 400,
20+
response: {
21+
code: Parse.Error.INVALID_CLASS_NAME,
22+
error: 'class name mismatch between ' + bodyClass + ' and ' + pathClass,
23+
}
24+
});
25+
}
26+
1027
function mongoFieldTypeToSchemaAPIType(type) {
1128
if (type[0] === '*') {
1229
return {
@@ -55,10 +72,7 @@ function mongoSchemaToSchemaAPIResponse(schema) {
5572

5673
function getAllSchemas(req) {
5774
if (!req.auth.isMaster) {
58-
return Promise.resolve({
59-
status: 401,
60-
response: {error: 'master key not specified'},
61-
});
75+
return masterKeyRequiredResponse();
6276
}
6377
return req.config.database.collection('_SCHEMA')
6478
.then(coll => coll.find({}).toArray())
@@ -69,10 +83,7 @@ function getAllSchemas(req) {
6983

7084
function getOneSchema(req) {
7185
if (!req.auth.isMaster) {
72-
return Promise.resolve({
73-
status: 401,
74-
response: {error: 'unauthorized'},
75-
});
86+
return masterKeyRequiredResponse();
7687
}
7788
return req.config.database.collection('_SCHEMA')
7889
.then(coll => coll.findOne({'_id': req.params.className}))
@@ -88,20 +99,11 @@ function getOneSchema(req) {
8899

89100
function createSchema(req) {
90101
if (!req.auth.isMaster) {
91-
return Promise.resolve({
92-
status: 401,
93-
response: {error: 'master key not specified'},
94-
});
102+
return masterKeyRequiredResponse();
95103
}
96104
if (req.params.className && req.body.className) {
97105
if (req.params.className != req.body.className) {
98-
return Promise.resolve({
99-
status: 400,
100-
response: {
101-
code: Parse.Error.INVALID_CLASS_NAME,
102-
error: 'class name mismatch between ' + req.body.className + ' and ' + req.params.className,
103-
},
104-
});
106+
return classNameMismatchResponse(req.body.className, req.params.className);
105107
}
106108
}
107109
var className = req.params.className || req.body.className;
@@ -123,9 +125,38 @@ function createSchema(req) {
123125
}));
124126
}
125127

128+
function modifySchema(req) {
129+
if (!req.auth.isMaster) {
130+
return masterKeyRequiredResponse();
131+
}
132+
133+
if (req.body.className && req.body.className != req.params.className) {
134+
return classNameMismatchResponse(req.body.className, req.path.className);
135+
}
136+
137+
if (!req.body.fields) {
138+
req.body.fields = {};
139+
}
140+
141+
return req.config.database.loadSchema()
142+
.then(schema => schema.hasClass(req.params.className))
143+
.then(hasClass => {
144+
if (!hasClass) {
145+
return Promise.resolve({
146+
status: 400,
147+
response: {
148+
code: Parse.Error.INVALID_CLASS_NAME,
149+
error: 'class ' + req.params.className + ' does not exist',
150+
}
151+
});
152+
}
153+
});
154+
}
155+
126156
router.route('GET', '/schemas', getAllSchemas);
127157
router.route('GET', '/schemas/:className', getOneSchema);
128158
router.route('POST', '/schemas', createSchema);
129159
router.route('POST', '/schemas/:className', createSchema);
160+
router.route('PUT', '/schemas/:className', modifySchema);
130161

131162
module.exports = router;

0 commit comments

Comments
 (0)