5

Ideally, I'd like to write a unit test to help me "dummy check" for unexpected effects of the upcoming guest user sharing setting changes.

We'd had some controller/trigger code "gracefully handling" data it couldn't see thanks to the new sharing restrictions ... which resulted in simply "not doing" some work that it was supposed to do, which from a business process perspective isn't "graceful" at all (it was an important automation for downstream processes).

I'd like to write up a unit test with some system.assert statements validating that "data still goes where it's supposed to" when the "submit" button a public-facing Visualforce page of a community is clicked.

Unfortunately, I can't seem to make the "submit" button on a Controller for a public-facing Visualforce page work in the context of a unit test because the record whose creation it results in doesn't get its corresponding "sharing setting" record created in time for the execution context to pick it up.

I did a little proof of concept here ...

@isTest
public class TestClass {

    private static Id guestProfileId = Util.getProfileIdByName('Public Facing Portal Profile');
    private static User guestUser;
    private static Id portalGroupId = [SELECT Id FROM Group WHERE Name = 'Public_Portal' LIMIT 1][0].Id;

    private static Custom_Object__c co;


    private static testMethod void runTest() {
        createCO();
        Test.startTest();
        // Note that putting createCO() inside the test and doesGuestSharingRuleExistForCO() doesn't help.
        // That's what I was afraid of.
        try {
            doesGuestSharingRuleExistForCO(co.Id);
        }
        catch (Util.DeveloperException e) {
            System.assert(FALSE, e.getMessage());
        }
        Test.stopTest();
    }


    private static void cacheUsers() {
        guestUser = [SELECT Id FROM User WHERE profileid = :guestProfileId AND IsActive = TRUE LIMIT 1][0];
    }

    private static void createCO() {
        co = new Custom_Object__c();
        INSERT co;
    }

    private static void doesGuestSharingRuleExistForCO(Id coId) {
        List<SObject> existingSharingRulesOnCO = [
            SELECT Id FROM Custom_Object__share
            WHERE RowCause = 'GuestRule' AND AccessLevel = 'Read' AND ParentId = :coId AND UserOrGroupId = :portalGroupId LIMIT 1
        ];
        if ( existingSharingRulesOnCO.isEmpty() ) { throw new Util.DeveloperException('Guest User sharing is not on for this custom object ID'); }
    }

    private static Boolean isCOSharingFlippedOnAtAll(){
        String lookingFor = 'Custom_Object__Share';
        for (Schema.SObjectType sObjectType : Schema.getGlobalDescribe().values() ) {
            String sobjName = String.valueOf(sObjectType);
            if (sobjName.contains(lookingFor) ) { return TRUE; }
        }
        return FALSE;
    }

}

Am I just out of luck? Is there no way to properly unit-test the effects (to automations relying upon "guest user" sharing settings when running as "guest user") of simulating the insertion of records into my database from a Visualforce page, due to not being able to separate out "execution context" enough and "wait" for the sharing rule record for the new record to come into existence?

1 Answer 1

4

Quoting a section from this help topic: https://help.salesforce.com/articleView?id=security_sharing_rule_types.htm&type=5

You can’t use Apex to create a criteria-based sharing rule. And you can’t test criteria-based sharing using Apex.

I'm assuming the new Guest User Sharing rules fall under this bracket and therefore can't be used in Unit Testing. After running into my own brick wall with this, it appears any Share records created are for the Record Owner, or Parent Owner (Owner/Implicit Child).

Looks like manual testing is the way to go for ensuring Secure Guest User Access doesn't break Production.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .