From 67ee94d98fc1ce20d13c6f60eda2e7a3212be9fc Mon Sep 17 00:00:00 2001 From: Drew Gross Date: Wed, 3 Feb 2016 16:10:00 -0800 Subject: [PATCH] Implement GET /schemas/OneSchema --- schemas.js | 20 +++++ spec/schemas.spec.js | 201 +++++++++++++++++++++++++++---------------- 2 files changed, 149 insertions(+), 72 deletions(-) diff --git a/schemas.js b/schemas.js index 88b0da38fe..62119a144e 100644 --- a/schemas.js +++ b/schemas.js @@ -64,6 +64,26 @@ function getAllSchemas(req) { }})); } +function getOneSchema(req) { + if (!req.auth.isMaster) { + return Promise.resolve({ + status: 401, + response: {error: 'unauthorized'}, + }); + } + return req.config.database.collection('_SCHEMA') + .then(coll => coll.findOne({'_id': req.params.className})) + .then(schema => ({response: mongoSchemaToSchemaAPIResponse(schema)})) + .catch(() => ({ + status: 400, + response: { + code: 103, + error: 'class ' + req.params.className + ' does not exist', + } + })); +} + router.route('GET', '/schemas', getAllSchemas); +router.route('GET', '/schemas/:className', getOneSchema); module.exports = router; diff --git a/spec/schemas.spec.js b/spec/schemas.spec.js index a4d2f6188c..8c7434da49 100644 --- a/spec/schemas.spec.js +++ b/spec/schemas.spec.js @@ -1,5 +1,60 @@ var request = require('request'); var dd = require('deep-diff'); +var hasAllPODobject = () => { + var obj = new Parse.Object('HasAllPOD'); + obj.set('aNumber', 5); + obj.set('aString', 'string'); + obj.set('aBool', true); + obj.set('aDate', new Date()); + obj.set('aObject', {k1: 'value', k2: true, k3: 5}); + obj.set('aArray', ['contents', true, 5]); + obj.set('aGeoPoint', new Parse.GeoPoint({latitude: 0, longitude: 0})); + obj.set('aFile', new Parse.File('f.txt', { base64: 'V29ya2luZyBhdCBQYXJzZSBpcyBncmVhdCE=' })); + var objACL = new Parse.ACL(); + objACL.setPublicWriteAccess(false); + obj.setACL(objACL); + return obj; +} + +var expectedResponseForHasAllPOD = { + className: 'HasAllPOD', + fields: { + //Default fields + ACL: {type: 'ACL'}, + createdAt: {type: 'Date'}, + updatedAt: {type: 'Date'}, + objectId: {type: 'String'}, + //Custom fields + aNumber: {type: 'Number'}, + aString: {type: 'String'}, + aBool: {type: 'Boolean'}, + aDate: {type: 'Date'}, + aObject: {type: 'Object'}, + aArray: {type: 'Array'}, + aGeoPoint: {type: 'GeoPoint'}, + aFile: {type: 'File'} + }, +}; + +var expectedResponseforHasPointersAndRelations = { + className: 'HasPointersAndRelations', + fields: { + //Default fields + ACL: {type: 'ACL'}, + createdAt: {type: 'Date'}, + updatedAt: {type: 'Date'}, + objectId: {type: 'String'}, + //Custom fields + aPointer: { + type: 'Pointer', + targetClass: 'HasAllPOD', + }, + aRelation: { + type: 'Relation', + targetClass: 'HasAllPOD', + }, + }, +} describe('schemas', () => { it('requires the master key to get all schemas', (done) => { @@ -17,6 +72,21 @@ describe('schemas', () => { }); }); + it('requires the master key to get one schema', (done) => { + request.get({ + url: 'http://localhost:8378/1/schemas/SomeSchema', + json: true, + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }, + }, (error, response, body) => { + expect(response.statusCode).toEqual(401); + expect(body.error).toEqual('unauthorized'); + done(); + }); + }); + it('responds with empty list when there are no schemas', done => { request.get({ url: 'http://localhost:8378/1/schemas', @@ -32,79 +102,66 @@ describe('schemas', () => { }); it('responds with a list of schemas after creating objects', done => { - var obj1 = new Parse.Object('HasAllPOD'); - obj1.set('aNumber', 5); - obj1.set('aString', 'string'); - obj1.set('aBool', true); - obj1.set('aDate', new Date()); - obj1.set('aObject', {k1: 'value', k2: true, k3: 5}); - obj1.set('aArray', ['contents', true, 5]); - obj1.set('aGeoPoint', new Parse.GeoPoint({latitude: 0, longitude: 0})); - obj1.set('aFile', new Parse.File('f.txt', { base64: 'V29ya2luZyBhdCBQYXJzZSBpcyBncmVhdCE=' })); - var obj1ACL = new Parse.ACL(); - obj1ACL.setPublicWriteAccess(false); - obj1.setACL(obj1ACL); + var obj1 = hasAllPODobject(); + obj1.save().then(savedObj1 => { + var obj2 = new Parse.Object('HasPointersAndRelations'); + obj2.set('aPointer', savedObj1); + var relation = obj2.relation('aRelation'); + relation.add(obj1); + return obj2.save(); + }).then(() => { + request.get({ + url: 'http://localhost:8378/1/schemas', + json: true, + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Master-Key': 'test', + }, + }, (error, response, body) => { + var expected = { + results: [expectedResponseForHasAllPOD,expectedResponseforHasPointersAndRelations] + }; + expect(body).toEqual(expected); + done(); + }) + }); + }); - obj1.save().then(savedObj1 => { - var obj2 = new Parse.Object('HasPointersAndRelations'); - obj2.set('aPointer', savedObj1); - var relation = obj2.relation('aRelation'); - relation.add(obj1); - return obj2.save(); - }).then(() => { - request.get({ - url: 'http://localhost:8378/1/schemas', - json: true, - headers: { - 'X-Parse-Application-Id': 'test', - 'X-Parse-Master-Key': 'test', - }, - }, (error, response, body) => { - var expected = { - results: [ - { - className: 'HasAllPOD', - fields: { - //Default fields - ACL: {type: 'ACL'}, - createdAt: {type: 'Date'}, - updatedAt: {type: 'Date'}, - objectId: {type: 'String'}, - //Custom fields - aNumber: {type: 'Number'}, - aString: {type: 'String'}, - aBool: {type: 'Boolean'}, - aDate: {type: 'Date'}, - aObject: {type: 'Object'}, - aArray: {type: 'Array'}, - aGeoPoint: {type: 'GeoPoint'}, - aFile: {type: 'File'} - }, - }, - { - className: 'HasPointersAndRelations', - fields: { - //Default fields - ACL: {type: 'ACL'}, - createdAt: {type: 'Date'}, - updatedAt: {type: 'Date'}, - objectId: {type: 'String'}, - //Custom fields - aPointer: { - type: 'Pointer', - targetClass: 'HasAllPOD', - }, - aRelation: { - type: 'Relation', - targetClass: 'HasAllPOD', - }, - }, - } - ] - }; - expect(body).toEqual(expected); - done(); - }) + it('responds with a single schema', done => { + var obj = hasAllPODobject(); + obj.save().then(() => { + request.get({ + url: 'http://localhost:8378/1/schemas/HasAllPOD', + json: true, + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Master-Key': 'test', + }, + }, (error, response, body) => { + expect(body).toEqual(expectedResponseForHasAllPOD); + done(); }); + }); + }); + + it('treats class names case sensitively', done => { + var obj = hasAllPODobject(); + obj.save().then(() => { + request.get({ + url: 'http://localhost:8378/1/schemas/HASALLPOD', + json: true, + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Master-Key': 'test', + }, + }, (error, response, body) => { + expect(response.statusCode).toEqual(400); + expect(body).toEqual({ + code: 103, + error: 'class HASALLPOD does not exist', + }); + done(); + }); + }); }); });