0

I've created a trigger to update a custom fields on Accounts (Last_Activity_Type__c and Last_Email_Date__c) each time an Email task is completed.

I have it only firing if the task type is Email because when we use the Email to Salesforce function, the whatId is null and doesn't update my custom fields automatically on the Account record.

Here's what I currently have for my trigger, everything works perfectly when I test it on my Sandbox, however, I can't get it to deploy because of the following code coverage error:


Your organization's code coverage is 54%. You need at least 75% coverage to complete this deployment. Also, the following triggers have 0% code coverage. Each trigger must have at least 1% code coverage.

  • updateAccountLastActivity

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATES_DETECTED, You're creating a duplicate record. We recommend you use an existing record instead.: [] Stack Trace: Class.updateAccountLastActivity.TestTaskAccountUpdate: line 12, column 1


Task Trigger: Sandbox Code Coverage: 100% (5/5)

trigger updateAccountLastActivity on Task (after insert, after update) 
{
    List<Id> Triggerids=new List<Id>();

    System.debug('in Trigger 1');
    for(Task t:trigger.new)
    {
       Triggerids.add(t.id);
    }
    classupdateAccountLastActivity.Triggerhelper(Triggerids);
}

Apex Class: Sandbox Code Coverage: 75% (27/36)

public class classupdateAccountLastActivity {

    @future
    public static void Triggerhelper(List<id> TaskId){

    List<Id> accountIds=new List<Id>();
    List<Id> ContactIds=new List<Id>();
    List<Account> UpdateAccounts = new List<Account>();
        List<Task> Tasks = [select Whoid, WhatId, Type, Subject, Status from task where id IN :TaskId];

        for(Task t:Tasks)
    {
        System.debug('task who id and whatid'+ t.whoid + '  ' + t.whatid);
        if(t.Status=='Completed' && t.Type=='Email')
        {
            system.debug('inside loop of task completed');
            if(t.whatId != null)
            {
                //check if the task is associated with an account
                accountIds.add(t.whatId);
            }
        }
        {
            if (t.whoId != null)
            {
                //check if the task is associated with a contact
                ContactIds.add(t.whoid);
            }
        }
    }
    if( accountIds.size() > 0)
    {
        List<Account> accountsToUpdate=[SELECT Id, Last_Activity_Type__c, Last_Email_Date__c FROM Account WHERE Id IN :accountIds];
        For (account a:accountsToUpdate)
        {

        a.Last_Activity_Type__c = 'Email';
        a.Last_Email_Date__c = date.today();

        UpdateAccounts.add(a);
        }



    }
    if(ContactIds.size() > 0)
    {
        System.debug('Testing inside tge loop'+ContactIds );
        List<Contact> listContact = [select id,accountid from contact where id in :ContactIds ];
        Set<id> accId = new Set<ID>();
        for(Contact cont : listContact)
        {
            if(cont.accountid != null)
            {
                accId.add(cont.accountid);
            }   
        }   

        if( accId.size() > 0)
    {
        List<Account> accountsToUpdate=[SELECT Id, Last_Activity_Type__c, Last_Email_Date__c FROM Account WHERE Id IN :accId];
        For (account a:accountsToUpdate)
        {
        a.Last_Activity_Type__c = 'Email';
        a.Last_Email_Date__c = date.today();

        UpdateAccounts.add(a);
        }

        }       
    }

    update UpdateAccounts;

    }

}

Test Class

@istest
public class TestUpdateAccountLastActivity 
{
    static testmethod void TestTaskAccountUpdate()
    {
        User U = [select id from User limit 1];

        Account acct = new Account(Name = 'ABC123 Company', Last_Name__c = 'Test', Email__c = 'test@test.com');
        insert acct;

        contact cont = new contact(Accountid = Acct.id, LastName = 'Test', Email = 'test@test.com');
        insert cont;

        Task t = new Task(Ownerid = U.id, Subject = 'Test', Whoid = cont.id, Whatid = acct.id, Status = 'Completed', Type = 'Email', Priority = 'Normal', Description = 'Test');
        insert t; 
    }
}

