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
DavisTMDavisTM 

Trailhead Transaction Security Module Apex Test Class Error

I'm doing the Transaction Security Module on Trailhead. and at the final stage "Explore Custom Transaction Security Policies" the test class below is provided. I get the following error when I attempt to sace it.

Error: Compile Error: Invalid type: MyDataLoaderLeadExportCondition at line 18 column 5

Line 18 has this code: 
MyDataLoaderLeadExportCondition dataLoaderLeadExportCondition = new MyDataLoaderLeadExportCondition();

Are you able to assist me with correcting the error?
/**
 * Test for default MyDataLoaderLeadExportCondition provided by Salesforce
 * 
*/
@isTest
public class MyDataLoaderLeadExportConditionTest {
    /*
     * Test to check if policy gets triggered when user exports 750 Leads
    */
  public static testMethod void testLeadExportTriggered() {
    Map<String, String> eventMap = getEventMap(String.valueOf(750));
    Organization org = getOrganization();
    User user = createUser();
      
    TxnSecurity.Event e = createTransactionSecurityEvent(org, user, eventMap) ;
    /* We are unit testing a PolicyCondition that triggers
       when an event is generated due to high NumberOfRecords */
    MyDataLoaderLeadExportCondition dataLoaderLeadExportCondition = new MyDataLoaderLeadExportCondition();
    /* Assert that the condition is triggered */
    System.assertEquals(true, dataLoaderLeadExportCondition.evaluate(e));
   }
    /*
     * Test to check if policy doesn't get triggered when user exports 200 Leads
    */
  public static testMethod void testLeadExportNotTriggered() {
    Map<String, String> eventMap = getEventMap(String.valueOf(200));
    Organization org = getOrganization();
    User user = createUser();
       
    TxnSecurity.Event e = createTransactionSecurityEvent(org, user, eventMap) ;
    /* We are unit testing a PolicyCondition that does not trigger
       an event due to low NumberOfRecords  */
    MyDataLoaderLeadExportCondition dataLoaderLeadExportCondition = new MyDataLoaderLeadExportCondition();
      
    /* Assert that the condition is NOT triggered */
    System.assertEquals(false, dataLoaderLeadExportCondition.evaluate(e));
  }
    /*
     * Create an example user
     */
    private static User createUser(){
        Profile p = [select id from profile where name='System Administrator'];
        String ourSysAdminString = p.Id; 
        
        User u = new User(alias = 'test', email='user@salesforce.com',
            emailencodingkey='UTF-8', lastname='TestLastname', languagelocalekey='en_US',
            localesidkey='en_US', profileid = p.Id, country='United States',
            timezonesidkey='America/Los_Angeles', username=generateRandomUsername(7));
        insert u;
        return u;
    }
    /**
     * Generates a random username of the form “[random]@[random].com”, where the 
     * length of the random string is the given Integer argument. For example, with 
     * an argument of 3, the following random username may be produced: 
     * “ajZ@ajZ.com”.
     */ 
    private static String generateRandomUsername(Integer len) {
        final String chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
        String randStr = '';
        while (randStr.length() < len) {
           Integer idx = Math.mod(Math.abs(Crypto.getRandomInteger()), chars.length());
           randStr += chars.substring(idx, idx+1);
        }
        return randStr + '@' + randStr + '.com'; 
    }

    /*
     * Returns current organization
     */
    private static Organization getOrganization(){
        return [SELECT id, Name FROM Organization];
    }
      
    /*
     * Adds NumberOfRecords and example ExecutionTime
     */ 
    private static Map<String, String> getEventMap(String numberOfRecords){
        Map<String, String> eventMap = new Map<String, String>();
        eventMap.put('NumberOfRecords', numberOfRecords);
        eventMap.put('ExecutionTime', '30');
        eventMap.put('EntityName', 'Lead');
        return eventMap;
    }
    
    /*
     * Create a TxnSecurity.Event instance
     */ 
    private static TxnSecurity.Event createTransactionSecurityEvent(Organization org, User user, Map<String, String> eventMap){
        TxnSecurity.Event e = new TxnSecurity.Event(
             org.Id /* organizationId */,
             user.Id /* userId */,
             'Lead' /* entityName */ ,
             'DataExport' /* action */,
             'Lead' /* resourceType */,
             '000000000000000' /* entityId */,
              Datetime.newInstance(2016, 9, 22) /* timeStamp */,
              eventMap /* data - Map containing information about the event */ );
        return e;
    }
}

 
Best Answer chosen by DavisTM
ApuroopApuroop
In quick find > type Transaction Security Policies > Enable the Transaction Security Policies > Click DataLoaderLeadExportCondition > Copy the whole class > Create a new class with the name MyDataLoaderLeadExportCondition > Paste copied class here and make sure the class' name is MyDataLoaderLeadExportCondition.

Now try saving the test class.

Here's my code:
global class MyDataLoaderLeadExportCondition implements TxnSecurity.PolicyCondition {
  public boolean evaluate(TxnSecurity.Event e) {
    // The event data is a Map<String, String>.
    // We need to call the valueOf() method on appropriate data types to use them in our logic.
    Integer numberOfRecords = Integer.valueOf(e.data.get('NumberOfRecords'));
    Long executionTimeMillis = Long.valueOf(e.data.get('ExecutionTime'));
    String entityName = e.data.get('EntityName');

    // Trigger the policy only for an export on leads, where we are downloading
    // more than 2000 records or it took more than 1 second (1000ms).
    if('Lead'.equals(entityName)){
      if(numberOfRecords > 2000 || executionTimeMillis > 1000){
        return true;
      }
    }

    // For everything else don't trigger the policy.
    return false;
  }

}

All Answers

ApuroopApuroop
In quick find > type Transaction Security Policies > Enable the Transaction Security Policies > Click DataLoaderLeadExportCondition > Copy the whole class > Create a new class with the name MyDataLoaderLeadExportCondition > Paste copied class here and make sure the class' name is MyDataLoaderLeadExportCondition.

Now try saving the test class.

Here's my code:
global class MyDataLoaderLeadExportCondition implements TxnSecurity.PolicyCondition {
  public boolean evaluate(TxnSecurity.Event e) {
    // The event data is a Map<String, String>.
    // We need to call the valueOf() method on appropriate data types to use them in our logic.
    Integer numberOfRecords = Integer.valueOf(e.data.get('NumberOfRecords'));
    Long executionTimeMillis = Long.valueOf(e.data.get('ExecutionTime'));
    String entityName = e.data.get('EntityName');

    // Trigger the policy only for an export on leads, where we are downloading
    // more than 2000 records or it took more than 1 second (1000ms).
    if('Lead'.equals(entityName)){
      if(numberOfRecords > 2000 || executionTimeMillis > 1000){
        return true;
      }
    }

    // For everything else don't trigger the policy.
    return false;
  }

}
This was selected as the best answer
DavisTMDavisTM
Many thanks for your prompt response, and the solution Apuroop!

Best,
{!Ty}