0

The following Apex Class Test is running properly in different SBXs inside 5 minutes, however I have another SBX that it´s also a Partial Copy that is running successfully inside 3 hours.

Is always stucked in this method "testInactiveUserDeactivator"

Is there any suggestion to solve it?

@isTest
public class MX_InactiveUserDeactivator_TEST {
    @testSetup 
    public static void insertUsers() {
        List <User> usersToAdd = new List<User>();
        Id p = [select id from profile where name='Standard User'].id;
        Id sp = [select id from profile where name='System Administrator'].id;

        usersToAdd.add(new User(Firstname = 'Antonio Admin', Lastname = 'Test', Email='antonioadmin@bco.com', isActive = true, Alias = 'afmn1', CommunityNickname =  'adm1',emailencodingkey='UTF-8', 
                                ServiceCountryCode__c='FRA',  languagelocalekey='es', localesidkey='es', country='United States', timezonesidkey='America/Los_Angeles', username='antonioAdmin@noemail.com.comm', profileid = sp));
        
        usersToAdd.add(new User(Firstname = 'Antonio', Lastname = 'Test', Email='antonio@bco.com', isActive = true, Alias = 'a1', CommunityNickname =  'a1',emailencodingkey='UTF-8', 
                                ServiceCountryCode__c='FRA',  languagelocalekey='es', localesidkey='es', country='United States', timezonesidkey='America/Los_Angeles', username='tester@noemail.com.comm', profileid = p));
        
        usersToAdd.add(new User(Firstname = 'Manolo', Lastname = 'Test', Email='manolo@bco.com', isActive = true, Alias = 'm1', CommunityNickname =  'm1',emailencodingkey='UTF-8', 
                                ServiceCountryCode__c='FRA',  languagelocalekey='es', localesidkey='es', country='United States', timezonesidkey='America/Los_Angeles', username='manolo@noemail.com.comm', profileid = p));
        
        usersToAdd.add(new User(Firstname = 'Pepe', Lastname = 'Test', Email='pepe@bco.com', isActive = false, Alias = 'a1', CommunityNickname =  'p1',emailencodingkey='UTF-8', 
                                ServiceCountryCode__c='FRA',  languagelocalekey='es', localesidkey='es', country='United States', timezonesidkey='America/Los_Angeles', username='pepe@noemail.com.comm', profileid = p));
        
         usersToAdd.add(new User(Firstname = 'Palomo', Lastname = 'Test', Email='palomo@bco.com', isActive = true, Alias = 'pa1', CommunityNickname =  'pa1',emailencodingkey='UTF-8', 
                                ServiceCountryCode__c='FRA',  languagelocalekey='es', localesidkey='es', country='United States', timezonesidkey='America/Los_Angeles', username='palomo@noemail.com.comm', profileid = p, WhiteListFromDeactivation__c = true ));
        
        insert usersToAdd;
        
        List <ServiceResource> serviceResources = new List<ServiceResource>();
        serviceResources.add(new serviceResource(IsActive = true, Name = 'SR1', RelatedRecordId = usersToAdd[1].Id ));
        serviceResources.add(new serviceResource(IsActive = true, Name = 'SR2', RelatedRecordId = usersToAdd[4].Id ));
        insert serviceResources;
    }
    
    @isTest
    public static void testInactiveUserDeactivator(){
        List <String> userNames = new List<String>{'palomo@noemail.com.comm','pepe@noemail.com.comm', 'manolo@noemail.com.comm', 'tester@noemail.com.comm', 'antonioAdmin@noemail.com.comm'};     
        Map<Id, User> inactiveUsers = new Map<Id, User>([SELECT Id FROM User WHERE isActive = false AND username IN :userNames]);
        List<User> usersToDeactivate = [SELECT Id FROM User WHERE isActive = true AND username IN :userNames AND WhiteListFromDeactivation__c= false];
        Test.setCreatedDate(usersToDeactivate.get(0).Id, System.now().addMonths(-8));
        Test.setCreatedDate(usersToDeactivate.get(1).Id, System.now().addMonths(-8));
        Test.setCreatedDate(usersToDeactivate.get(2).Id, System.now().addMonths(-8));
        
        String CRON_EXP = '0 0 0 15 3 ? 2022';
        Test.startTest();
            String jobId = System.schedule('ScheduledApexTest', CRON_EXP, new MX_InactiveUserDeactivator());
             List <User> users = MX_Utils.getUsersWithExpirationLogin();
            System.enqueueJob(new SPT_AsyncServiceResourceDeactivator(users));
            System.enqueueJob(new SPT_AsyncUserDeactivator(users));
        Test.stopTest();
        System.assert([SELECT COUNT() FROM ServiceResource WHERE isActive = true] == 1);
        System.assert([SELECT COUNT() FROM USER WHERE isActive = false AND username IN :userNames] == inactiveUsers.size() + 3);
        
    }
    
     @isTest
    public static void testAsyncEmailSender(){
        List <User> users = MX_Utils.getUsersWithExpirationLogin();
        Test.startTest();
        System.enqueueJob(new SPT_AsyncUserDeactivator.AsyncEmailSender(users, new List<User>{users[0]}, new Map<Id, String>()));
        Test.stopTest();
    }
 
    
}

