+ Start a Discussion
JaggyJaggy 

System.runAs not working as expected

Hi,

 

I've written a test method and I've to test the functionality by different users. So I've used System.runAs for that. But it's not working as I expected. Below is my code.

 

        Profile projectManagerProfile = [SELECT Id FROM Profile WHERE Name = 'Project Manager'];
        Profile teamMemberProfile = [SELECT Id FROM Profile WHERE Name = 'Team Member'];        

        User projectManager = new User(alias = 'promgr', 
                                       email = 'pm@aaaa.co.uk', 
                                       emailencodingkey = 'UTF-8', 
                                       lastname = 'Testing', 
                                       languagelocalekey = 'en_US', 
                                       localesidkey = 'en_US', 
                                       profileid = projectManagerProfile.Id, 
                                       timezonesidkey = 'Europe/London', 
                                       username = 'xxxpm.aaa@aa.co.uk');  
        
        User teamMemberRead = new User(alias = 'tmr', 
                                       email = 'team.member.read@precursive.co.uk', 
                                       emailencodingkey = 'UTF-8', 
                                       lastname = 'Testing', 
                                       languagelocalekey = 'en_US', 
                                       localesidkey = 'en_US', 
                                       profileid = teamMemberProfile.Id, 
                                       timezonesidkey = 'Europe/London', 
                                       username = 'xxxteam.member.read@precursive.co.uk');  
        
        User teamMemberWrite = new User(alias = 'tmw', 
                                        email = 'team.member.write@aaa.co.uk', 
                                        emailencodingkey = 'UTF-8', 
                                        lastname = 'Testing', 
                                        languagelocalekey = 'en_US', 
                                        localesidkey = 'en_US', 
                                        profileid = teamMemberProfile.Id, 
                                        timezonesidkey = 'Europe/London', 
                                        username = 'xxxteam.member.write@aaaa.co.uk');  
                                        
        insert new User[]{projectManager, teamMemberRead, teamMemberWrite};     
        
        Project__c project = null;
        Phase__c phase = null;	// default phase of a project
        Team_Member__c teamMember1 = null;
        Team_Member__c teamMember2 = null;
        

        // Login as PM and create a project
        System.runAs(projectManager) {
            project = new Project__c(Name = 'XXX My Dummy Project XXX',                                      
                                                Start_Date__c = System.today(),
                                                End_Date__c = System.today().addYears(1),
                                                Description__c = 'XXX My Dummy Desc XXX');          
            insert project;
            
            // A default phase is always created upon creation of a project.
            // So we don't need to create one seperatley.                                 
            phase = [SELECT Id FROM Phase__c WHERE Name = 'XXX My Dummy Project XXX - Phase 1' and Project__c = :project.Id];   

            teamMember1 = new Team_Member__c(Name = 'XXX My Team Member Read XXX',
                                   			 Project__c = project.Id,
                                   			 Phase__c = phase.Id,
                                   			 User__c = teamMemberRead.Id,
                                   			 Access__c = 'Read');
           
            teamMember2 = new Team_Member__c(Name = 'XXX My Team Member Write XXX',
                                   			 Project__c = project.Id,
                                   			 Phase__c = phase.Id,
                                   			 User__c = teamMemberWrite.Id,
                                   			 Access__c = 'Write');
            
            insert new Team_Member__c[]{teamMember1, teamMember2};
        }
        
        /* Testing begins */
        // Check for both team members,
        // they should have at least "read" access to the phase record.
        
        System.runAs(teamMemberRead) {
            Phase__c ph;
            try {
                ph = Database.query('SELECT Id FROM Phase__c WHERE Id = \'' + phase.Id + '\' and Name = \'XXX My Dummy Project XXX - Phase 1\'');                
            } catch (Exception e) {System.debug('########-' + e);}
            
            System.assertNotEquals(null, ph);
        }

 My assert gets failed. It shows that 'ph' is null. According to me it shouldn't be null. What am I missing here.

bob_buzzardbob_buzzard

Have you asserted that the phase is correctly created after insertion of the project?  E.g. after:

 

// A default phase is always created upon creation of a project.
// So we don't need to create one seperatley.                                 
phase = [SELECT Id FROM Phase__c WHERE Name = 'XXX My Dummy Project XXX - Phase 1' and Project__c = :project.Id];  

System.assertNotEquals(null, phase); 
JaggyJaggy

Hey Bob! thanks for your reply!

 

I did it after your reply. Following assert doesn't get failed.

 

System.assertNotEquals(null, phase); 

 

bob_buzzardbob_buzzard

Cool.  Next thing I'd do is to move the final assert outside the runas, to check that when I'm in the system context I can see the phase.  If that is the case, it would suggest that the sharing settings don't allow the user you are running as to see the phase.

JaggyJaggy

Bob,

 

Yes, outside of System runas I can see phase record but inside it fails.

bob_buzzardbob_buzzard

In that case I'd check the profiles and sharing settings to confirm that user should have visibility.  

JaggyJaggy

Sharing model for Phase is Private

and Team Member profile has all of four CRUD permissions.

 

 

Any help in this regard would be highly appreciated.

bob_buzzardbob_buzzard

If the sharing model is private, then the team members won't have any access to the phase through org wide defaults.  Do you have any sharing rules defined that would open up the access?  If not, then the behaviour is correct.