Run Schema validations after beforeSave #2672 (#2677)

* Adds test to repro #2672

* Run schema validation after beforeSave is run

* Makes authData part of base _User object

* exclude flaky pg test
This commit is contained in:
Florent Vilmart
2016-09-09 14:41:03 -04:00
committed by GitHub
parent 58a2ee32fa
commit 364604e181
5 changed files with 48 additions and 5 deletions

View File

@@ -954,7 +954,11 @@ it('beforeSave should not affect fetched pointers', done => {
});
});
it('should fully delete objects when using `unset` with beforeSave (regression test for #1840)', done => {
/*
TODO: fix for Postgres
trying to delete a field that doesn't exists doesn't play nice
*/
it_exclude_dbs(['postgres'])('should fully delete objects when using `unset` with beforeSave (regression test for #1840)', done => {
var TestObject = Parse.Object.extend('TestObject');
var BeforeSaveObject = Parse.Object.extend('BeforeSaveChanged');

View File

@@ -1494,6 +1494,42 @@ it('ensure that if you try to sign up a user with a unique username and email, b
done();
});
});
it('should not update schema beforeSave #2672', (done) => {
Parse.Cloud.beforeSave('MyObject', (request, response) => {
if (request.object.get('secret')) {
response.error('cannot set secret here');
return;
}
response.success();
});
let object = new Parse.Object('MyObject');
object.set('key', 'value');
object.save().then(() => {
return object.save({'secret': 'should not update schema'});
}).then(() => {
fail();
done();
}, () => {
return rp({
method: 'GET',
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-Master-Key': 'test'
},
uri: 'http://localhost:8378/1/schemas/MyObject',
json: true
});
}).then((res) => {
let fields = res.fields;
expect(fields.secret).toBeUndefined();
done();
}, (err) => {
jfail(err);
done();
});
});
});
describe_only_db('mongo')('legacy _acl', () => {

View File

@@ -96,7 +96,8 @@ const userSchema = {
"username": {"type": "String"},
"password": {"type": "String"},
"email": {"type": "String"},
"emailVerified": {"type": "Boolean"}
"emailVerified": {"type": "Boolean"},
"authData": {"type": "Object"}
},
"classLevelPermissions": defaultClassLevelPermissions,
}
@@ -676,6 +677,7 @@ describe('schemas', () => {
password: {type: 'String'},
email: {type: 'String'},
emailVerified: {type: 'Boolean'},
authData: {type: 'Object'},
newField: {type: 'String'},
ACL: {type: 'ACL'}
},
@@ -696,6 +698,7 @@ describe('schemas', () => {
password: {type: 'String'},
email: {type: 'String'},
emailVerified: {type: 'Boolean'},
authData: {type: 'Object'},
newField: {type: 'String'},
ACL: {type: 'ACL'}
},

View File

@@ -31,6 +31,7 @@ const defaultColumns = Object.freeze({
"password": {type:'String'},
"email": {type:'String'},
"emailVerified": {type:'Boolean'},
"authData": {type:'Object'}
},
// The additional default columns for the _Installation collection (in addition to DefaultCols)
_Installation: {

View File

@@ -62,8 +62,6 @@ RestWrite.prototype.execute = function() {
return this.getUserAndRoleACL();
}).then(() => {
return this.validateClientClassCreation();
}).then(() => {
return this.validateSchema();
}).then(() => {
return this.handleInstallation();
}).then(() => {
@@ -72,6 +70,8 @@ RestWrite.prototype.execute = function() {
return this.validateAuthData();
}).then(() => {
return this.runBeforeTrigger();
}).then(() => {
return this.validateSchema();
}).then(() => {
return this.setRequiredFieldsIfNeeded();
}).then(() => {
@@ -176,7 +176,6 @@ RestWrite.prototype.runBeforeTrigger = function() {
if (this.query && this.query.objectId) {
delete this.data.objectId
}
return this.validateSchema();
}
});
};