[SalesForce] Unit-Testing Sites Permission Involving a Sharing Rule with Unit-Test Created Data

We currently have a Salesforce Site, and we're trying to add some unit-tests, around permissions and sharing rules that need to be set. We've smoke tested everything via the UI, and permissions appear to be set up correctly in the DevOrg, where these tests are running.

When running the unit-test with (seeAllData=False) and creating test data directly in the unit-test, the tests are failing with the assertion that there is 1 Case in the DB (when querying from within the context of the Sites user). However, when using (seeAllData=True) and using data that is in the dev org, the same (or very similar) tests are passing.

Some background information.

  1. The Org-Wide Sharing Rules for the Case Object is set to Private.
  2. There is a Criteria Based Sharing Rule, granting "Read" access to any Case with the RecordType "Geography" to a Public Group in which the Sites User is a member. Everything else should remain Private.
  3. The Sites user has "Read" access to the Case object and fields as defined in the "Public Access Settings" in the Site.

Here is Example Code, which, provided the 3 items above are met, should be reproducible.

@isTest
private class SitesPermission_Test{

  @isTest(seeAllData=False)
  static void sitesUserShouldSeeCase(){
    RecordType myRT = [SELECT Id FROM RecordType WHERE sObjectType = 'Case' AND DeveloperName = 'Geography' LIMIT 1];
    Test.startTest();
    Case myCase = new Case(Subject = 'Test', RecordTypeId = myRT.Id, Status = 'New');
    insert myCase;
    Test.stopTest();
    system.debug(myCase);

    List<Case> allCases = [SELECT Id FROM Case];
    system.assertEquals(1, allCases.size()); //This works

    User sitesUser = [SELECT Id FROM User WHERE Profile.Name = 'Sites Profile' AND isActive = TRUE LIMIT 1];
    system.runAs(sitesUser){
      List<Case> allSitesCases = [SELECT Id FROM Case];
      system.assertEquals(1, allSitesCases.size()); //This is currently failing
    }
  }

  //Everything is passing
  @isTest(seeAllData=True)
  static void sitesUserShouldSeeExistingCase(){
    RecordType myRT = [SELECT Id FROM RecordType WHERE sObjectType = 'Case' AND DeveloperName = 'Geography' LIMIT 1];
    List<Case> allGeoCases = [SELECT Id FROM Case WHERE RecordTypeId = :myRT.Id];
    system.debug(allGeoCases);
    system.assertNotEquals(0, allGeoCases.size()); //there should be at least 1 case in devOrg

    List<Case> allNonGeoCases = [SELECT Id FROM Case WHERE RecordTypeId != :myRT.Id];
    system.debug(allNonGeoCases);
    system.assertNotEquals(0, allNonGeoCases.size()); //there should be at least 1 case in devOrg

    User sitesUser = [SELECT Id FROM User WHERE Profile.Name = 'Sites Profile' AND isActive = TRUE LIMIT 1];
      system.runAs(sitesUser){
        List<Case> allSitesCases = [SELECT Id FROM Case WHERE RecordTypeId = :myRT.Id];
        system.assertEquals(allGeoCases.size(), allSitesCases.size());  //This is passing
        List<Case> sitesAllNonGeoCases = [SELECT Id FROM Case WHERE RecordTypeId != :myRT.Id];
        system.debug(sitesAllNonGeoCases);
        system.assertEquals(0, sitesAllNonGeoCases.size());  //shouldn't be able to see nonGeo
      }    
  }
}

Is this a bug, or is it perhaps by design as Sharing Rules are created asynchronously? I've tried surrounding the creation of the Case in test.StartTest() & test.StopTest() to force anything asynchronously to run, but still no avail.

Has anyone else experienced this issue, and are there any workarounds aside from using (seeAllData=true)?

Best Answer

It looks like from here, http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_bulk_sharing_understanding.htm

Criteria based rules cannot be tested in Apex. Trying out this code and looking at the CaseSharing records for the new case shows that only the Owner sharing record gets created.

Andy