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
Katie ChristensenKatie Christensen 

Code Coverage on Lead Round Robin

Looking for some assistance with code coverage for a Lead Round robin trigger. The code coverage is approximately 45% so looking for help in increasing it so I can deploy to production.

Thanks in advance!

Apex Class

@isTest
private class TestMethodClsLeads1 {

    static testMethod void myTest1() {

        // This code runs as the system user

       User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {


       //*****Create Queue 
       
       Group testGroup = new Group ();
       testGroup.Name = 'TestQueue';
       testGroup.Type = 'Queue';
       insert testGroup;
       
       QueueSObject testQueue = new QueueSObject();
       testQueue.QueueId = testGroup.id;
       testQueue.SObjectType = 'Lead';
       insert testQueue;

       // Second Queue       
       Group testGroup2 = new Group ();
       testGroup2.Name = 'TestQueue2';
       testGroup2.Type = 'Queue';
       insert testGroup2;
       
       QueueSObject testQueue2 = new QueueSObject();
       testQueue2.QueueId = testGroup2.id;
       testQueue2.SObjectType = 'Lead';
       insert testQueue2;


       test.starttest();
        
        //Run test

        //Assign Lead with out any Assignment Groups
        Lead c1 = new Lead (Lastname='testLead', Company='TestCompany', TempOwnerID__c=testGroup2.id, OwnerID=thisUser.id); //TempOwnerID__c=testGroup2.id,  
        insert c1;
        update c1;
        
        
        //Create Assignment Group
        Assignment_Group_Name__c ag1 = new Assignment_Group_Name__c (Name='TestAG', Type__c = 'Lead');
        insert ag1;

         
        //Add bad queue name
        Assignment_Group_Queues__c agqBad = new Assignment_Group_Queues__c(name='Bad Queue',Assignment_Group_Name__c = ag1.id );

        try {
            insert agqBad; 
        } catch (DmlException e){
             System.assert(e.getMessage().contains('CUSTOM_VALIDATION_EXCEPTION'), e.getMessage()); 
        
        } //catch

        test.stoptest();
        
    }
    }
    static testMethod void myTest2() {

        // This code runs as the system user

        User u1;

        try{
          u1 = [select Id from User WHERE IsActive=True AND Profile.Name = 'System Administrator'  LIMIT 1];
        } catch (QueryException qe){

        List<User> users = [SELECT Id, Profile.PermissionsModifyAllData FROM User WHERE IsActive = true LIMIT 1000];

        for(User u : users){
            if(u.Profile.PermissionsModifyAllData = true){
              u1 = u;
              break;
        }
        }

        }

        System.debug(u1);

       //*****Create Queue 
       
       Group testGroup = new Group ();
       testGroup.Name = 'TestQueue';
       testGroup.Type = 'Queue';
       insert testGroup;
       
       QueueSObject testQueue = new QueueSObject();
       testQueue.QueueId = testGroup.id;
       testQueue.SObjectType = 'Lead';
       insert testQueue;

       // Second Queue       
       Group testGroup2 = new Group ();
       testGroup2.Name = 'TestQueue2';
       testGroup2.Type = 'Queue';
       insert testGroup2;
       
       QueueSObject testQueue2 = new QueueSObject();
       testQueue2.QueueId = testGroup2.id;
       testQueue2.SObjectType = 'Lead';
       insert testQueue2;


       test.starttest();
        
        //Run test
        
        //Create Assignment Group
        Assignment_Group_Name__c ag1 = new Assignment_Group_Name__c (Name='TestAG', Type__c = 'Lead');
        insert ag1;        

        //Add Good Queue to Assignment Group
        Assignment_Group_Queues__c agq1 = new Assignment_Group_Queues__c(name=testGroup.Name ,Assignment_Group_Name__c = ag1.id );
        insert agq1;
        
        
        //Add User to Assignment Groups Users
        Assignment_Groups__c agu1 = new Assignment_Groups__c (User__c = u1.id, Active__c='True', Group_Name__c = ag1.id, Last_Assignment__c = datetime.valueOf('2009-01-01 21:13:24') );
        insert agu1;

        Lead c2 = new Lead (Lastname='testLead', Status='New', Company='TestCompany',TempOwnerID__c=testGroup2.id , OwnerID=testGroup.id); //Set owner ID to Queue
        insert c2;
        update c2;        

        test.stoptest();
        
    }

    static testMethod void myTest3() {

        // This code runs as the system user

        User u1;

        try{
          u1 = [select Id from User WHERE IsActive=True AND Profile.Name = 'System Administrator'  LIMIT 1];
        } catch (QueryException qe){

        List<User> users = [SELECT Id, Profile.PermissionsModifyAllData FROM User WHERE IsActive = true LIMIT 1000];

        for(User u : users){
            if(u.Profile.PermissionsModifyAllData = true){
              u1 = u;
              break;
        }
        }

        }

        System.debug(u1);
        
        User u2;

        try{
          u2 = [select Id from User WHERE IsActive=True AND Profile.Name = 'LiveOps: SaaS Account Management'  LIMIT 1];
        } catch (QueryException qe){
//should run an error test here like above.              
        }


        System.debug(u2);
        


       //*****Create Queue 
       
       Group testGroup = new Group ();
       testGroup.Name = 'TestQueue';
       testGroup.Type = 'Queue';
       insert testGroup;
       
       QueueSObject testQueue = new QueueSObject();
       testQueue.QueueId = testGroup.id;
       testQueue.SObjectType = 'Lead';
       insert testQueue;

       test.starttest();
        
        //Run test        
        
        //Create Assignment Group
        Assignment_Group_Name__c ag1 = new Assignment_Group_Name__c (Name='TestAG', Type__c = 'Lead');
        insert ag1;        

        //Add Good Queue to Assignment Group
        Assignment_Group_Queues__c agq1 = new Assignment_Group_Queues__c(name=testGroup.Name ,Assignment_Group_Name__c = ag1.id );
        insert agq1;
        
         //Add User to Assignment Groups Users
        Assignment_Groups__c agu1 = new Assignment_Groups__c (User__c = u1.id, Active__c='True', Group_Name__c = ag1.id, Last_Assignment__c = datetime.valueOf('2009-01-01 21:13:24') );
        insert agu1;   

        //Add User to Assignment Groups Users
        Assignment_Groups__c agu2 = new Assignment_Groups__c (User__c = u2.id, Active__c='True', Group_Name__c = ag1.id, Last_Assignment__c = datetime.valueOf('2010-01-01 21:13:24') );
        insert agu2;   
        
        Lead c2 = new Lead (Lastname='testLead', Status='New', Company='TestCompany',OwnerID=testGroup.id); //Set owner ID to Queue
        insert c2;
        update c2;
                
        Lead c3 = new Lead (Lastname='testLead2', Status='New', Company='TestCompany2', TempOwnerID__c=testGroup.id , OwnerID=testGroup.id); //Set owner ID to Queue
        insert c3;
        update c3; 
        
        Lead c4 = new Lead (Lastname='testLead3', Status='New', Company='TestCompany3', TempOwnerID__c=testGroup.id , OwnerID=testGroup.id); //Set owner ID to Queue
        insert c4;
        update c4;       
        
        test.stoptest();
        
    }

    static testMethod void myTest4() {

        // This code runs as the system user

        User u1;

        try{
          u1 = [select Id from User WHERE IsActive=True AND Profile.Name = 'System Administrator'  LIMIT 1];
        } catch (QueryException qe){

        List<User> users = [SELECT Id, Profile.PermissionsModifyAllData FROM User WHERE IsActive = true LIMIT 1000];

        for(User u : users){
            if(u.Profile.PermissionsModifyAllData = true){
              u1 = u;
              break;
        }
        }

        }

        System.debug(u1);

       //*****Create Queue 
       
       Group testGroup = new Group ();
       testGroup.Name = 'TestQueue';
       testGroup.Type = 'Queue';
       insert testGroup;
       
       QueueSObject testQueue = new QueueSObject();
       testQueue.QueueId = testGroup.id;
       testQueue.SObjectType = 'Lead';
       insert testQueue;
      

       test.starttest();
        
        //Run test

        //Create Assignment Group
        Assignment_Group_Name__c ag1 = new Assignment_Group_Name__c (Name='TestAG', Type__c = 'Lead');
        insert ag1;        

        //Add Good Queue to Assignment Group
        Assignment_Group_Queues__c agq1 = new Assignment_Group_Queues__c(name=testGroup.Name ,Assignment_Group_Name__c = ag1.id );
        insert agq1;
        
          //Test for AG-Queues already assigned to another Assignment Group -- trying to assign a group with a name that already exists.. repeats code above.
        Assignment_Group_Queues__c agq2 = new Assignment_Group_Queues__c(name=testGroup.Name,Assignment_Group_Name__c = ag1.id );
        try {
            insert agq2;
        } catch (DmlException e){
             System.assert(e.getMessage().contains('CUSTOM_VALIDATION_EXCEPTION'), e.getMessage()); 
        } //catch

        test.stoptest();
        
    }
}
Apex Trigger
trigger leadRoundRobin on Lead (before insert, before update) {
 //
    //Check if assignment owner has changed
    //
    Map<Integer,Id> queueIds = new Map<Integer,Id>();   //Trigger index --> Queue ID
    
    Integer idx = 0;
    for (Lead l : Trigger.new)
    {
        if(Trigger.isUpdate) {  
            if(l.OwnerId <> Trigger.oldMap.get(l.id).OwnerId) {
                if (l.TempOwnerId__c == 'SKIP') {
                    Trigger.new[idx].TempOwnerId__c = '';
                } else {
                    queueIds.put(idx, l.OwnerId);
                }
            }           
        }else {
            queueIds.put(idx, l.OwnerId);
        }   
        idx++;
    }
    System.debug('>>>>>queueIds: '+queueIds);
    if (queueIds.isEmpty()) return;
    
    //
    //Find active Assignment Group for Queue
    //
    Map<Integer,Id> asgnGroupNameIds = new Map<Integer,Id>();   //Trigger index --> Assignment_Group_Name ID
    Map<Id,Assignment_Group_Queues__c> asgnGroupQueues = new Map<Id,Assignment_Group_Queues__c>(); //Queue ID --> Assignment Group Queues
    
    for(Assignment_Group_Queues__c[] agq : [SELECT Assignment_Group_Name__c, QueueId__c
                                          FROM Assignment_Group_Queues__c 
                                          WHERE QueueId__c in :queueIds.values()
                                          AND Active__c = 'True'])
    {
        for (Integer i = 0; i < agq.size() ; i++) {
            asgnGroupQueues.put(agq[i].QueueId__c, agq[i]);
        }                                           
    }
    System.debug('>>>>>asgnGroupQueues: '+asgnGroupQueues); 
    if (asgnGroupQueues.isEmpty()) return;

    for (Integer i : queueIds.keySet()) {
        Assignment_Group_Queues__c agq = asgnGroupQueues.get(queueIds.get(i));
        
        if (agq <> null) {
            asgnGroupNameIds.put(i, agq.Assignment_Group_Name__c);
        }
        //else no active assignment group queue error
    }
    System.debug('>>>>>asgnGroupNameIds: '+asgnGroupNameIds);
    if (asgnGroupNameIds.isEmpty()) return;
    
    //
    //Determine next valid user in Queue/Assignment Group for round robin
    //User with earliest last assignment date wins.
    //
    Map<Id,Assignment_Groups__c[]> asgnGroups = new Map<Id,Assignment_Groups__c[]>(); // Assignment Group Name ID --> User ID
    for(Assignment_Groups__c[] ags : [SELECT Group_Name__c, User__c, Last_Assignment__c, Millisecond__c 
                                   FROM Assignment_Groups__c 
                                   WHERE Group_Name__c in :asgnGroupNameIds.values() 
                                   AND Active__c = 'True' AND User_Active__c = 'True'
                                   ORDER BY Last_Assignment__c, Millisecond__c])
    {
        if (ags.size()>0) {
            asgnGroups.put(ags[0].Group_Name__c, ags);
        }
    }
    System.debug('>>>>>asgnGroups: '+asgnGroups);   
    if (asgnGroups.isEmpty()) return;

    Map<Id,Assignment_Groups__c> updateAssignmentGroups = new Map<Id,Assignment_Groups__c>();
    Map<Id, datetime> latestAGDateTime = new Map<Id,datetime>();
    idx = 0;    
    for (Integer i : queueIds.keySet())
    {
        Assignment_Groups__c[] ags = asgnGroups.get(asgnGroupNameIds.get(i));
        if (ags.size()>0)
        {   
            //Choose next user in line if user ID has already been used but not committed in this trigger batch 
            Assignment_Groups__c ag = ags[math.mod(idx, ags.size())];
                
            //Assign User to Lead as the new owner
            System.debug('>>>>>Owner changed for Lead ' + Trigger.new[i].Id + ' from '+Trigger.new[i].OwnerId+' to '+ ag.User__c);
            Trigger.new[i].OwnerId = ag.User__c;    
            Trigger.new[i].TempOwnerId__c = '';  // don't assign back in an endless loop

            //Set last assignment datetime
            datetime now = datetime.now();
            ag.Last_Assignment__c = now;
            ag.Millisecond__c = now.millisecondGMT();
            
            //update only latest Assignment Groups per ID
            if (latestAGDateTime.containsKey(ag.id)) {
                if(latestAGDateTime.get(ag.id) < now) {
                    updateAssignmentGroups.put(ag.id, ag);
                    latestAGDateTime.put(ag.id, now);
                }
            } else {
                updateAssignmentGroups.put(ag.id, ag);
                latestAGDateTime.put(ag.id,now);
            }
            
            idx++;
        }
    }
    //Map --> List/Array for DML update
    List<Assignment_Groups__c> updateAG = new List<Assignment_Groups__c>();
    for (Id agId : updateAssignmentGroups.keySet()) {
        updateAG.add(updateAssignmentGroups.get(agId));
    }

    System.debug('>>>>>Update Assignment Groups: '+updateAG);   
    
    //
    //Update last assignment for Assignment Group in batch
    //
    if (updateAG.size()>0) {
        try {
            update updateAG;
        } catch (Exception e){
            for (Integer i : queueIds.keySet())
            {
                Trigger.new[i].addError('ERROR: Could not update Assignment Group records ' + ' DETAIL: '+e.getMessage());  
            }
        }
    }
}


 
pconpcon
Looking over your tests, you are missing several "vectors" into your code.  For example, you have not tests that cover if the TempOwnerId__c == 'SKIP'.  Without spending a lot of time learning all of the parts of your system and trying to parse through all of your test code, I can give you some pointers to start off with.
  • I would try to reduce the overall size (if possible) of each of your test methods and try to make them as succinct as possible.
  • I would also rename each of your test methods to describe what is being tested.
  • I would move all of your object creation (or at least most of it) into a TestUtils class [1] that generates your test data
  • I would add System.asserts to your tests to verify that you are getting the appropriate data back
  • I would remove any try/catches from your tests so that if something fails you know exactly what caused it and that the failure doesn't get eaten an blamed on the class you are testing.
I would also read over this post that talks about testing strategies [2].

[1] http://pcon.github.io/presentations/testing/#testutils-get-set
[2] http://blog.deadlypenguin.com/blog/testing/strategies/