2

We are an ISV developing a Managed Package.

We wrote some Unit tests that do things like (this is an Example)

Custom_Object__c a = new Custom_Object__c(Name = 'Test');
insert a;

Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
        User usr = new User(Alias = 'standt', Email= 'somerandomEmail@here.com',
                            EmailEncodingKey='UTF-8', LastName='Testing', 
                            LanguageLocaleKey='en_US',
                            LocaleSidKey='en_US', ProfileId = p.Id,
                            TimeZoneSidKey='America/Los_Angeles', 
                            UserName= 'somerandomUsername@here.com');

        insert usr;
    System.runAs(usr) {
      a.Name = 'testxxx';
      update a;
    }

In our dev org, the sharing model for Custom_Object__c is Public Read/Write. However, some customers in some of their orgs run with Private Sharing model.

When we run our tests in their orgs, they fail.

However, if we switch our dev org to Private and amend the tests like so

Custom_Object__c a = new Custom_Object__c(Name = 'Test');
insert a;

Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
        User usr = new User(Alias = 'standt', Email= 'somerandomEmail@here.com',
                            EmailEncodingKey='UTF-8', LastName='Testing', 
                            LanguageLocaleKey='en_US',
                            LocaleSidKey='en_US', ProfileId = p.Id,
                            TimeZoneSidKey='America/Los_Angeles', 
                            UserName= 'somerandomUsername@here.com');

        insert usr;

UserRecordAccess ura = [SELECT HasEditAccess, RecordId FROM UserRecordAccess WHERE UserId = :usr.Id AND RecordId = :a.Id];

            if (!ura.HasEditAccess) {
                Custom_Object__Share share = new Custom_Object__Share (ParentId = t.Id, UserOrGroupId = usr.Id, AccessLevel = 'Edit');
                insert share;
            }

    System.runAs(usr) {
      a.Name = 'testxxx';
      update a;
    }

Then switching back to Public Read/Write fails because

Error: Unable to change sharing model because sharing objects are referenced by the following components:

How are we meant to support both sharing models as an ISV?

Ideally we want to baseline our package on Public Read/Write but then we also want our tests not fail if the customer has changed to Private or Public Read Only.

  • 1
    Have you tried to use Type.forName in order to dynamically create share record without referencing that explicitly? – kurunve Mar 10 '20 at 8:25
1

If you want this unit test user with the Standard User profile to have full read/write capabilities, I'd suggest creating a PermissionSet, adding object permissions to that Permission Set via ObjectPermissions, then assign it to this unit test user via PermissionSetAssignment. All of these are standard objects of which you can use regular DML commands to create and work with.

Something along these lines:

// Create new Permission Set for your unit test user
PermissionSet ps = new PermissionSet(
    Label='Custom Object Perms',
    Name='Custom_Object_Perms',
    Description='Gives permissions to read/write on Custom Object'
);
insert ps;

// Assign read/write permissions to this new Permission Set
ObjectPermissions op = new ObjectPermissions(
    ParentId = ps.Id,
    SobjectType = 'Custom_Object__c',
    PermissionsViewAllRecords = true,
    PermissionsModifyAllRecords = true
    // Add any other permissions on the object you'd like...
);
insert op;

// Assign the Permission Set to your unit test user
PermissionSetAssignment psa = new PermissionSetAssignment(
    PermissionSetId = ps.Id,
    AssigneeId = usr.Id
);
insert psa;

NOTE: I'm not sure if creating this PermissionSet actually creates the Permission Set permanently in the org via the unit test. Worth testing, and you could always delete the PermissionSetAssignments and PermissionSet at the end of your unit test method.

Update 3/10: As confirmed by @sfdcfox, no data persists after the unit test, including all these Permission Set related objects, so you don't have to worry about cleaning up the data.

  • 1
    No data ever persists beyond the end of a unit test. There was a bug where Platform Event triggers were doing this, but that's been fixed. It's perfectly safe to do what you describe. – sfdcfox Mar 10 '20 at 12:27
  • @sfdcfox Thanks for confirming - I'll update my post to remove that note – Brian Miller Mar 10 '20 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.