Skip to content

Commit 3bc5adf

Browse files
committed
fix: support before and after save
1 parent 04c3a32 commit 3bc5adf

File tree

2 files changed

+87
-5
lines changed

2 files changed

+87
-5
lines changed

spec/ParseRole.spec.js

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ describe('Parse Role testing', () => {
602602
});
603603
});
604604

605-
it('should trigger afterSave hook when using Parse.Role class reference', done => {
605+
it('should trigger afterSave hook when using Parse.Role', done => {
606606
let afterSaveCalled = false;
607607

608608
Parse.Cloud.afterSave(Parse.Role, req => {
@@ -631,4 +631,84 @@ describe('Parse Role testing', () => {
631631
done();
632632
});
633633
});
634+
635+
it('should trigger beforeSave hook and allow modifying role in beforeSave', done => {
636+
Parse.Cloud.beforeSave(Parse.Role, req => {
637+
// Add a custom field in beforeSave
638+
req.object.set('customField', 'addedInBeforeSave');
639+
});
640+
641+
const acl = new Parse.ACL();
642+
acl.setPublicReadAccess(true);
643+
const role = new Parse.Role('ModifiedRole', acl);
644+
645+
role
646+
.save({}, { useMasterKey: true })
647+
.then(savedRole => {
648+
expect(savedRole.id).toBeDefined();
649+
expect(savedRole.get('customField')).toBe('addedInBeforeSave');
650+
done();
651+
})
652+
.catch(err => {
653+
fail(`Should not have failed: ${err.message}`);
654+
done();
655+
});
656+
});
657+
658+
it('should trigger beforeSave hook using Parse.Role', done => {
659+
let beforeSaveCalled = false;
660+
661+
Parse.Cloud.beforeSave(Parse.Role, req => {
662+
beforeSaveCalled = true;
663+
expect(req.object).toBeDefined();
664+
expect(req.object.get('name')).toBe('BeforeSaveWithClassRef');
665+
});
666+
667+
const acl = new Parse.ACL();
668+
acl.setPublicReadAccess(true);
669+
const role = new Parse.Role('BeforeSaveWithClassRef', acl);
670+
671+
role
672+
.save({}, { useMasterKey: true })
673+
.then(savedRole => {
674+
expect(savedRole.id).toBeDefined();
675+
expect(beforeSaveCalled).toBe(true);
676+
done();
677+
})
678+
.catch(err => {
679+
fail(`Should not have failed: ${err.message}`);
680+
done();
681+
});
682+
});
683+
684+
it('should allow modifying role name in beforeSave hook', done => {
685+
Parse.Cloud.beforeSave(Parse.Role, req => {
686+
// Modify the role name in beforeSave
687+
if (req.object.get('name') === 'OriginalName') {
688+
req.object.set('name', 'ModifiedName');
689+
}
690+
});
691+
692+
const acl = new Parse.ACL();
693+
acl.setPublicReadAccess(true);
694+
const role = new Parse.Role('OriginalName', acl);
695+
696+
role
697+
.save({}, { useMasterKey: true })
698+
.then(savedRole => {
699+
expect(savedRole.id).toBeDefined();
700+
expect(savedRole.get('name')).toBe('ModifiedName');
701+
// Verify the name was actually saved to the database
702+
const query = new Parse.Query(Parse.Role);
703+
return query.get(savedRole.id, { useMasterKey: true });
704+
})
705+
.then(fetchedRole => {
706+
expect(fetchedRole.get('name')).toBe('ModifiedName');
707+
done();
708+
})
709+
.catch(err => {
710+
fail(`Should not have failed: ${err.message}`);
711+
done();
712+
});
713+
});
634714
});

src/RestWrite.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,10 +1743,12 @@ RestWrite.prototype.buildParseObjects = function () {
17431743
const readOnlyAttributes = className.constructor.readOnlyAttributes
17441744
? className.constructor.readOnlyAttributes()
17451745
: [];
1746-
// For _Role class, the 'name' field is read-only after the object has been saved
1747-
// Since _handleSaveResponse is called after buildParseObjects and sets the objectId,
1748-
// we need to exclude 'name' from being set to avoid "A role's name can only be set before it has been saved" error
1749-
if (this.className === '_Role' && !readOnlyAttributes.includes('name')) {
1746+
1747+
// For _Role class, 'name' cannot be set after the role has an objectId.
1748+
// In afterSave context, _handleSaveResponse has already set the objectId,
1749+
// so we treat 'name' as read-only to avoid Parse SDK validation errors.
1750+
const isRoleAfterSave = this.className === '_Role' && this.response && !this.query;
1751+
if (isRoleAfterSave && this.data.name && !readOnlyAttributes.includes('name')) {
17501752
readOnlyAttributes.push('name');
17511753
}
17521754
if (!this.originalData) {

0 commit comments

Comments
 (0)