Any ideas what could be wrong.. Possibly a simpler way to update the associated Account from completed Tasks while passing the Whoid and Whatid?

Thanks ahead of time!


EDIT: Below are the lines not covered in my Apex Class:

lines 17 & 20:

 if(t.whatId != null)
     {
          //check if the task is associated with an account
          accountIds.add(t.whatId);
     }

lines 33-40:

if( accountIds.size() > 0)
    {
        List<Account> accountsToUpdate=[SELECT Id, Last_Activity_Type__c, Last_Email_Date__c FROM Account WHERE Id IN :accountIds];
        For (account a:accountsToUpdate)
        {

        a.Last_Activity_Type__c = 'Email';
        a.Last_Email_Date__c = date.today();

        UpdateAccounts.add(a);
        }

and line 76:

 }catch(DMLException e){
  • What lines aren't getting coverage? – EricSSH Mar 3 '16 at 16:11
  • updated with lines not covered from Apex Class – AJ47 Mar 3 '16 at 16:35
3

The only thing you're doing in your test method is inserting the records. You're not testing any of the after Update and you have no last activity dates since you're not creating any new email tasks. You need a separate test method for AfterInsert and AfterUpdate to test these two different situations.

Edit

Your test needs to follow the structure below. I'll leave it to you to sort out the details. I highly recommend you locate the Trailhead Module on Test Classes and work your way through it. Me giving you all the code won't help you learn to do it yourself. If you get stuck someplace in particular, come back and post again.

That being said, I don't think you really need the try-catch block. Are there particular errors in your data that you expect to see? You can use other means of handling DML and capturing DML errors. Your method accomplishes little for you. You may as well allow partial success and write the errors to the debug log directly.

@istest
public class TestUpdateAccountLastActivity 
{

    @testSetup static void setup() 
    {
     // Create & insert common test accounts & contacts

    }

    static testmethod void TestTaskInsert()
    {
       // create & insert tasks    

    }

    static testmethod void TestTaskUpdate()
    {
       // create & insert tasks for accounts

       // validate that tasks have been inserted for accounts

       // create more tasks for same accounts

       // validate that new tasks have been inserted for accounts
       // validate that last activity date has new value which matches

    }

    static testmethod void TestCatchBlock()
    {
       // create & insert tasks for accounts

       // validate that tasks have been inserted for accounts

       // create more tasks for same accounts using data that will fail update
       // validate your debug statement and that last activity date doesn't change 
      }

    }
  • Thanks! Possible to help me a bit with editing my current Test Class? I'm a bit over my head when it comes to Apex coding, I got this far mostly from searching similar issues / solutions... thanks again for the reply! – AJ47 Mar 3 '16 at 17:12
  • See my edited response. Additionally, you should be creating lists of accounts, contacts and tasks that you match up to bulkify your testing. Testing a single record isn't sufficient. You also want to assert the expected results at the end of each method. – crmprogdev Mar 3 '16 at 17:52
  • Thanks again! I'll check out that link and take a stab at this using your structure.. I took out the try-catch block as I agree, it's not really needed and not expecting any particular errors – AJ47 Mar 3 '16 at 18:06
  • BTW, you do realize that Your organization's code coverage is 54%. means that you have MANY test classes that don't have sufficient test coverage to allow you to deploy this code don't you? You'll need to increase the coverage so that your org's code coverage, (including this code) is at least 75% before you'll be able to deploy. In essence, there are other classes you'll need to add coverage to in order to deploy this code. – crmprogdev Mar 3 '16 at 18:23
  • Yea, this is my 3rd trigger that I'm trying to deploy, so I'll have to go back and redo the test classes on the other 2, hopefully I'll learn a bit getting this one setup to fix the others. Thanks! – AJ47 Mar 3 '16 at 18:35

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.