1

I have a simple getter inside my class that returns a list of cases depending on who the currently logged in user is (in my circumstance this is a Community User). When i run the code in my full sandbox, it passes with no issue, but the test fails when attempting to push to production. I am not using any @SeeAllData or anything else that would base data inconsistencies.

Additionally, if i directly run the same query in the getter within the context of the User within my System.RunAs() bracket, the list returns with the values intended.

What could be causing this strange error? I've never come across something like this where i can directly write the same query above the system.assert for the controller getter and get values where the getter iteself returns nothing. The portalCases query is literally the same and both are being invoked from the same context user, and it works/passes perfectly in my Staging org.

Controller Getter:

public List<Case> portalCases
    {
        get {
            if (portalCases == null)
            {
                portalCases = new List<Case>();
                portalCases = [SELECT Id, 
                                      AccountId, 
                                      Status, 
                                      RecordType.Name,
                                      Problem_Explanation__c,
                                      Patient_Name__c,
                                      Patient_DOB__c,
                                      Patient_MRN__c,
                                      Ordering_Physician__c,
                                      Web_Subject__c,
                                      Account.Name,
                                      CaseNumber,
                                      Collection_Date_Time__c,
                                      Affected_Tests__c,
                                      CreatedDate, 
                                      Description,
                                      CreatedBy.Name
                               FROM   Case
                               WHERE  (RecordType.Name = 'Problem Resolution' OR RecordType.Name = 'Web Inquiry')
                               AND    Account.Id IN :entitledCaseAccountIds];     

            }
            return portalCases;
        }
        set;
    }

Test Method (After all the other stuff):

System.RunAs(portalUser){
            TriCorePortalCaseController controller = new TriCorePortalCaseController();
            System.assert(controller.currentPortalUser != null); //this passes and it finds the user
            System.assert(!controller.entitledCaseAccountIds.isEmpty()); //this passes and finds the account ids permitted
            system.debug('Queried: ' +[SELECT Id, 
                                      AccountId, 
                                      Status, 
                                      RecordType.Name,
                                      Problem_Explanation__c,
                                      Patient_Name__c,
                                      Patient_DOB__c,
                                      Patient_MRN__c,
                                      Ordering_Physician__c,
                                      Web_Subject__c,
                                      Account.Name,
                                      CaseNumber,
                                      Collection_Date_Time__c,
                                      Affected_Tests__c,
                                      CreatedDate, 
                                      Description,
                                      CreatedBy.Name
                               FROM   Case
                               WHERE  (RecordType.Name = 'Problem Resolution' OR RecordType.Name = 'Web Inquiry')
                               AND    Account.Id IN :controller.entitledCaseAccountIds]); //this returns 2 cases as it should
            System.assert(!controller.portalCases.isEmpty());//This fails and returns an empty list. Why?
}
  • What happens if you run your test with sharing? Are the permissions for Case object, AccountId field, and Account object the same across the two orgs? – Adrian Larson May 17 '16 at 2:16
  • Instead of using the runAs? RunAs documents it runs within sharing context of the user. – cricketlang May 17 '16 at 2:19
  • No, make your entire test class with sharing. Keep runAs. – Adrian Larson May 17 '16 at 2:19
  • Sorry tons of code. Still waiting for results of the deploy validation. Test passed as expected in Sandbox again. – cricketlang May 17 '16 at 2:47
  • Ah dang, you can only find out if it succeeds by deploying. That's tricky. What sharing modifier is applied to the controller itself? – Adrian Larson May 17 '16 at 2:52
1

You need to make sure the portal user has read access to the Case records. You might be able to make a Case Sharing Rule work. Failing that, you would need to use Apex Sharing. Unfortunately, if you create the record shares through triggers, you will need one each on Case, Contact, and User so that you match $User.Contact.AccountId to the Case.AccountId.

I've done similar sharing patterns before, and one useful concept was to create an IdPair class (in this case User to Case), so you can have one Set<IdPair> to insert, and one Set<IdPair> to delete.

  • Was definitely a sharing issue. All sharing is done with Apex Sharing, so i have a bit of work to do on getting all that taken care of, but this definitely explained the issues with the deployment. – cricketlang May 17 '16 at 3:46
  • I didnt even know about IdPair. lol. – cricketlang May 17 '16 at 3:57
  • Not sure if it's a common pattern, but it is useful for custom sharing. – Adrian Larson May 17 '16 at 4:40

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.