fix: Error in afterSave trigger for Parse.Role due to name field (#9883)
This commit is contained in:
@@ -25,7 +25,7 @@ describe('Cloud Code Logger', () => {
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return Parse.User.signUp('tester', 'abc')
|
return Parse.User.signUp('tester', 'abc')
|
||||||
.catch(() => {})
|
.catch(() => { })
|
||||||
.then(loggedInUser => (user = loggedInUser))
|
.then(loggedInUser => (user = loggedInUser))
|
||||||
.then(() => Parse.User.logIn(user.get('username'), 'abc'));
|
.then(() => Parse.User.logIn(user.get('username'), 'abc'));
|
||||||
})
|
})
|
||||||
@@ -139,7 +139,7 @@ describe('Cloud Code Logger', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it_id('9857e15d-bb18-478d-8a67-fdaad3e89565')(it)('should log an afterSave', done => {
|
it_id('9857e15d-bb18-478d-8a67-fdaad3e89565')(it)('should log an afterSave', done => {
|
||||||
Parse.Cloud.afterSave('MyObject', () => {});
|
Parse.Cloud.afterSave('MyObject', () => { });
|
||||||
new Parse.Object('MyObject')
|
new Parse.Object('MyObject')
|
||||||
.save()
|
.save()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -271,7 +271,7 @@ describe('Cloud Code Logger', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Parse.Cloud.run('aFunction', { foo: 'bar' })
|
Parse.Cloud.run('aFunction', { foo: 'bar' })
|
||||||
.catch(() => {})
|
.catch(() => { })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const logs = spy.calls.all().reverse();
|
const logs = spy.calls.all().reverse();
|
||||||
expect(logs[0].args[1]).toBe('Parse error: ');
|
expect(logs[0].args[1]).toBe('Parse error: ');
|
||||||
@@ -384,8 +384,8 @@ describe('Cloud Code Logger', () => {
|
|||||||
Parse.Cloud.beforeSave('TestClassError', () => {
|
Parse.Cloud.beforeSave('TestClassError', () => {
|
||||||
throw new Error('Failed');
|
throw new Error('Failed');
|
||||||
});
|
});
|
||||||
Parse.Cloud.beforeSave('TestClass', () => {});
|
Parse.Cloud.beforeSave('TestClass', () => { });
|
||||||
Parse.Cloud.afterSave('TestClass', () => {});
|
Parse.Cloud.afterSave('TestClass', () => { });
|
||||||
|
|
||||||
spy = spyOn(Config.get('test').loggerController.adapter, 'log').and.callThrough();
|
spy = spyOn(Config.get('test').loggerController.adapter, 'log').and.callThrough();
|
||||||
|
|
||||||
|
|||||||
@@ -601,4 +601,78 @@ describe('Parse Role testing', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should trigger afterSave hook when using Parse.Role', async () => {
|
||||||
|
const afterSavePromise = new Promise(resolve => {
|
||||||
|
Parse.Cloud.afterSave(Parse.Role, req => {
|
||||||
|
expect(req.object).toBeDefined();
|
||||||
|
expect(req.object.get('name')).toBe('AnotherTestRole');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
const role = new Parse.Role('AnotherTestRole', acl);
|
||||||
|
|
||||||
|
const savedRole = await role.save({}, { useMasterKey: true });
|
||||||
|
expect(savedRole.id).toBeDefined();
|
||||||
|
|
||||||
|
await afterSavePromise;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should trigger beforeSave hook and allow modifying role in beforeSave', async () => {
|
||||||
|
Parse.Cloud.beforeSave(Parse.Role, req => {
|
||||||
|
// Add a custom field in beforeSave
|
||||||
|
req.object.set('customField', 'addedInBeforeSave');
|
||||||
|
});
|
||||||
|
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
const role = new Parse.Role('ModifiedRole', acl);
|
||||||
|
|
||||||
|
const savedRole = await role.save({}, { useMasterKey: true });
|
||||||
|
expect(savedRole.id).toBeDefined();
|
||||||
|
expect(savedRole.get('customField')).toBe('addedInBeforeSave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should trigger beforeSave hook using Parse.Role', async () => {
|
||||||
|
let beforeSaveCalled = false;
|
||||||
|
|
||||||
|
Parse.Cloud.beforeSave(Parse.Role, req => {
|
||||||
|
beforeSaveCalled = true;
|
||||||
|
expect(req.object).toBeDefined();
|
||||||
|
expect(req.object.get('name')).toBe('BeforeSaveWithClassRef');
|
||||||
|
});
|
||||||
|
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
const role = new Parse.Role('BeforeSaveWithClassRef', acl);
|
||||||
|
|
||||||
|
const savedRole = await role.save({}, { useMasterKey: true });
|
||||||
|
expect(savedRole.id).toBeDefined();
|
||||||
|
expect(beforeSaveCalled).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow modifying role name in beforeSave hook', async () => {
|
||||||
|
Parse.Cloud.beforeSave(Parse.Role, req => {
|
||||||
|
// Modify the role name in beforeSave
|
||||||
|
if (req.object.get('name') === 'OriginalName') {
|
||||||
|
req.object.set('name', 'ModifiedName');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
const role = new Parse.Role('OriginalName', acl);
|
||||||
|
|
||||||
|
const savedRole = await role.save({}, { useMasterKey: true });
|
||||||
|
expect(savedRole.id).toBeDefined();
|
||||||
|
expect(savedRole.get('name')).toBe('ModifiedName');
|
||||||
|
|
||||||
|
// Verify the name was actually saved to the database
|
||||||
|
const query = new Parse.Query(Parse.Role);
|
||||||
|
const fetchedRole = await query.get(savedRole.id, { useMasterKey: true });
|
||||||
|
expect(fetchedRole.get('name')).toBe('ModifiedName');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1743,6 +1743,14 @@ RestWrite.prototype.buildParseObjects = function () {
|
|||||||
const readOnlyAttributes = className.constructor.readOnlyAttributes
|
const readOnlyAttributes = className.constructor.readOnlyAttributes
|
||||||
? className.constructor.readOnlyAttributes()
|
? className.constructor.readOnlyAttributes()
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
|
// For _Role class, 'name' cannot be set after the role has an objectId.
|
||||||
|
// In afterSave context, _handleSaveResponse has already set the objectId,
|
||||||
|
// so we treat 'name' as read-only to avoid Parse SDK validation errors.
|
||||||
|
const isRoleAfterSave = this.className === '_Role' && this.response && !this.query;
|
||||||
|
if (isRoleAfterSave && this.data.name && !readOnlyAttributes.includes('name')) {
|
||||||
|
readOnlyAttributes.push('name');
|
||||||
|
}
|
||||||
if (!this.originalData) {
|
if (!this.originalData) {
|
||||||
for (const attribute of readOnlyAttributes) {
|
for (const attribute of readOnlyAttributes) {
|
||||||
extraData[attribute] = this.data[attribute];
|
extraData[attribute] = this.data[attribute];
|
||||||
|
|||||||
Reference in New Issue
Block a user