Salesforce – Unit test generator for profile field accessibility verification by XML

This brief post is a continuation of the prior one and discusses the possibility of generating tests from profile XML(s), rather than using SOQL. Note: This is basically a proof of concept that relies on reading a directory of profile xml files, then parsing the field accessibility values  based on a target Object. The fields gathered from the profile xml, are not exhaustive and thus may not result in passing tests. See the last post for a more accurate solution.

This script “generateProfileUnitTests.py” was created in Python 2.7, it will generate a sample Salesforce unit test named “generateProfileUnitTests.cls

#!/bin/python

"""
python generateProfileUnitTests.py -o 'Contact' -d 'C:\Salesforce\profiles'
"""

import sys
import xml.etree.ElementTree as ET
import argparse
from os import listdir
from os.path import isfile, join
import re

parser = argparse.ArgumentParser()                                               

parser.add_argument("--sobject", "-o", type=str, required=True)
parser.add_argument("--profiledirectorypath", "-d", type=str, required=True)
args = parser.parse_args()

sobject = args.sobject

filetemplatePre = """
@isTest
public class ContactObjectTest {{

    static String writeFieldName = 'PermissionsEdit';

    /**
    object = Contact
    profile = System Administrator
    **/
    private static void runProfileTest(String objectName, String profile, Map<String, Map<String, Boolean>> expectedPerms) {{
        Boolean success = true;
        try 
        {{
            List perms = [SELECT Id, Field, SObjectType, PermissionsRead, PermissionsEdit 
                FROM fieldPermissions 
                WHERE SObjectType = :objectName 
                AND parentId in ( SELECT id 
                    FROM permissionSet 
                    WHERE PermissionSet.Profile.Name = :profile)];
            
            Set nonExpectedFieldsFound = new Set();
            // Go through actual perms and make sure they exist if expected
            for(FieldPermissions perm  : perms) {{
                try {{
                    Map<String, Boolean> expectedPerm = expectedPerms.get(perm.Field);
                    System.assertEquals(expectedPerm.get(writeFieldName), perm.PermissionsEdit,
                        'Permission named ' + perm.Field + ' is ' + perm.PermissionsEdit + ' but expected ' + expectedPerm.get(writeFieldName)
                    );
                    // Should also create a copy and remove (to assert exact fields?)
                }} catch (NullPointerException e) {{
                    nonExpectedFieldsFound.add(perm.Field);
                    // Error is 'Attempt to de-reference a null object'
                    System.debug('Found a field that was not in expected permissions: ' + perm.Field);
                    success = false;
                }}
            }}
            System.assertEquals(0, nonExpectedFieldsFound.size(), 'Found Read only fields in ' + objectName + ' for ' + 
                'profile -- ' + profile + ' -- that were not in expected set: ' + nonExpectedFieldsFound);
        }} 
        catch (Exception e) 
        {{
            System.debug('Failed profile field test ' + e.getMessage());
            success = false;
        }} 
        finally 
        {{
	        System.assert(success);
        }}
    }}

	static Map<String, Boolean> createPerm(String writeName, Boolean value) {{
        Map<String, Boolean> perm = new Map<String, Boolean>();
        perm.put(writeName, value);
        return perm;
    }}

    /****************** PROFILE FIELD ACCESS TESTS *****************/
    {tests}
}}
"""

fileTemplateInsertTest = """
    static testMethod void test{sobject}ReadWriteFields{profileFormatted}Profile() {{
        runProfileTest('{sobject}', '{profile}', {expectedFieldsMethod}());
    }}

"""

fileTemplateInsertExpectedFeilds = """
    static Map<String, Map<String, Boolean>> get{sobject}{profileFormatted}Fields() {{
        Map<String, Map<String, Boolean>> {sobject}Fields = new Map<String, Map<String, Boolean>>();

        {insertExpectedFeild}

        return {sobject}Fields;
    }}

"""

fileTemplateInsertExpectedFeild = """
		{sobject}Fields.put('{fieldName}', createPerm(writeFieldName, {editFieldAccess}));"""

testFile = ''
tests = ''

for f in listdir(args.profiledirectorypath):
	if isfile(join(args.profiledirectorypath, f)):
		tree = ET.parse(join(args.profiledirectorypath, f))
		profileName = f.split('.')[0]

		expectedFeild=''

		for child in tree.getroot():
			if 'fieldPermissions' in child.tag:
				# Get field
				fieldName = child.find('{http://soap.sforce.com/2006/04/metadata}field')
				if sobject + '.' in fieldName.text:
					editable = child.find('{http://soap.sforce.com/2006/04/metadata}editable')
					# readable = child.find('{http://soap.sforce.com/2006/04/metadata}readable')
					expectedFeild+=fileTemplateInsertExpectedFeild.format(sobject=sobject,
																			fieldName=fieldName.text,
																			editFieldAccess=editable.text)
		profileFormatted=re.sub('[^a-zA-Z]+', '', profileName) 
		insertExpectedFields=fileTemplateInsertExpectedFeilds.format(sobject=sobject, 
																profileFormatted=profileFormatted, 
																insertExpectedFeild=expectedFeild)

		insertTest=fileTemplateInsertTest.format(sobject=sobject,
												 profileFormatted=profileFormatted,
												 profile=profileName,
												 expectedFieldsMethod='get' + sobject + profileFormatted + 'Fields')
		tests+=insertExpectedFields
		tests+=insertTest

testFile = filetemplatePre.format(tests=tests)
f = open('generateProfileUnitTests.cls', 'w')
f.write(testFile)
f.close

 

Leave a Reply

Your email address will not be published. Required fields are marked *