1

I'm trying to create an update on the account object when someone creates or updates task. I'm not getting enough test code coverage, and I'm also receiving a recursive error when running the test. Any help is tremendously appreciated.

Trigger

trigger UpdateAccountActivityDescription on Task (after insert,after update) {
  system.debug(trigger.new);
  set<String> setAccountIds = new set<String>();
  map<Id, Id> mapContactsIds = new map<Id, Id>();

  // INSERT OR UPDATE
  if(trigger.isdelete != true){

    for( Integer i=0; i < trigger.new.size(); i++) {
      if(trigger.new[i].WhatId != null){
          setAccountIds.add(trigger.new[i].WhatId);
      }
      // contact and leads
      if(trigger.new[i].WhoId != null) {
          mapContactsIds.put(trigger.new[i].WhoId, null);
      }
    }
    // get only contacts
    id thisAccountId = null;
    list<Contact> lstContacts = new list<Contact>([SELECT AccountId FROM Contact WHERE id IN :mapContactsIds.keySet()]);
    for(Contact cont : lstContacts) {
      // account Id of contact to map
      if(cont.AccountId != null) {
        setAccountIds.add(cont.AccountId);
        mapContactsIds.remove(cont.Id);
        mapContactsIds.put(cont.Id, cont.AccountId);
      }
    }
    system.debug(lstContacts);
    system.debug(mapContactsIds);

    map<Id, Account> mapAccount = new map<Id, Account>([Select Id, Recent_Activity_Notes__c, Recent_Activity_Date__c, Recent_Activity_Owner__c From Account WHERE id IN :setAccountIds]);
    DateTime nowDateTime = DateTime.now();
    for( Integer i=0; i < trigger.new.size(); i++){
      if (mapAccount.get(trigger.new[i].WhatId) != null) { // it task if for account
        mapAccount.get(trigger.new[i].WhatId).Recent_Activity_Notes__c = trigger.new[i].Description;
        mapAccount.get(trigger.new[i].WhatId).Recent_Activity_Owner__c = UserInfo.getName();
        mapAccount.get(trigger.new[i].WhatId).Recent_Activity_Date__c = trigger.new[i].CreatedDate;
      } else if (mapAccount.get(mapContactsIds.get(trigger.new[i].WhoId)) != null) { // if task is for contact
        mapAccount.get(mapContactsIds.get(trigger.new[i].WhoId)).Recent_Activity_Notes__c = trigger.new[i].Description;
        mapAccount.get(mapContactsIds.get(trigger.new[i].WhoId)).Recent_Activity_Owner__c = UserInfo.getName();
        mapAccount.get(mapContactsIds.get(trigger.new[i].WhoId)).Recent_Activity_Date__c = trigger.new[i].CreatedDate;
      }
    }
    update mapAccount.values();
  }
}

Test Class

@isTest
public class UpdateAccountActivityDecscription_Test {
 static testMethod void myUnitTest() {

      integer contactsCount = 2;

      list<Contact> lstContact = new list<Contact>();

        Account objAcc = new Account(Name='Test');
        insert objAcc;

        Account objAcc2 = new Account(Name='Test Account 2');
        insert objAcc2;

    for(integer i = 0; i < contactsCount; i++){
            Contact objContact = new Contact();
            objContact.AccountId = objAcc2.id;
            objContact.FirstName = 'ContactFirstName'+string.valueOf(i);
            objContact.LastName = 'ContactLastName'+string.valueOf(i);
            objContact.Email = 'Adress'+string.valueOf(i)+'@Adress.com';
            objContact.Title = 'ContactTitile'+string.valueOf(i);
            objContact.MailingStreet = '456 garrik st'+string.valueOf(i);
            objContact.MailingCity = 'Portsmount';
            objContact.MailingState = 'Georgia';
            objContact.mailingPostalCode = '3457348';
            objContact.MailingCountry = 'USA';
            lstContact.add(objContact);
        }
        insert lstContact;

        string test_desc = 'test description';
        string test_desc2 = 'test description2';
        string test_desc3 = 'test description3';
        string test_desc4 = 'test description4';


        list<Task> lstTasks = new list<Task>();

        //=================

        Test.startTest();

        Task newTask = new Task(Subject='First Meeting', Description=test_desc, status='In Progress', priority='Normal', WhatId=objAcc.Id);
        insert newTask;

        Account testAcc = [SELECT Recent_Activity_Notes__c, Recent_Activity_Date__c FROM Account WHERE id = :objAcc.Id];
        system.assertEquals(test_desc, testAcc.Recent_Activity_Notes__c);


        // create new task => Recent_Activity_Notes__c should change
        newTask = new Task(Subject='First New Meeting', Description=test_desc2, status='Not Started', priority='Low', WhatId=objAcc.Id);
        insert newTask;

        testAcc = [SELECT Recent_Activity_Notes__c FROM Account WHERE id = :objAcc.Id];
        system.assertEquals(test_desc2, testAcc.Recent_Activity_Notes__c);

    newTask = new Task(Subject='First Meeting', Description=test_desc3, status = 'In Progress', priority = 'Normal', WhoId=lstContact[0].Id, WhatId=objAcc2.Id);
        insert newTask;

        testAcc = [SELECT Recent_Activity_Notes__c FROM Account WHERE id = :objAcc2.Id];
        system.assertEquals(test_desc3, testAcc.Recent_Activity_Notes__c);

        Task newTaskOnlyWhoID = new Task(Subject='First New Meeting', Description = test_desc4, status = 'Not Started', priority = 'Low', WhoId=lstContact[1].Id);
        insert newTaskOnlyWhoID;

        //list<Contact> testContact = [select Description from Contact where Description =: test_desc4];
        //system.assertEquals(1, testContact.size());

        Test.stopTest();
    }
}

Trigger Throwing Error

    trigger UpdateContactActivityDescription on Task (after insert, after update) {
 if(Trigger.isAfter) {
        if(Trigger.isUpdate){
        for(Task t : Trigger.new) {
    // We need to update associated Opportunity Fields with Fields from Case.
    Contact cont = [SELECT Id, Recent_Activity_Notes__c, Recent_Activity_Date__c, Recent_Activity_Owner__c From Contact WHERE Id = :t.WhoId ];

    cont.Recent_Activity_Notes__c = t.Description;
    cont.Recent_Activity_Date__c = t.CreatedDate;

    update cont;
    }
    }
}
}

Actual Error

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, UpdateContactActivityDescription: execution of AfterUpdate

caused by: System.QueryException: List has no rows for assignment to SObject

Trigger.UpdateContactActivityDescription: line 6, column 1: []

  • We likely need the Contact Triggers as well since your Task trigger updates it. We may potentially need more after looking through it. – dphil Nov 20 '14 at 20:51
  • I edited my answer. The portion under the Edit code shows what you need to change in your UpdateContactActivityDescription trigger. – dphil Nov 20 '14 at 21:54
0

Recrusive trigger errors usually occur when one trigger causes another trigger to fire, which in turn causes the original trigger to fire again. This trigger causes the Account Trigger to fire since it does an update to Accounts. Your Account trigger likely causes another trigger to fire. It could be this same Task one or another Trigger. You need to figure out where this is happening. You left out 2 important points to your questions.

1) What line does the error occur on? Don't just tell us the line number, show us since we don't know what line is which.

2) What code isn't covered?

Your question should be separated into 2 separate questions.

1) Get help to fix your error first.

2) After your error is fixed then focus on code coverage. There is a chance that fixing your error will boost code coverage as well but always take care of errors first.

EDIT:

It appears that your UpdateContactActivityDescription trigger is querying for a Contact even when it's not linked to one.

trigger UpdateContactActivityDescription on Task (after insert, after update) {
  if(Trigger.isAfter) {
    if(Trigger.isUpdate){
      for(Task t : Trigger.new) {
        // We need to update associated Opportunity Fields with Fields from Case.
        List<Contact> contacts = [SELECT Id, Recent_Activity_Notes__c, Recent_Activity_Date__c, Recent_Activity_Owner__c From Contact WHERE Id = :t.WhoId ];

        if (!contacts.isEmpty())
        {
          Contact cont = contacts[0];
          cont.Recent_Activity_Notes__c = t.Description;
          cont.Recent_Activity_Date__c = t.CreatedDate;

          update cont;
        }
      }
    }
  }
}

This should fix your current error but keep in mind that you should also bulkify this trigger as well or you will run into more issues down the road.

  • It looks like the error is occurring in another trigger – Andrew Sims Nov 20 '14 at 20:24
  • @AndrewSims Now you need to figure out what calls that other trigger and what that other Trigger calls and begin walking through your code – dphil Nov 20 '14 at 20:25
  • the trigger is calling the contact object for the exact same function as the account trigger. – Andrew Sims Nov 20 '14 at 20:27
  • @AndrewSims Please don't post code in Comments. It's extremely hard to read. It's better as an edit to your post and might even be a good idea to rework your entire question to focus specifically on the error for now. – dphil Nov 20 '14 at 20:27
  • @AndrewSims Also, it sounds like your Contact Triggers and Account Triggers are relevant because any of those 3 could be the culprits or even another trigger that is called by the Contact/Account Triggers. – dphil Nov 20 '14 at 20:29

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.