function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Abhinav GuptaAbhinav Gupta 

Is Apex System.runAs() not resetting the context for CRUD/FLS changes in profile ?

Here is the complete Test class with all comments and required code. To test it one can deploy this to their DE org directly, it has no dependencies.While writing an apex test case I noticed a strange behavior with System.runAs(). My tests were failing incorrectly, because system.runAs() was somehow not resetting the CRUD/FLS context for different profiles across same or different test method executions.

 

Here is the complete Test class with all comments and required code. To test it one can deploy this to their DE org directly, it has no dependencies.

 

@isTest
private class Test_System_RunAs {
 
/*
 This test class has two test methods, i.e.
  1. testWithSysAdmin() executes a FLS check with SYS Admin profile
  2. testWithChatterFree()  executes a FLS check with Chatter Free profile
   
  PROBLEM :
  Both of these methods doesn't execute correctly. 
  The one that executes first sets the profile context via System.runAs()
  and somehow its not reset internally for the second testMethod execution,
  this makes the testMethod executing later fail (as profile permissions mismatch)
  Though if we comment and execute both these testMethods one at a time, they will behave correct.
  So that means each of these testXXX() methods are correct, somehow context is not reset correctly
  when they execute one after another.
   
  QUESTION :
   
  Am I doing something wrong or is this some bug in System.runAs() context, I feel it takes care
  of sharing rules etc, but doesn't enforces the FLS correctly ?
   
*/
 
public static testMethod void testWithSysAdmin() {
  System.runAs(createMockUserForProfile('System Administrator')) {
    // This debug indicates different profiles
    System.debug('ProfileId:' +Userinfo.getProfileId());
    System.assertEquals(true, Account.BillingCity.getDescribe().isUpdateable());
  }          
}
 
public static testMethod void testWithChatterFree() {
  System.runAs(createMockUserForUserLicense('Chatter Free')) {
    // This debug indicates different profiles
    System.debug('ProfileId:' +Userinfo.getProfileId());
    // Chatter Free user has no permission on the Account, so it should be false
    System.assertEquals(false, Account.BillingCity.getDescribe().isUpdateable());
  }          
}
 
static User createMockUserForUserLicense(String licenseName) {
  Profile p = [SELECT Id FROM profile WHERE UserLicense.Name like :licenseName LIMIT 1];
  return createMockUser(p.id);
}
 
static User createMockUserForProfile(String profileName) {
  Profile p = [SELECT Id FROM profile WHERE name like :profileName];
  return createMockUser(p.id);
}
 
static User createMockUser(Id profileId) {
  User u = new User(alias = 'newUser', email='newuser@tgerm.com.test',
  emailencodingkey='UTF-8', lastname='Testing', 
  languagelocalekey='en_US', localesidkey='en_US', profileid = profileId,
  timezonesidkey='America/Los_Angeles', username= System.now().millisecond() + 'newuser@tgerm.com.test');
  insert u;
  return  u; 
}
}

 

Please let me know what's the gap ?

 

I am also discussing the same on my blog here : http://www.tgerm.com/2011/09/apex-systemrunas-different-profiles.html

 

Thanks ! 

Best Answer chosen by Admin (Salesforce Developers) 
spraetzspraetz

Thank you very much for the super detailed reproducer.

 

I was able to reproduce the behavior in my own org, but it appears that this issue is fixed in the Winter '12 release as it passed in an org on the Winter '12 codeline.

 

Since the upgrade is coming so soon, I doubt we'd be able to fix it before Winter '12 is released, but please re-post if you're still seeing the issue after the upgrade. 

All Answers

spraetzspraetz

Thank you very much for the super detailed reproducer.

 

I was able to reproduce the behavior in my own org, but it appears that this issue is fixed in the Winter '12 release as it passed in an org on the Winter '12 codeline.

 

Since the upgrade is coming so soon, I doubt we'd be able to fix it before Winter '12 is released, but please re-post if you're still seeing the issue after the upgrade. 

This was selected as the best answer
Abhinav GuptaAbhinav Gupta

Thanks a lot Ryan, I will try this out in win'12 org.