I've tried to comment the CRON EXPRESION, but it took over than two hours, so the issues still remain.

Here there is the method "getUsersWithExpirationLogin()" for the MX_Utils class.

public class MX_Utils {
    /*
    * @author: lidl es
    * @description:  Method to deactivate the users without loggin s. After Deactivating, an email is sended to SF support Competence Center with the results.   
    */
    public static List<User> getUsersWithExpirationLogin(){
        List <User> expiredUsers = new List<User>();
        try{
            Map<Id,Profile> profileIds = new Map<id,profile>([SELECT Id,UserLicenseId FROM Profile where UserLicenseId  in
                         (SELECT Id FROM UserLicense where name IN ('Salesforce','Salesforce Platform'))]); 

            Map<String,User_Decativation__mdt> mapUserDecativation = new Map<String,User_Decativation__mdt>();

            for (User_Decativation__mdt userDeactivation : [Select CountryCodeException__c,MasterLabel, DaysDeactivation__c FROM User_Decativation__mdt]){
                mapUserDecativation.put(userDeactivation.MasterLabel.toUppercase(),userDeactivation);
            }
            
            User_Decativation__mdt defaultUserDeactivation = mapUserDecativation.get('DEU');

            for (User  u : [SELECT Id, Username, Name, isActive,ServiceCountryCode__c,lastLoginDate, CreatedDate, countryCode FROM User 
                                    WHERE WhiteListFromDeactivation__c = false AND
                                    isActive=true AND Profile.id in:profileIds.Keyset()]) {
                if (mapUserDecativation.containsKey(u.ServiceCountryCode__c)) {
                    User_Decativation__mdt userDeactivation = mapUserDecativation.get(u.ServiceCountryCode__c);
                    Integer days = Integer.valueOf(userDeactivation.DaysDeactivation__c) *-1;
                    
                    if ( (u.lastLoginDate <=System.now().addDays(days)|| (u.lastLoginDate == null && u.CreatedDate <= System.now().addDays(days))) &&
                        u.ServiceCountryCode__c != userDeactivation.CountryCodeException__c) {
                            expiredUsers.add(u);
                    }
                }else {
                    Integer days = Integer.valueOf(defaultUserDeactivation.DaysDeactivation__c) *-1;
                    if ( (u.lastLoginDate <= System.now().addDays(days)|| (u.lastLoginDate == null && u.CreatedDate <= System.now().addDays(days))) &&
                        u.ServiceCountryCode__c != defaultUserDeactivation.CountryCodeException__c) {
                        expiredUsers.add(u);
                    }
                }                
            } 
        }catch(Exception e){
            throw e;
        }
        return expiredUsers;
    }
    
    public static void sendEmail(String htmlBody, String[]  toAddresses){
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(toAddresses);
        mail.setSenderDisplayName('Salesforce Support');
        mail.setSubject('Users automatically deactivated ');
        mail.setHtmlBody(htmlBody);
        Messaging.SendEmailResult[] resultEmail = (Test.isRunningTest()) ?
            new List<Messaging.SendEmailResult>() : Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });    
    }
    
}
4
  • User object is something which can be queried from Database also. Your this method MX_Utils.getUsersWithExpirationLogin(); may return a huge value depending on the org, so its better to restrict the logic to 1 or 2 users if the logic is running from a Test class. Nov 5 '21 at 11:17
  • Hi Nagendra. I think I should do it using SOQL, but I don't know if it´s the best approach. Could you help me? I have still a basic level from Apex... Sorry :) Nov 5 '21 at 13:08
  • Can you share whats there in getUsersWithExpirationLogin method? Nov 8 '21 at 4:10
  • Hi! I've been added the method! Thank you!! Nov 8 '21 at 9:51
0

You can convert your query to this:

Map<Id,Profile> profileIds = new Map<id,profile>([SELECT Id,UserLicenseId FROM Profile where UserLicenseId  in
(SELECT Id FROM UserLicense where name IN ('Salesforce','Salesforce Platform'))]);
Set<Id> ids = profileIds.keySet();
String strQuery = 'SELECT Id, Username, Name, isActive,LastLoginDate, CreatedDate FROM User WHERE  isActive=true AND Profile.id in :ids';
if(Test.isRunningTest()){
    strQuery = strQuery + ' LIMIT 2 ';
}
for (User  u : Database.query(strQuery)) {
    
}

To restrict the user list when running from Test context.

3
  • First, thank you for your help!! Well I added the SOQL in the "MX_Utils" Apex Class as you suggested me, but still have issues with the long-running. The following tests have long execution times. To improve each test's performance, be sure to follow Apex and SOQL best practices. To learn more, see Performance Tuning Resources for Long-Running Tests MX_InactiveUserDeactivator_TEST.testInactiveUserDeactivator 13 min 34 sec Nov 9 '21 at 16:23
  • Reduce the LIMIT to 1 and then try to check, also you may need to tune SPT_AsyncServiceResourceDeactivator and SPT_AsyncUserDeactivator too as there might be queries there too. Nov 9 '21 at 16:27
  • Hi again! Could you write the code, please? For this second part (SPT_AsyncServiceResourceDeactivator and SPT_AsyncUserDeactivator) I'm a little lost in this case. Nov 9 '21 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.