Skip to content

Instantly share code, notes, and snippets.

@FishOfPrey
Created June 21, 2018 10:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FishOfPrey/9ef39b32948f23b604c8e8e0ab041c53 to your computer and use it in GitHub Desktop.
Save FishOfPrey/9ef39b32948f23b604c8e8e0ab041c53 to your computer and use it in GitHub Desktop.
public class FishOfPreySettings {
// Normally during testing we want to limit the custom setting to a testing user.
// However, this won't work with anything that depends on $Setup.FishOfPrey_Settings__c.showTheThing__c in a validation rule
// As it will appear as null
private static boolean useTestingUpdateUserCustomSetting {
get {
if(useTestingUpdateUserCustomSetting == null) {
return true;
}
return useTestingUpdateUserCustomSetting;
}
set;
}
/**
* Get a single static instance rather than constantly calling the constructor and any init code.
*/
public static FishOfPreySettings Instance {
get {
if(Instance == null) {
if(Test.isRunningTest() && useTestingUpdateUserCustomSetting) {
Instance = createMock();
} else {
Instance = new FishOfPreySettings();
}
}
return Instance;
}
private set {
Instance = value;
}
}
private FishOfPrey_Settings__c actualSettings;
// Needs to be public so it can be mocked
public FishOfPrey_Settings__c getFishOfPreyCustomSettings() {
if(actualSettings == null) {
actualSettings = FishOfPrey_Settings__c.getInstance();
}
return actualSettings;
}
public void setFishOfPreyCustomSettings(FishOfPrey_Settings__c newSettings) {
actualSettings = newSettings;
}
private boolean fishOfPreySettingsDefined {
get {
return getFishOfPreyCustomSettings() != null;
}
}
public boolean showTheThing {
get {
if(FishOfPreySettingsDefined) {
return getFishOfPreyCustomSettings().showTheThing__c;
}
return true;
}
set {
FishOfPrey_Settings__c fopSessingsDml = fishOfPreyCustomSettingsForUpsert();
fopSessingsDml.showTheThing__c = value;
upsertSettingsChange(fopSessingsDml);
}
}
private FishOfPrey_Settings__c fishOfPreyCustomSettingsForUpsert() {
FishOfPrey_Settings__c fopSessingsDml = getFishOfPreyCustomSettings();
if(fopSessingsDml == null) {
fopSessingsDml = new FishOfPrey_Settings__c();
}
return fopSessingsDml;
}
public void upsertSettingsChange(FishOfPrey_Settings__c fopSessingsDml) {
if(Test.isRunningTest() && useTestingUpdateUserCustomSetting) {
// Few, if any test methods should actually reach this block to avoid contention/locking
//System.assert(false, 'prevent tests modifying Custom Settings');
// Avoid UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record: []
system.runAs(testingUpdateUser())
{
// During testing, reduce scope to active user to reduce chance of DML Exception that would occur
fopSessingsDml.SetupOwnerId = UserInfo.getUserId();
System.debug('upsertSettingsChange() Upserting Settings for ' + fopSessingsDml.SetupOwnerId + ' Email:' + UserInfo.getUserEmail());
upsert fopSessingsDml;
setFishOfPreyCustomSettings(fopSessingsDml);
}
} else {
System.debug('upsertSettingsChange() fopSessingsDml:' + fopSessingsDml);
upsert fopSessingsDml;
}
}
private static User testingUpdateUser() {
string profileName = 'System Administrator';
// Setting the Profile to one that contains 'Administrator' will bypass certain validations rules that check CONTAINS($Profile.Name, "Administrator")
List<Profile> matchingProfiles = [SELECT Id FROM Profile WHERE Name=:profileName];
System.assertEquals(1, matchingProfiles.size(), 'Expecting a single profile for ' + profileName);
Profile p = matchingProfiles[0];
// Try keep to predictable and consistent functions within the test cases.
// Currently needs to be random for Test_RefreshOrderController
string rand = String.valueOf(Math.rint(Math.random() * 10000)) + DateTime.now().getTime(); //'Deterministic';
User u = new User(Alias='testUser', Email='test'+rand+'@example.com',
EmailEncodingKey='UTF-8', LastName='TestUser', LanguageLocaleKey='en_US',
LocaleSidKey='en_US', ProfileId = p.Id,
TimeZoneSidKey='America/Los_Angeles', UserName='fopTest' + rand + '@example.com');
System.debug('testDataSetupUser() UserName: ' + u.UserName);
return u;
}
private static FishOfPreySettings mockSettings;
@TestVisible
private static FishOfPreySettings createMock() {
// Use static instance to avoid creating a new mock with each call
if(mockSettings == null) {
mockSettings = (FishOfPreySettings)Test.createStub(FishOfPreySettings.class, new FishOfPreySettingsMockProvider());
System.debug('FishOfPreySettings.createMock() completed - new');
} else {
System.debug('FishOfPreySettings.createMock() completed - existing');
}
return mockSettings;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment