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?
}
8
  • 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
    Commented May 17, 2016 at 2:16
  • Instead of using the runAs? RunAs documents it runs within sharing context of the user. Commented May 17, 2016 at 2:19
  • No, make your entire test class with sharing. Keep runAs.
    – Adrian Larson
    Commented May 17, 2016 at 2:19
  • Sorry tons of code. Still waiting for results of the deploy validation. Test passed as expected in Sandbox again. Commented May 17, 2016 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
    Commented May 17, 2016 at 2:52

1 Answer 1

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.

3
  • 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. Commented May 17, 2016 at 3:46
  • I didnt even know about IdPair. lol. Commented May 17, 2016 at 3:57
  • Not sure if it's a common pattern, but it is useful for custom sharing.
    – Adrian Larson
    Commented May 17, 2016 at 4:40

You must log in to answer this question.

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