Skip to content

Instantly share code, notes, and snippets.

@FishOfPrey
Created September 15, 2026 04:36
Show Gist options
  • Select an option

  • Save FishOfPrey/5b9fa8e11ca3d083dc8b30d60b2fc24c to your computer and use it in GitHub Desktop.

Select an option

Save FishOfPrey/5b9fa8e11ca3d083dc8b30d60b2fc24c to your computer and use it in GitHub Desktop.
Apex Test Helper class for creating users with only a specific set of object and field level access permissions.
/**
* Test helper for creating Users with a defined set of object and field level access permissions.
*
* Each User is created on the standard "Minimum Access - Salesforce" profile, which
* grants almost no data access on its own. Any object and field permissions the test
* needs are then layered on through a dedicated Permission Set.
*
* All SOQL and DML here run explicitly in system mode ("as system" / "WITH SYSTEM_MODE")
* so that fixture setup always succeeds, independent of the running user's own access.
*/
@IsTest
public with sharing class TestUser {
/**
* ObjectPermissions granting create, edit and read (but not delete) on Contact.
* Used by userWithAccess() as a convenient, ready-made permission set.
*/
static ObjectPermissions contactObjectCreateEditReadPermission = new ObjectPermissions(
SobjectType = 'Contact',
PermissionsCreate = true,
PermissionsDelete = false,
PermissionsEdit = true,
PermissionsRead = true
);
/**
* Creates a User that can create, edit and read Contacts, along with read/write
* access to a common set of Contact fields.
*/
public static User userWithAccess() {
return createMinimumAccessUser(contactObjectCreateEditReadPermission, true, null);
}
/**
* Creates a User with no Contact object or field access beyond the bare minimum
* granted by the "Minimum Access - Salesforce" profile.
*/
public static User userWithoutAccess() {
return createMinimumAccessUser(null, false, null);
}
/**
* Creates a User on the "Minimum Access - Salesforce" profile and grants the
* requested permissions through a dedicated Permission Set.
*
* @param contactObjectPermission Object permission to grant on Contact, or null for none.
* @param createReadWriteFieldPermissions When true, grants read/write access to a common set of Contact fields.
* @param additionalFieldPermissions Extra field permissions to grant, or null for none.
* Only applied when createReadWriteFieldPermissions is true.
* @return The inserted User.
*/
public static User createMinimumAccessUser(
ObjectPermissions contactObjectPermission,
Boolean createReadWriteFieldPermissions,
List<FieldPermissions> additionalFieldPermissions
) {
// The built in "Minimum Access - Salesforce" profile grants almost no data access.
List<Profile> profiles = [SELECT Id FROM Profile WHERE Name = 'Minimum Access - Salesforce' WITH SYSTEM_MODE];
Assert.areEqual(1, profiles.size(), 'Failed to find \'Minimum Access - Salesforce\' profile');
Profile minimumAccessProfile = profiles[0];
// Build a unique name so parallel tests do not collide on the User or Permission Set.
String uniqueName = ('U' + Math.random()).replace('.', '');
if (contactObjectPermission != null) {
uniqueName += 'OP';
}
if (createReadWriteFieldPermissions) {
uniqueName += 'RWFP';
}
User testUser = new User(
Alias = 'standt',
Email = uniqueName + '@esapi.com',
EmailEncodingKey = 'UTF-8',
LastName = 'Testing',
LanguageLocaleKey = 'en_US',
LocaleSidKey = 'en_US',
ProfileId = minimumAccessProfile.Id,
TimeZoneSidKey = 'America/Los_Angeles',
UserName = uniqueName + '@esapi.com'
);
insert as system testUser;
// All extra access is granted through this Permission Set rather than the profile.
PermissionSet permissionSet = new PermissionSet(Label = uniqueName + 'mockPs', Name = uniqueName + 'mockPs');
insert as system permissionSet;
if (contactObjectPermission != null) {
// Clone so the shared static template is not mutated with this Permission Set's Id.
ObjectPermissions objectPermission = contactObjectPermission.clone();
objectPermission.ParentId = permissionSet.Id;
insert as system objectPermission;
}
if (createReadWriteFieldPermissions) {
List<FieldPermissions> readWritePerms = createContactFieldPermissions(permissionSet.Id, true, true);
if (additionalFieldPermissions != null) {
for (FieldPermissions fieldPermission : additionalFieldPermissions) {
fieldPermission.ParentId = permissionSet.Id;
readWritePerms.add(fieldPermission);
}
}
insert as system readWritePerms;
}
// Assign the Permission Set so the User picks up its object and field permissions.
PermissionSetAssignment assignment = new PermissionSetAssignment(
PermissionSetId = permissionSet.Id,
AssigneeId = testUser.Id
);
insert as system assignment;
return testUser;
}
/**
* Builds (but does not insert) FieldPermissions for a common set of Contact fields,
* all parented to the given Permission Set.
*
* @param permissionSetId The Permission Set the field permissions belong to.
* @param read Whether to grant read access.
* @param edit Whether to grant edit access.
* @return The unsaved field permissions.
*/
private static List<FieldPermissions> createContactFieldPermissions(Id permissionSetId, Boolean read, Boolean edit) {
String sObjectType = 'Contact';
List<String> fieldNames = new List<String>{
'Account', 'Phone', 'Fax', 'Email', 'MobilePhone', 'HomePhone', 'OtherPhone',
'AssistantPhone', 'Title', 'Department', 'AssistantName', 'LeadSource', 'Birthdate',
'Description', 'ReportsTo', 'OtherAddress', 'MailingAddress'
};
List<FieldPermissions> fieldPerms = new List<FieldPermissions>();
for (String fieldName : fieldNames) {
fieldPerms.add(new FieldPermissions(
SobjectType = sObjectType,
Field = sObjectType + '.' + fieldName,
ParentId = permissionSetId,
PermissionsRead = read,
PermissionsEdit = edit
));
}
return fieldPerms;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment