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
Cam Evans 2Cam Evans 2 

Coverage for Milestone Completion Trigger

I have minimal Salesforce development experience and I am struggling with getting a test class built to cover 2 triggers.

In the following Salesforce help article there are 2 triggers, 1 to auto-complete a milestone when an email is sent to the case contact, and a second to complete a milestone when the case is marked complete.
https://help.salesforce.com/articleView?id=entitlements_milestones_trigger.htm&type=5 (http://https://help.salesforce.com/articleView?id=entitlements_milestones_trigger.htm&type=5)
There is also a util class and test class for the until. Everything works great in my DEV sandbox; however, I can't promote to production as I don't have min 75% code coverage. I don't have any other custom APEX in my org. Below are the 2 triggers, any assistance with a test class would be much appreciated.

Case object trigger;
trigger CompleteResolutionTimeMilestone on Case (after update) {
if (UserInfo.getUserType() == 'Standard'){
    DateTime completionDate = System.now(); 
        List<Id> updateCases = new List<Id>();
        for (Case c : Trigger.new){
                if (((c.isClosed == true)||(c.Status == 'Closed'))&&((c.SlaStartDate 
                    <= completionDate)&&(c.SlaExitDate == null)))
    updateCases.add(c.Id);
    }
if (updateCases.isEmpty() == false)
    milestoneUtils.completeMilestone(updateCases, 'Case Resolved', completionDate);
}

email message object trigger;
trigger CompleteFirstResponseEmail on EmailMessage (after insert) {
if (UserInfo.getUserType() == 'Standard'){
    DateTime completionDate = System.now();
    Map<Id, String> emIds = new Map<Id, String>();
    for (EmailMessage em : Trigger.new){
        if(em.Incoming == false)
            emIds.put(em.ParentId, em.ToAddress);
    }
    if (emIds.isEmpty() == false){
        Set <Id> emCaseIds = new Set<Id>();
        emCaseIds = emIds.keySet();
            List<Case> caseList = [Select c.Id, c.ContactId, c.Contact.Email,
                c.OwnerId, c.Status,
                c.EntitlementId,
                c.SlaStartDate, c.SlaExitDate
                From Case c where c.Id IN :emCaseIds];
        if (caseList.isEmpty()==false){
                List<Id> updateCases = new List<Id>();
                for (Case caseObj:caseList) {
                    if ((emIds.get(caseObj.Id)==caseObj.Contact.Email)&&
                        (caseObj.EntitlementId != null)&&
                        (caseObj.SlaStartDate <= completionDate)&&
                        (caseObj.SlaStartDate != null)&&
                        (caseObj.SlaExitDate == null))
                            updateCases.add(caseObj.Id);
                }
                if(updateCases.isEmpty() == false)
                    milestoneUtils.completeMilestone(updateCases, 
                            'First Response', completionDate);
        }
    }
}

 
Best Answer chosen by Cam Evans 2
Andrew GAndrew G
for the case trigger, something like:
@IsTest
public class CaseResolutionMilestone_Test{
    @IsTest
    static void unitTest_1(){
        List<String>DupCase =new List<String>();
        Account testAccount = new Account(Name='Test Company Name123');
        insert testAccount;

        Contact con  = new Contact(LastName='Testcont' ,Email='sss@test.com', AccountId=testAccount.Id);
        insert con;

        Case caseRec = new Case();
        caseRec.AccountId = testAccount.Id;
        caseRec.ContactId=con.Id;

        insert caseRec;
        Test.startTest();
        caseRec.Status = 'Closed';
        caseRec.SlaStartDate = DateTime.Now().addDays(-1);
        update caseRec;
        Test.stopTest();
//some sort of assertion dependent on what the Utils class is doing
//perhaps
        List<Case> cases = [SELECT Id, Status, CompletionDate FROM Case WHERE Id = :caseRec.Id;
        System.assertEquals(System.Today(),cases[0].CompletionDate);
    }
}

as for the Email message
 
@IsTest
public class CompleteFirstResponseEmail_Test{
    @IsTest
    static void unitTest_1(){
        List<String>DupCase =new List<String>();
        Account testAccount = new Account(Name='Test Company Name123');
        insert testAccount;

        Contact con  = new Contact(LastName='Testcont' ,Email='sss@test.com', AccountId=testAccount.Id);
        insert con;

        Case caseRec = new Case();
        caseRec.AccountId = testAccount.Id;
        caseRec.ContactId=con.Id;
        insert caseRec;


        Test.startTest();
        
        EmailMessage[] newEmail = new EmailMessage[0];
        newEmail.add(new EmailMessage(FromAddress = 'sss@test.com', Incoming = True, ToAddress= '<someInboundemailaddress>', Subject = 'Test email', TextBody = 'Text Body', ParentId = caseRec.Id)); 
        insert newEmail;

        Test.stopTest();
//some sort of assertion dependent on what the Utils class is doing
//perhaps
        List<Case> cases = [SELECT Id, Status, CompletionDate FROM Case WHERE Id = :caseRec.Id;
        System.assertEquals(System.Today(),cases[0].CompletionDate);
    }
}

hope the above points you in the right direction

regards

Andrew

p.s. all code provided as-is and uncompiled.
 

All Answers

Andrew GAndrew G
for the case trigger, something like:
@IsTest
public class CaseResolutionMilestone_Test{
    @IsTest
    static void unitTest_1(){
        List<String>DupCase =new List<String>();
        Account testAccount = new Account(Name='Test Company Name123');
        insert testAccount;

        Contact con  = new Contact(LastName='Testcont' ,Email='sss@test.com', AccountId=testAccount.Id);
        insert con;

        Case caseRec = new Case();
        caseRec.AccountId = testAccount.Id;
        caseRec.ContactId=con.Id;

        insert caseRec;
        Test.startTest();
        caseRec.Status = 'Closed';
        caseRec.SlaStartDate = DateTime.Now().addDays(-1);
        update caseRec;
        Test.stopTest();
//some sort of assertion dependent on what the Utils class is doing
//perhaps
        List<Case> cases = [SELECT Id, Status, CompletionDate FROM Case WHERE Id = :caseRec.Id;
        System.assertEquals(System.Today(),cases[0].CompletionDate);
    }
}

as for the Email message
 
@IsTest
public class CompleteFirstResponseEmail_Test{
    @IsTest
    static void unitTest_1(){
        List<String>DupCase =new List<String>();
        Account testAccount = new Account(Name='Test Company Name123');
        insert testAccount;

        Contact con  = new Contact(LastName='Testcont' ,Email='sss@test.com', AccountId=testAccount.Id);
        insert con;

        Case caseRec = new Case();
        caseRec.AccountId = testAccount.Id;
        caseRec.ContactId=con.Id;
        insert caseRec;


        Test.startTest();
        
        EmailMessage[] newEmail = new EmailMessage[0];
        newEmail.add(new EmailMessage(FromAddress = 'sss@test.com', Incoming = True, ToAddress= '<someInboundemailaddress>', Subject = 'Test email', TextBody = 'Text Body', ParentId = caseRec.Id)); 
        insert newEmail;

        Test.stopTest();
//some sort of assertion dependent on what the Utils class is doing
//perhaps
        List<Case> cases = [SELECT Id, Status, CompletionDate FROM Case WHERE Id = :caseRec.Id;
        System.assertEquals(System.Today(),cases[0].CompletionDate);
    }
}

hope the above points you in the right direction

regards

Andrew

p.s. all code provided as-is and uncompiled.
 
This was selected as the best answer
Cam Evans 2Cam Evans 2
Thanks, Andrew! That pointed me in the right direction. A couple of small modifications and I got 100% coverage.