From 039d9874dc91190266fd38c2763c6b7443b09ef1 Mon Sep 17 00:00:00 2001
From: Diamond Lewis
Date: Tue, 10 Oct 2017 07:55:39 -0500
Subject: [PATCH 1/7] Support for Parse Schema
---
integration/test/ParseSchemaTest.js | 247 ++++++++++++++++++++++++++
src/CoreManager.js | 17 ++
src/Parse.js | 1 +
src/ParseSchema.js | 259 ++++++++++++++++++++++++++++
4 files changed, 524 insertions(+)
create mode 100644 integration/test/ParseSchemaTest.js
create mode 100644 src/ParseSchema.js
diff --git a/integration/test/ParseSchemaTest.js b/integration/test/ParseSchemaTest.js
new file mode 100644
index 000000000..79bcf9a5e
--- /dev/null
+++ b/integration/test/ParseSchemaTest.js
@@ -0,0 +1,247 @@
+const assert = require('assert');
+const clear = require('./clear');
+const Parse = require('../../node');
+
+describe('Schema', () => {
+ before(() => {
+ Parse.initialize('integration');
+ Parse.CoreManager.set('SERVER_URL', 'http://localhost:1337/parse');
+ Parse.CoreManager.set('MASTER_KEY', 'notsosecret');
+ Parse.Storage._clear();
+ });
+
+ beforeEach((done) => {
+ clear().then(() => {
+ done();
+ });
+ });
+
+ it('invalid get all no schema', (done) => {
+ Parse.Schema.all().then(() => {}).fail((e) => {
+ done();
+ });
+ });
+
+ it('invalid get no schema', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ testSchema.get().then(() => {}).fail((e) => {
+ done();
+ });
+ });
+
+ it('save', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ testSchema.save().then((result) => {
+ assert.equal(result.className, 'SchemaTest');
+ done();
+ });
+ });
+
+ it('get', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ testSchema
+ .addField('defaultFieldString')
+ .addString('stringField')
+ .addNumber('numberField')
+ .addBoolean('booleanField')
+ .addDate('dateField')
+ .addFile('fileField')
+ .addGeoPoint('geoPointField')
+ .addArray('arrayField')
+ .addObject('objectField')
+ .addPointer('pointerField', '_User')
+ .addRelation('relationField', '_User');
+
+ testSchema.save().then(() => {
+ return testSchema.get();
+ }).then((result) => {
+ assert.equal(result.fields.defaultFieldString.type, 'String');
+ assert.equal(result.fields.stringField.type, 'String');
+ assert.equal(result.fields.numberField.type, 'Number');
+ assert.equal(result.fields.booleanField.type, 'Boolean');
+ assert.equal(result.fields.dateField.type, 'Date');
+ assert.equal(result.fields.fileField.type, 'File');
+ assert.equal(result.fields.geoPointField.type, 'GeoPoint');
+ assert.equal(result.fields.arrayField.type, 'Array');
+ assert.equal(result.fields.objectField.type, 'Object');
+ assert.equal(result.fields.pointerField.type, 'Pointer');
+ assert.equal(result.fields.relationField.type, 'Relation');
+ assert.equal(result.fields.pointerField.targetClass, '_User');
+ assert.equal(result.fields.relationField.targetClass, '_User');
+ done();
+ });
+ });
+
+ it('all', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ testSchema.save().then(() => {
+ return Parse.Schema.all();
+ }).then((results) => {
+ assert.equal(results.length, 1);
+ done();
+ });
+ });
+
+ it('update', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ testSchema.addString('name');
+ testSchema.save().then(() => {
+ testSchema.deleteField('name');
+ testSchema.addNumber('quantity');
+ testSchema.addBoolean('status');
+ return testSchema.update();
+ }).then((result) => {
+ assert.equal(result.fields.status.type, 'Boolean');
+ assert.equal(result.fields.quantity.type, 'Number');
+ assert.equal(result.fields.name, undefined);
+ done();
+ });
+ });
+
+ it('delete', (done) => {
+ const testSchema1 = new Parse.Schema('SchemaTest1');
+ const testSchema2 = new Parse.Schema('SchemaTest2');
+ testSchema1.save().then(() => {
+ return testSchema2.save();
+ }).then(() => {
+ return Parse.Schema.all();
+ }).then((results) => {
+ assert.equal(results.length, 2);
+ return testSchema1.delete();
+ }).then(() => {
+ return Parse.Schema.all();
+ }).then((results) => {
+ assert.equal(results.length, 1);
+ assert.equal(results[0].className, 'SchemaTest2');
+ done();
+ });
+ });
+
+ it('save index', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ const index = {
+ name: 1
+ };
+ testSchema.addString('name');
+ testSchema.addIndex('test_index', index);
+ testSchema.save().then((result) => {
+ assert.notEqual(result.indexes.test_index, undefined);
+ done();
+ });
+ });
+
+ it('update index', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ testSchema.save().then((result) => {
+ const index = {
+ name: 1
+ };
+ testSchema.addString('name');
+ testSchema.addIndex('test_index', index);
+ return testSchema.update();
+ }).then((result) => {
+ assert.notEqual(result.indexes.test_index, undefined);
+ done();
+ });
+ });
+
+ it('delete index', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ testSchema.save().then((result) => {
+ const index = {
+ name: 1
+ };
+ testSchema.addString('name');
+ testSchema.addIndex('test_index', index);
+ return testSchema.update();
+ }).then((result) => {
+ assert.notEqual(result.indexes.test_index, undefined);
+ testSchema.deleteIndex('test_index');
+ return testSchema.update();
+ }).then((result) => {
+ assert.equal(result.indexes, undefined);
+ done();
+ });
+ });
+
+ it('invalid field name', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ try {
+ testSchema.addField(null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('invalid field type', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ try {
+ testSchema.addField('name', 'UnknownType');
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('invalid index name', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ try {
+ testSchema.addIndex(null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('invalid index', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ try {
+ testSchema.addIndex('name', null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('invalid pointer name', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ try {
+ testSchema.addPointer(null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('invalid pointer class', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ try {
+ testSchema.addPointer('name', null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('invalid relation name', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ try {
+ testSchema.addRelation(null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('invalid relation class', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ try {
+ testSchema.addRelation('name', null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('assert class name', (done) => {
+ const testSchema = new Parse.Schema();
+ try {
+ testSchema.assertClassName();
+ } catch (e) {
+ done();
+ }
+ });
+});
diff --git a/src/CoreManager.js b/src/CoreManager.js
index 8dac29644..383f93701 100644
--- a/src/CoreManager.js
+++ b/src/CoreManager.js
@@ -76,6 +76,13 @@ type RESTController = {
request: (method: string, path: string, data: mixed) => ParsePromise;
ajax: (method: string, url: string, data: any, headers?: any) => ParsePromise;
};
+type SchemaController = {
+ get: (className: string, options: RequestOptions) => ParsePromise;
+ delete: (className: string, options: RequestOptions) => ParsePromise;
+ create: (className: string, params: any, options: RequestOptions) => ParsePromise;
+ update: (className: string, params: any, options: RequestOptions) => ParsePromise;
+ send(className: string, method: string, params: any, options: RequestOptions): ParsePromise;
+};
type SessionController = {
getSession: (token: RequestOptions) => ParsePromise;
};
@@ -131,6 +138,7 @@ type Config = {
PushController?: PushController,
QueryController?: QueryController,
RESTController?: RESTController,
+ SchemaController?: SchemaController,
SessionController?: SessionController,
StorageController?: StorageController,
UserController?: UserController,
@@ -285,6 +293,15 @@ module.exports = {
return config['RESTController'];
},
+ setSchemaController(controller: SchemaController) {
+ requireMethods('SchemaController', ['get', 'create', 'update', 'delete', 'send'], controller);
+ config['SchemaController'] = controller;
+ },
+
+ getSchemaController(): SchemaController {
+ return config['SchemaController'];
+ },
+
setSessionController(controller: SessionController) {
requireMethods('SessionController', ['getSession'], controller);
config['SessionController'] = controller;
diff --git a/src/Parse.js b/src/Parse.js
index 872f4ae19..4cae086bc 100644
--- a/src/Parse.js
+++ b/src/Parse.js
@@ -116,6 +116,7 @@ Parse.Push = require('./Push');
Parse.Query = require('./ParseQuery').default;
Parse.Relation = require('./ParseRelation').default;
Parse.Role = require('./ParseRole').default;
+Parse.Schema = require('./ParseSchema').default;
Parse.Session = require('./ParseSession').default;
Parse.Storage = require('./Storage');
Parse.User = require('./ParseUser').default;
diff --git a/src/ParseSchema.js b/src/ParseSchema.js
new file mode 100644
index 000000000..b7ea10d05
--- /dev/null
+++ b/src/ParseSchema.js
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2015-present, Parse, LLC.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @flow
+ */
+
+import CoreManager from './CoreManager';
+import ParsePromise from './ParsePromise';
+
+import type { RequestOptions, FullOptions } from './RESTController';
+
+const FIELD_TYPES = ['String', 'Number', 'Boolean', 'Date', 'File', 'GeoPoint', 'Array', 'Object', 'Pointer', 'Relation'];
+
+/**
+ * @class Parse.Schema
+ * @constructor
+ * @param {String} className The class name for the object
+ *
+ * A Parse.Schema object is for handling schema data from Parse.
+ * All the schemas methods require master key.
+ */
+export default class ParseSchema {
+ className: string;
+ _fields: { [key: string]: mixed };
+ _indexes: { [key: string]: mixed };
+
+ constructor(className: ?string) {
+ if (typeof className === 'string') {
+ if (className === 'User' && CoreManager.get('PERFORM_USER_REWRITE')) {
+ this.className = '_User';
+ } else {
+ this.className = className;
+ }
+ }
+
+ this._fields = {};
+ this._indexes = {};
+ }
+
+ static all(options: FullOptions) {
+ options = options || {};
+ const controller = CoreManager.getSchemaController();
+
+ return controller.get('', {}, options)
+ .then((response) => {
+ if (response.results.length === 0) {
+ throw new Error('Schema not found.');
+ }
+ return response.results;
+ })._thenRunCallbacks(options);
+ }
+
+ get(options: FullOptions) {
+ this.assertClassName();
+
+ options = options || {};
+ const controller = CoreManager.getSchemaController();
+
+ return controller.get(this.className, options)
+ .then((response) => {
+ if (!response) {
+ throw new Error('Schema not found.');
+ }
+ return response;
+ })._thenRunCallbacks(options);
+ }
+
+ save(options: FullOptions) {
+ this.assertClassName();
+
+ options = options || {};
+ const controller = CoreManager.getSchemaController();
+ const params = {
+ className: this.className,
+ fields: this._fields,
+ indexes: this._indexes,
+ };
+
+ return controller.create(this.className, params, options)
+ .then((response) => {
+ return response;
+ })._thenRunCallbacks(options);
+ }
+
+ update(options: FullOptions) {
+ this.assertClassName();
+
+ options = options || {};
+ const controller = CoreManager.getSchemaController();
+ const params = {
+ className: this.className,
+ fields: this._fields,
+ indexes: this._indexes,
+ };
+
+ return controller.update(this.className, params, options)
+ .then((response) => {
+ return response;
+ })._thenRunCallbacks(options);
+ }
+
+ delete(options: FullOptions) {
+ this.assertClassName();
+
+ options = options || {};
+ const controller = CoreManager.getSchemaController();
+
+ return controller.delete(this.className, options)
+ .then((response) => {
+ return response;
+ })._thenRunCallbacks(options);
+ }
+
+ assertClassName() {
+ if (!this.className) {
+ throw new Error('You must set a Class Name before making any request.');
+ }
+ }
+
+ addField(name: string, type: string) {
+ type = type || 'String';
+
+ if (!name) {
+ throw new Error('field name may not be null.');
+ }
+ if (FIELD_TYPES.indexOf(type) === -1) {
+ throw new Error(`${type} is not a valid type.`);
+ }
+
+ this._fields[name] = { type };
+
+ return this;
+ }
+
+ addIndex(name: string, index: any) {
+ if (!name) {
+ throw new Error('index name may not be null.');
+ }
+ if (!index) {
+ throw new Error('index may not be null.');
+ }
+
+ this._indexes[name] = index;
+
+ return this;
+ }
+
+ addString(name: string) {
+ return this.addField(name, 'String');
+ }
+
+ addNumber(name: string) {
+ return this.addField(name, 'Number');
+ }
+
+ addBoolean(name: string) {
+ return this.addField(name, 'Boolean');
+ }
+
+ addDate(name: string) {
+ return this.addField(name, 'Date');
+ }
+
+ addFile(name: string) {
+ return this.addField(name, 'File');
+ }
+
+ addGeoPoint(name: string) {
+ return this.addField(name, 'GeoPoint');
+ }
+
+ addArray(name: string) {
+ return this.addField(name, 'Array');
+ }
+
+ addObject(name: string) {
+ return this.addField(name, 'Object');
+ }
+
+ addPointer(name: string, targetClass: string) {
+ if (!name) {
+ throw new Error('field name may not be null.');
+ }
+ if (!targetClass) {
+ throw new Error('You need to set the targetClass of the Pointer.');
+ }
+
+ this._fields[name] = {
+ type: 'Pointer',
+ targetClass
+ };
+
+ return this;
+ }
+
+ addRelation(name: string, targetClass: string) {
+ if (!name) {
+ throw new Error('field name may not be null.');
+ }
+ if (!targetClass) {
+ throw new Error('You need to set the targetClass of the Relation.');
+ }
+
+ this._fields[name] = {
+ type: 'Relation',
+ targetClass
+ };
+
+ return this;
+ }
+
+ deleteField(name: string) {
+ this._fields[name] = { __op: 'Delete'};
+ }
+
+ deleteIndex(name: string) {
+ this._fields = {};
+ this._indexes[name] = { __op: 'Delete'};
+ }
+}
+
+const DefaultController = {
+ send(className: string, method: string, params: any, options: RequestOptions): ParsePromise {
+ const RESTController = CoreManager.getRESTController();
+ const requestOptions = { useMasterKey: true };
+ if (options.hasOwnProperty('sessionToken')) {
+ requestOptions.sessionToken = options.sessionToken;
+ }
+ return RESTController.request(
+ method,
+ `schemas/${className}`,
+ params,
+ requestOptions
+ );
+ },
+
+ get(className: string, options: RequestOptions): ParsePromise {
+ return this.send(className, 'GET', {}, options);
+ },
+
+ create(className: string, params: any, options: RequestOptions): ParsePromise {
+ return this.send(className, 'POST', params, options);
+ },
+
+ update(className: string, params: any, options: RequestOptions): ParsePromise {
+ return this.send(className, 'PUT', params, options);
+ },
+
+ delete(className: string, options: RequestOptions): ParsePromise {
+ return this.send(className, 'DELETE', {}, options);
+ }
+};
+
+CoreManager.setSchemaController(DefaultController);
From fadc6e77779ec8ddfbc10b1d059803c614109d3f Mon Sep 17 00:00:00 2001
From: Diamond Lewis
Date: Wed, 11 Oct 2017 23:17:42 -0500
Subject: [PATCH 2/7] multiple update
---
integration/test/ParseSchemaTest.js | 15 +++++++++++++++
src/ParseSchema.js | 4 +++-
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/integration/test/ParseSchemaTest.js b/integration/test/ParseSchemaTest.js
index 79bcf9a5e..11bfeb1ac 100644
--- a/integration/test/ParseSchemaTest.js
+++ b/integration/test/ParseSchemaTest.js
@@ -98,6 +98,21 @@ describe('Schema', () => {
});
});
+ it('multiple update', (done) => {
+ const testSchema = new Parse.Schema('SchemaTest');
+ testSchema.save().then(() => {
+ testSchema.addString('name');
+ return testSchema.update();
+ }).then(() => {
+ return testSchema.update();
+ }).then(() => {
+ return testSchema.get();
+ }).then((result) => {
+ assert.equal(Object.keys(result.fields).length, 5);
+ done();
+ });
+ });
+
it('delete', (done) => {
const testSchema1 = new Parse.Schema('SchemaTest1');
const testSchema2 = new Parse.Schema('SchemaTest2');
diff --git a/src/ParseSchema.js b/src/ParseSchema.js
index b7ea10d05..8a8e7e5cb 100644
--- a/src/ParseSchema.js
+++ b/src/ParseSchema.js
@@ -98,6 +98,9 @@ export default class ParseSchema {
indexes: this._indexes,
};
+ this._fields = {};
+ this._indexes = {};
+
return controller.update(this.className, params, options)
.then((response) => {
return response;
@@ -219,7 +222,6 @@ export default class ParseSchema {
}
deleteIndex(name: string) {
- this._fields = {};
this._indexes[name] = { __op: 'Delete'};
}
}
From 3995cca2d080f69e11d8771ec219902b8092552d Mon Sep 17 00:00:00 2001
From: Diamond Lewis
Date: Mon, 27 Nov 2017 16:10:12 -0600
Subject: [PATCH 3/7] test fix
---
integration/package.json | 2 +-
integration/test/ParseSchemaTest.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/integration/package.json b/integration/package.json
index b5a35b928..5927ccbc9 100644
--- a/integration/package.json
+++ b/integration/package.json
@@ -3,7 +3,7 @@
"dependencies": {
"express": "^4.13.4",
"mocha": "^2.4.5",
- "parse-server": "^2.6.0"
+ "parse-server": "^2.7.0"
},
"scripts": {
"test": "mocha --reporter dot -t 5000"
diff --git a/integration/test/ParseSchemaTest.js b/integration/test/ParseSchemaTest.js
index 11bfeb1ac..91dfbffc9 100644
--- a/integration/test/ParseSchemaTest.js
+++ b/integration/test/ParseSchemaTest.js
@@ -174,7 +174,7 @@ describe('Schema', () => {
testSchema.deleteIndex('test_index');
return testSchema.update();
}).then((result) => {
- assert.equal(result.indexes, undefined);
+ assert.equal(result.indexes.test_index, undefined);
done();
});
});
From ddf2356c64abd618871ba72af7984578d9ac401e Mon Sep 17 00:00:00 2001
From: Diamond Lewis
Date: Mon, 27 Nov 2017 19:10:59 -0600
Subject: [PATCH 4/7] bump node to 6.11.4
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 28561741c..fc6cec052 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
---
language: node_js
node_js:
-- '5'
+- '6.11.4'
branches:
only:
From a909803cc61f1414deca998b9014d1e736a3d436 Mon Sep 17 00:00:00 2001
From: Diamond Lewis
Date: Mon, 27 Nov 2017 22:14:14 -0600
Subject: [PATCH 5/7] docs
---
src/ParseSchema.js | 179 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 172 insertions(+), 7 deletions(-)
diff --git a/src/ParseSchema.js b/src/ParseSchema.js
index 8a8e7e5cb..4a0300daa 100644
--- a/src/ParseSchema.js
+++ b/src/ParseSchema.js
@@ -17,19 +17,27 @@ import type { RequestOptions, FullOptions } from './RESTController';
const FIELD_TYPES = ['String', 'Number', 'Boolean', 'Date', 'File', 'GeoPoint', 'Array', 'Object', 'Pointer', 'Relation'];
/**
- * @class Parse.Schema
- * @constructor
- * @param {String} className The class name for the object
+ * A Parse.Schema object is for handling schema data from Parse.
+ * All the schemas methods require MasterKey.
*
- *
A Parse.Schema object is for handling schema data from Parse.
- * All the schemas methods require master key.
+ *
+ * const schema = new Parse.Schema('MyClass');
+ * schema.addString('field');
+ * schema.addIndex('index_name', {'field', 1});
+ * schema.save();
+ *
+ *
+ * @alias Parse.Schema
*/
-export default class ParseSchema {
+class ParseSchema {
className: string;
_fields: { [key: string]: mixed };
_indexes: { [key: string]: mixed };
- constructor(className: ?string) {
+ /**
+ * @param {String} className Parse Class string.
+ */
+ constructor(className: string) {
if (typeof className === 'string') {
if (className === 'User' && CoreManager.get('PERFORM_USER_REWRITE')) {
this.className = '_User';
@@ -42,6 +50,21 @@ export default class ParseSchema {
this._indexes = {};
}
+ /**
+ * Static method to get all schemas
+ * @param {Object} options A Backbone-style options object.
+ * Valid options are:
+ * - success: A Backbone-style success callback
+ *
- error: An Backbone-style error callback.
+ *
- useMasterKey: In Cloud Code and Node only, causes the Master Key to
+ * be used for this request.
+ *
- sessionToken: A valid session token, used for making a request on
+ * behalf of a specific user.
+ *
+ *
+ * @return {Parse.Promise} A promise that is resolved with the result when
+ * the query completes.
+ */
static all(options: FullOptions) {
options = options || {};
const controller = CoreManager.getSchemaController();
@@ -55,6 +78,21 @@ export default class ParseSchema {
})._thenRunCallbacks(options);
}
+ /**
+ * Get the Schema from Parse
+ * @param {Object} options A Backbone-style options object.
+ * Valid options are:
+ * - success: A Backbone-style success callback
+ *
- error: An Backbone-style error callback.
+ *
- useMasterKey: In Cloud Code and Node only, causes the Master Key to
+ * be used for this request.
+ *
- sessionToken: A valid session token, used for making a request on
+ * behalf of a specific user.
+ *
+ *
+ * @return {Parse.Promise} A promise that is resolved with the result when
+ * the query completes.
+ */
get(options: FullOptions) {
this.assertClassName();
@@ -70,6 +108,21 @@ export default class ParseSchema {
})._thenRunCallbacks(options);
}
+ /**
+ * Create a new Schema on Parse
+ * @param {Object} options A Backbone-style options object.
+ * Valid options are:
+ * - success: A Backbone-style success callback
+ *
- error: An Backbone-style error callback.
+ *
- useMasterKey: In Cloud Code and Node only, causes the Master Key to
+ * be used for this request.
+ *
- sessionToken: A valid session token, used for making a request on
+ * behalf of a specific user.
+ *
+ *
+ * @return {Parse.Promise} A promise that is resolved with the result when
+ * the query completes.
+ */
save(options: FullOptions) {
this.assertClassName();
@@ -87,6 +140,21 @@ export default class ParseSchema {
})._thenRunCallbacks(options);
}
+ /**
+ * Update a Schema from Parse
+ * @param {Object} options A Backbone-style options object.
+ * Valid options are:
+ * - success: A Backbone-style success callback
+ *
- error: An Backbone-style error callback.
+ *
- useMasterKey: In Cloud Code and Node only, causes the Master Key to
+ * be used for this request.
+ *
- sessionToken: A valid session token, used for making a request on
+ * behalf of a specific user.
+ *
+ *
+ * @return {Parse.Promise} A promise that is resolved with the result when
+ * the query completes.
+ */
update(options: FullOptions) {
this.assertClassName();
@@ -107,6 +175,21 @@ export default class ParseSchema {
})._thenRunCallbacks(options);
}
+ /**
+ * Removing a Schema from Parse
+ * @param {Object} options A Backbone-style options object.
+ * Valid options are:
+ * - success: A Backbone-style success callback
+ *
- error: An Backbone-style error callback.
+ *
- useMasterKey: In Cloud Code and Node only, causes the Master Key to
+ * be used for this request.
+ *
- sessionToken: A valid session token, used for making a request on
+ * behalf of a specific user.
+ *
+ *
+ * @return {Parse.Promise} A promise that is resolved with the result when
+ * the query completes.
+ */
delete(options: FullOptions) {
this.assertClassName();
@@ -119,12 +202,22 @@ export default class ParseSchema {
})._thenRunCallbacks(options);
}
+ /**
+ * Assert if ClassName has been filled
+ * @private
+ */
assertClassName() {
if (!this.className) {
throw new Error('You must set a Class Name before making any request.');
}
}
+ /**
+ * Adding a Field to Create / Update a Schema
+ * @param {String} name Name of the field will be created on Parse
+ * @param {String} type TheCan be a (String|Number|Boolean|Date|Parse.File|Parse.GeoPoint|Array|Object|Pointer|Parse.Relation)
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addField(name: string, type: string) {
type = type || 'String';
@@ -140,6 +233,12 @@ export default class ParseSchema {
return this;
}
+ /**
+ * Adding an Index to Create / Update a Schema
+ * @param {String} name Name of the field will be created on Parse
+ * @param {String} type TheCan be a (String|Number|Boolean|Date|Parse.File|Parse.GeoPoint|Array|Object|Pointer|Parse.Relation)
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addIndex(name: string, index: any) {
if (!name) {
throw new Error('index name may not be null.');
@@ -153,38 +252,84 @@ export default class ParseSchema {
return this;
}
+ /**
+ * Adding String Field
+ * @param {String} name Name of the field will be created on Parse
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addString(name: string) {
return this.addField(name, 'String');
}
+ /**
+ * Adding Number Field
+ * @param {String} name Name of the field will be created on Parse
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addNumber(name: string) {
return this.addField(name, 'Number');
}
+ /**
+ * Adding Boolean Field
+ * @param {String} name Name of the field will be created on Parse
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addBoolean(name: string) {
return this.addField(name, 'Boolean');
}
+ /**
+ * Adding Date Field
+ * @param {String} name Name of the field will be created on Parse
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addDate(name: string) {
return this.addField(name, 'Date');
}
+ /**
+ * Adding File Field
+ * @param {String} name Name of the field will be created on Parse
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addFile(name: string) {
return this.addField(name, 'File');
}
+ /**
+ * Adding GeoPoint Field
+ * @param {String} name Name of the field will be created on Parse
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addGeoPoint(name: string) {
return this.addField(name, 'GeoPoint');
}
+ /**
+ * Adding Array Field
+ * @param {String} name Name of the field will be created on Parse
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addArray(name: string) {
return this.addField(name, 'Array');
}
+ /**
+ * Adding Object Field
+ * @param {String} name Name of the field will be created on Parse
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addObject(name: string) {
return this.addField(name, 'Object');
}
+ /**
+ * Adding Pointer Field
+ * @param {String} name Name of the field will be created on Parse
+ * @param {String} targetClass Name of the target Pointer Class
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addPointer(name: string, targetClass: string) {
if (!name) {
throw new Error('field name may not be null.');
@@ -201,6 +346,12 @@ export default class ParseSchema {
return this;
}
+ /**
+ * Adding Relation Field
+ * @param {String} name Name of the field will be created on Parse
+ * @param {String} targetClass Name of the target Pointer Class
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
addRelation(name: string, targetClass: string) {
if (!name) {
throw new Error('field name may not be null.');
@@ -217,10 +368,22 @@ export default class ParseSchema {
return this;
}
+ /**
+ * Deleting a Field to Update on a Schema
+ * @param {String} name Name of the field will be created on Parse
+ * @param {String} targetClass Name of the target Pointer Class
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
deleteField(name: string) {
this._fields[name] = { __op: 'Delete'};
}
+ /**
+ * Deleting an Index to Update on a Schema
+ * @param {String} name Name of the field will be created on Parse
+ * @param {String} targetClass Name of the target Pointer Class
+ * @return {Parse.Schema} Returns the schema, so you can chain this call.
+ */
deleteIndex(name: string) {
this._indexes[name] = { __op: 'Delete'};
}
@@ -259,3 +422,5 @@ const DefaultController = {
};
CoreManager.setSchemaController(DefaultController);
+
+export default ParseSchema;
From 7c8446c28581e17740d14d49d3d3f00e298cc9c0 Mon Sep 17 00:00:00 2001
From: Diamond Lewis
Date: Wed, 29 Nov 2017 20:24:54 -0600
Subject: [PATCH 6/7] improve docs
---
src/ParseSchema.js | 51 +++++++++++++++++++++++++++++++---------------
1 file changed, 35 insertions(+), 16 deletions(-)
diff --git a/src/ParseSchema.js b/src/ParseSchema.js
index 4a0300daa..c50b159b2 100644
--- a/src/ParseSchema.js
+++ b/src/ParseSchema.js
@@ -52,6 +52,7 @@ class ParseSchema {
/**
* Static method to get all schemas
+ *
* @param {Object} options A Backbone-style options object.
* Valid options are:
* - success: A Backbone-style success callback
@@ -80,6 +81,7 @@ class ParseSchema {
/**
* Get the Schema from Parse
+ *
* @param {Object} options A Backbone-style options object.
* Valid options are:
* - success: A Backbone-style success callback
@@ -110,6 +112,7 @@ class ParseSchema {
/**
* Create a new Schema on Parse
+ *
* @param {Object} options A Backbone-style options object.
* Valid options are:
* - success: A Backbone-style success callback
@@ -141,7 +144,8 @@ class ParseSchema {
}
/**
- * Update a Schema from Parse
+ * Update a Schema on Parse
+ *
* @param {Object} options A Backbone-style options object.
* Valid options are:
* - success: A Backbone-style success callback
@@ -177,6 +181,7 @@ class ParseSchema {
/**
* Removing a Schema from Parse
+ *
* @param {Object} options A Backbone-style options object.
* Valid options are:
* - success: A Backbone-style success callback
@@ -214,7 +219,8 @@ class ParseSchema {
/**
* Adding a Field to Create / Update a Schema
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @param {String} type TheCan be a (String|Number|Boolean|Date|Parse.File|Parse.GeoPoint|Array|Object|Pointer|Parse.Relation)
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
@@ -235,8 +241,9 @@ class ParseSchema {
/**
* Adding an Index to Create / Update a Schema
- * @param {String} name Name of the field will be created on Parse
- * @param {String} type TheCan be a (String|Number|Boolean|Date|Parse.File|Parse.GeoPoint|Array|Object|Pointer|Parse.Relation)
+ *
+ * @param {String} name Name of the field that will be created on Parse
+ * @param {String} type Can be a (String|Number|Boolean|Date|Parse.File|Parse.GeoPoint|Array|Object|Pointer|Parse.Relation)
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
addIndex(name: string, index: any) {
@@ -254,7 +261,8 @@ class ParseSchema {
/**
* Adding String Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
addString(name: string) {
@@ -263,7 +271,8 @@ class ParseSchema {
/**
* Adding Number Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
addNumber(name: string) {
@@ -272,7 +281,8 @@ class ParseSchema {
/**
* Adding Boolean Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
addBoolean(name: string) {
@@ -281,7 +291,8 @@ class ParseSchema {
/**
* Adding Date Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
addDate(name: string) {
@@ -290,7 +301,8 @@ class ParseSchema {
/**
* Adding File Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
addFile(name: string) {
@@ -299,7 +311,8 @@ class ParseSchema {
/**
* Adding GeoPoint Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
addGeoPoint(name: string) {
@@ -308,7 +321,8 @@ class ParseSchema {
/**
* Adding Array Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
addArray(name: string) {
@@ -317,7 +331,8 @@ class ParseSchema {
/**
* Adding Object Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
addObject(name: string) {
@@ -326,7 +341,8 @@ class ParseSchema {
/**
* Adding Pointer Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @param {String} targetClass Name of the target Pointer Class
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
@@ -348,7 +364,8 @@ class ParseSchema {
/**
* Adding Relation Field
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @param {String} targetClass Name of the target Pointer Class
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
@@ -370,7 +387,8 @@ class ParseSchema {
/**
* Deleting a Field to Update on a Schema
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @param {String} targetClass Name of the target Pointer Class
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
@@ -380,7 +398,8 @@ class ParseSchema {
/**
* Deleting an Index to Update on a Schema
- * @param {String} name Name of the field will be created on Parse
+ *
+ * @param {String} name Name of the field that will be created on Parse
* @param {String} targetClass Name of the target Pointer Class
* @return {Parse.Schema} Returns the schema, so you can chain this call.
*/
From b6f6970c9344b9edd139081e72df6c97b8d2bba5 Mon Sep 17 00:00:00 2001
From: Diamond Lewis
Date: Wed, 29 Nov 2017 23:41:14 -0600
Subject: [PATCH 7/7] jest tests
---
src/ParseSchema.js | 2 +-
src/__tests__/CoreManager-test.js | 27 ++
src/__tests__/ParseSchema-test.js | 432 ++++++++++++++++++++++++++++++
3 files changed, 460 insertions(+), 1 deletion(-)
create mode 100644 src/__tests__/ParseSchema-test.js
diff --git a/src/ParseSchema.js b/src/ParseSchema.js
index c50b159b2..4eb8199d0 100644
--- a/src/ParseSchema.js
+++ b/src/ParseSchema.js
@@ -70,7 +70,7 @@ class ParseSchema {
options = options || {};
const controller = CoreManager.getSchemaController();
- return controller.get('', {}, options)
+ return controller.get('', options)
.then((response) => {
if (response.results.length === 0) {
throw new Error('Schema not found.');
diff --git a/src/__tests__/CoreManager-test.js b/src/__tests__/CoreManager-test.js
index 5429907e6..88be5cbd1 100644
--- a/src/__tests__/CoreManager-test.js
+++ b/src/__tests__/CoreManager-test.js
@@ -315,4 +315,31 @@ describe('CoreManager', () => {
CoreManager.setStorageController(controller);
expect(CoreManager.getStorageController()).toBe(controller);
});
+
+ it('requires SchemaController to implement certain functionality', () => {
+ expect(CoreManager.setSchemaController.bind(null, {})).toThrow(
+ 'SchemaController must implement get()'
+ );
+
+ expect(CoreManager.setSchemaController.bind(null, {
+ send: function() {},
+ get: function() {},
+ create: function() {},
+ update: function() {},
+ delete: function() {}
+ })).not.toThrow();
+ });
+
+ it('can set and get SchemaController', () => {
+ var controller = {
+ send: function() {},
+ get: function() {},
+ create: function() {},
+ update: function() {},
+ delete: function() {}
+ };
+
+ CoreManager.setSchemaController(controller);
+ expect(CoreManager.getSchemaController()).toBe(controller);
+ });
});
diff --git a/src/__tests__/ParseSchema-test.js b/src/__tests__/ParseSchema-test.js
new file mode 100644
index 000000000..c99311caa
--- /dev/null
+++ b/src/__tests__/ParseSchema-test.js
@@ -0,0 +1,432 @@
+/**
+ * Copyright (c) 2015-present, Parse, LLC.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+jest.autoMockOff();
+
+var ParseSchema = require('../ParseSchema').default;
+var ParsePromise = require('../ParsePromise').default;
+var CoreManager = require('../CoreManager');
+
+function generateSaveMock(prefix) {
+ return function(name, payload) {
+ return ParsePromise.as({
+ name: name,
+ url: prefix + name
+ });
+ };
+}
+
+var defaultController = CoreManager.getSchemaController();
+
+describe('ParseSchema', () => {
+ it('can create schema', (done) => {
+ var schema = new ParseSchema('SchemaTest');
+ expect(schema.className, 'SchemaTest');
+ done();
+ });
+
+ it('can create schema with User Class', (done) => {
+ var schema = new ParseSchema('User');
+ expect(schema.className, '_User');
+ done();
+ });
+
+ it('cannot use schema without class', (done) => {
+ try {
+ var schema = new ParseSchema();
+ schema.assertClassName();
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('can create schema fields', (done) => {
+ var schema = new ParseSchema('SchemaTest');
+ schema
+ .addField('defaultFieldString')
+ .addString('stringField')
+ .addNumber('numberField')
+ .addBoolean('booleanField')
+ .addDate('dateField')
+ .addFile('fileField')
+ .addGeoPoint('geoPointField')
+ .addArray('arrayField')
+ .addObject('objectField')
+ .addPointer('pointerField', '_User')
+ .addRelation('relationField', '_User');
+
+ expect(schema._fields.defaultFieldString.type, 'String');
+ expect(schema._fields.stringField.type, 'String');
+ expect(schema._fields.numberField.type, 'Number');
+ expect(schema._fields.booleanField.type, 'Boolean');
+ expect(schema._fields.dateField.type, 'Date');
+ expect(schema._fields.fileField.type, 'File');
+ expect(schema._fields.geoPointField.type, 'GeoPoint');
+ expect(schema._fields.arrayField.type, 'Array');
+ expect(schema._fields.objectField.type, 'Object');
+ expect(schema._fields.pointerField.type, 'Pointer');
+ expect(schema._fields.relationField.type, 'Relation');
+ expect(schema._fields.pointerField.targetClass, '_User');
+ expect(schema._fields.relationField.targetClass, '_User');
+ done();
+ });
+
+ it('can create schema indexes', (done) => {
+ var schema = new ParseSchema('SchemaTest');
+ schema.addIndex('testIndex', { name: 1 });
+
+ expect(schema._indexes.name, 1);
+ done();
+ });
+
+ it('cannot add field with null name', (done) => {
+ try {
+ var schema = new ParseSchema('SchemaTest');
+ schema.addField(null, 'string');
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('cannot add field with invalid type', (done) => {
+ try {
+ var schema = new ParseSchema('SchemaTest');
+ schema.addField('testField', 'unknown');
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('cannot add index with null name', (done) => {
+ try {
+ var schema = new ParseSchema('SchemaTest');
+ schema.addIndex(null, {'name': 1});
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('cannot add index with null index', (done) => {
+ try {
+ var schema = new ParseSchema('SchemaTest');
+ schema.addIndex('testIndex', null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('cannot add pointer with null name', (done) => {
+ try {
+ var schema = new ParseSchema('SchemaTest');
+ schema.addPointer(null, 'targetClass');
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('cannot add pointer with null targetClass', (done) => {
+ try {
+ var schema = new ParseSchema('SchemaTest');
+ schema.addPointer('pointerField', null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('cannot add relation with null name', (done) => {
+ try {
+ var schema = new ParseSchema('SchemaTest');
+ schema.addRelation(null, 'targetClass');
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('cannot add relation with null targetClass', (done) => {
+ try {
+ var schema = new ParseSchema('SchemaTest');
+ schema.addRelation('relationField', null);
+ } catch (e) {
+ done();
+ }
+ });
+
+ it('can delete schema field', (done) => {
+ var schema = new ParseSchema('SchemaTest');
+ schema.deleteField('testField');
+ expect(schema._fields.testField._op, 'Delete');
+ done();
+ });
+
+ it('can delete schema index', (done) => {
+ var schema = new ParseSchema('SchemaTest');
+ schema.deleteIndex('testIndex');
+ expect(schema._indexes.testIndex._op, 'Delete');
+ done();
+ });
+
+ // CoreManager.setSchemaController({
+ // send() {},
+ // get() {},
+ // create() {},
+ // update() {},
+ // delete() {},
+ // });
+ it('can save schema', (done) => {
+ CoreManager.setSchemaController({
+ send() {},
+ get() {},
+ update() {},
+ delete() {},
+ create(className, params, options) {
+ expect(className).toBe('SchemaTest');
+ expect(params).toEqual({
+ className: 'SchemaTest',
+ fields: { name: { type: 'String'} },
+ indexes: { testIndex: { name: 1 } }
+ });
+ expect(options).toEqual({});
+ return ParsePromise.as([]);
+ },
+ });
+
+ var schema = new ParseSchema('SchemaTest');
+ schema.addField('name');
+ schema.addIndex('testIndex', {'name': 1});
+ schema.save().then((results) => {
+ expect(results).toEqual([]);
+ done();
+ });
+ });
+
+ it('can update schema', (done) => {
+ CoreManager.setSchemaController({
+ send() {},
+ get() {},
+ create() {},
+ delete() {},
+ update(className, params, options) {
+ expect(className).toBe('SchemaTest');
+ expect(params).toEqual({
+ className: 'SchemaTest',
+ fields: { name: { type: 'String'} },
+ indexes: { testIndex: { name: 1 } }
+ });
+ expect(options).toEqual({});
+ return ParsePromise.as([]);
+ },
+ });
+
+ var schema = new ParseSchema('SchemaTest');
+ schema.addField('name');
+ schema.addIndex('testIndex', {'name': 1});
+ schema.update().then((results) => {
+ expect(results).toEqual([]);
+ done();
+ });
+ });
+
+ it('can delete schema', (done) => {
+ CoreManager.setSchemaController({
+ send() {},
+ create() {},
+ update() {},
+ get() {},
+ delete(className, options) {
+ expect(className).toBe('SchemaTest');
+ expect(options).toEqual({});
+ return ParsePromise.as([]);
+ },
+ });
+
+ var schema = new ParseSchema('SchemaTest');
+ schema.delete().then((results) => {
+ expect(results).toEqual([]);
+ done();
+ });
+ });
+
+ it('can get schema', (done) => {
+ CoreManager.setSchemaController({
+ send() {},
+ create() {},
+ update() {},
+ delete() {},
+ get(className, options) {
+ expect(className).toBe('SchemaTest');
+ expect(options).toEqual({});
+ return ParsePromise.as([]);
+ },
+ });
+
+ var schema = new ParseSchema('SchemaTest');
+ schema.get().then((results) => {
+ expect(results).toEqual([]);
+ done();
+ });
+ });
+
+ it('can get schema with options', (done) => {
+ CoreManager.setSchemaController({
+ send() {},
+ create() {},
+ update() {},
+ delete() {},
+ get(className, options) {
+ expect(className).toBe('SchemaTest');
+ expect(options).toEqual({ sessionToken: 1234 });
+ return ParsePromise.as([]);
+ },
+ });
+
+ var schema = new ParseSchema('SchemaTest');
+ schema.get({ sessionToken: 1234 }).then((results) => {
+ expect(results).toEqual([]);
+ done();
+ });
+ });
+
+ it('cannot get empty schema', (done) => {
+ CoreManager.setSchemaController({
+ send() {},
+ create() {},
+ update() {},
+ delete() {},
+ get(className, options) {
+ expect(className).toBe('SchemaTest');
+ expect(options).toEqual({});
+ return ParsePromise.as(null);
+ },
+ });
+
+ var schema = new ParseSchema('SchemaTest');
+ schema.get().then(() => {
+ // Should never reach
+ expect(true).toBe(false);
+ done();
+ }, (error) => {
+ expect(error.message).toBe('Schema not found.');
+ done();
+ });
+ });
+
+ it('can get all schema', (done) => {
+ CoreManager.setSchemaController({
+ send() {},
+ create() {},
+ update() {},
+ delete() {},
+ get(className, options) {
+ expect(className).toBe('');
+ expect(options).toEqual({});
+ return ParsePromise.as({
+ results: ['all']
+ });
+ },
+ });
+
+ ParseSchema.all().then((results) => {
+ expect(results[0]).toEqual('all');
+ done();
+ });
+ });
+
+ it('can get all schema with options', (done) => {
+ CoreManager.setSchemaController({
+ send() {},
+ create() {},
+ update() {},
+ delete() {},
+ get(className, options) {
+ expect(className).toBe('');
+ expect(options).toEqual({ sessionToken: 1234 });
+ return ParsePromise.as({
+ results: ['all']
+ });
+ },
+ });
+
+ ParseSchema.all({ sessionToken: 1234 }).then((results) => {
+ expect(results[0]).toEqual('all');
+ done();
+ });
+ });
+
+ it('cannot get all schema when empty', (done) => {
+ CoreManager.setSchemaController({
+ send() {},
+ create() {},
+ update() {},
+ delete() {},
+ get(className, options) {
+ expect(className).toBe('');
+ expect(options).toEqual({});
+ return ParsePromise.as({
+ results: []
+ });
+ },
+ });
+
+ ParseSchema.all().then(() => {
+ // Should never reach
+ expect(true).toBe(false);
+ done();
+ }, (error) => {
+ expect(error.message).toBe('Schema not found.');
+ done();
+ });
+ });
+});
+
+describe('SchemaController', () => {
+ beforeEach(() => {
+ CoreManager.setSchemaController(defaultController);
+ var request = function(method, path, data, options) {
+ var name = path.substr(path.indexOf('/') + 1);
+ return ParsePromise.as([]);
+ };
+ var ajax = function(method, path, data, headers) {
+ var name = path.substr(path.indexOf('/') + 1);
+ return ParsePromise.as([]);
+ };
+ CoreManager.setRESTController({ request: request, ajax: ajax });
+ });
+
+ it('save schema with sessionToken', (done) => {
+ var schema = new ParseSchema('SchemaTest');
+ schema.save({ sessionToken: 1234 }).then((results) => {
+ expect(results).toEqual([]);
+ done();
+ });
+ });
+
+ it('get schema', (done) => {
+ var schema = new ParseSchema('SchemaTest');
+ schema.get().then((results) => {
+ expect(results).toEqual([]);
+ done();
+ });
+ });
+
+ it('update schema', (done) => {
+ var schema = new ParseSchema('SchemaTest');
+ schema.update().then((results) => {
+ expect(results).toEqual([]);
+ done();
+ });
+ });
+
+ it('delete schema', (done) => {
+ var schema = new ParseSchema('SchemaTest');
+ schema.delete().then((results) => {
+ expect(results).toEqual([]);
+ done();
+ });
+ });
+});