0

I've designed this apex trigger and test class to create a task each time an email message is sent in Salesforce. I've been successful with bulkifying it by using a list and map collection to locate contacts based on an email address associated with a contact.

trigger EmailToTask on EmailMessage (after insert) {
list<Task> lstTask          = new list<Task>();
map<String,Id> mapEmail     = new map<String,Id>();
map<String,Id> mapWorkEmail = new map<String,Id>();
map<String,Id> mapHomeEmail = new map<String,Id>(); 

for(Contact con: [SELECT Id,Email,npe01__WorkEmail__c,npe01__HomeEmail__c FROM Contact]){
    if(string.isNotBlank(con.Email))
        mapEmail.put(con.Email,con.Id);
    if(string.isNotBlank(con.npe01__WorkEmail__c))
        mapWorkEmail.put(con.npe01__WorkEmail__c,con.Id);
    if(string.isNotBlank(con.npe01__HomeEmail__c))
        mapHomeEmail.put(con.npe01__HomeEmail__c,con.Id);
}

for (EmailMessage e : Trigger.new) {
   if (e.RelatedToId != NULL 
   && (mapEmail <> NULL && !mapEmail.isEmpty()
       || mapWorkEmail <> NULL && !mapWorkEmail.isEmpty()
       || mapHomeEmail <> NULL && !mapHomeEmail.isEmpty())
      ) {
       Task t =  new Task();
       t.ActivityDate  = date.today();
       t.Description   = e.TextBody;
       t.Move_Type__c  = 'Personal Note/Email from Donor';
       t.Priority      = 'Normal';
       t.Status        = 'Completed';
       t.Subject       = e.Subject;
       t.WhatId        = e.RelatedToId;
       if(mapEmail.containsKey(e.ToAddress)){
            t.WhoId = mapEmail.get(e.ToAddress);
       }
       else if(mapWorkEmail.containsKey(e.ToAddress )){
            t.WhoId = mapWorkEmail.get(e.ToAddress);
       }
         else if(mapHomeEmail.containsKey(e.ToAddress )){
            t.WhoId = mapHomeEmail.get(e.ToAddress);
       }       
       lstTask.add(t);
    }
}
if(lstTask <> NULL && !lstTask.isEmpty()){
    insert lstTask;
}}

In addition, I have authored the following test class.

@isTest
 public with sharing class TestEmailTrigger {

@isTest static void test_method_c() {
     Account a = new Account();
     a.Name  = 'Bob Smith Household';
     insert a; 

     Contact c = new Contact();
     c.lastname = 'Smith';
     c.FirstName = 'Bob';
     c.AccountId = a.Id;
     c.npe01__HomeEmail__c = 'bob.test@gmail.com';
     c.npe01__WorkEmail__c = 'bob.test+5@gmail.com';
     c.Email = NULL;
     c.npe01__Preferred_Email__c = 'Work';
     insert c;

    EmailMessage e = new EmailMessage();
    e.BccAddress            = 'reporting@foodcorps.org';
    e.FromAddress           = 'reporting@foodcorps.org';
    e.FromName              = 'Medhanie Habte';
    e.MessageDate           = datetime.now(); 
    e.MessageIdentifier     = '';
    e.Status                = '3';
    e.Subject               = 'test';
    e.TextBody              = 'test';
    e.RelatedToId           = c.AccountId;
    e.ToAddress             = 'bob.test@gmail.com';
    e.ValidatedFromAddress  = 'reporting@foodcorps.org';
    insert e;

   Task t =  new Task();
   t.ActivityDate  = date.today();
   t.Description   = e.TextBody;
   t.Move_Type__c  = 'Personal Note/Email from Donor';
   t.Priority      = 'Normal';
   t.Status        = 'Completed';
   t.Subject       = e.Subject;
   t.WhatId        = e.RelatedToId;
   t.WhoId         = c.Id;
   insert t;
 }

@isTest static void test_method_b() {
     Account a = new Account();
     a.Name  = 'Bob Smith Household';
     insert a; 

     Contact c = new Contact();
     c.lastname = 'Smith';
     c.FirstName = 'Bob';
     c.AccountId = a.Id;
     c.npe01__HomeEmail__c = '';
     c.npe01__WorkEmail__c = 'bob.test+5@gmail.com';
     c.Email = NULL;
     c.npe01__Preferred_Email__c = 'Work';
     insert c;

    EmailMessage e = new EmailMessage();
    e.BccAddress            = 'reporting@foodcorps.org';
    e.FromAddress           = 'reporting@foodcorps.org';
    e.FromName              = 'Medhanie Habte';
    e.MessageDate           = datetime.now(); 
    e.MessageIdentifier     = '';
    e.Status                = '3';
    e.Subject               = 'test';
    e.TextBody              = 'test';
    e.RelatedToId           = c.AccountId;
    e.ToAddress             = 'bob.test+5@gmail.com';
    e.ValidatedFromAddress  = 'reporting@foodcorps.org';
    insert e;

   Task t =  new Task();
   t.ActivityDate  = date.today();
   t.Description   = e.TextBody;
   t.Move_Type__c  = 'Personal Note/Email from Donor';
   t.Priority      = 'Normal';
   t.Status        = 'Completed';
   t.Subject       = e.Subject;
   t.WhatId        = e.RelatedToId;
   t.WhoId         = c.Id;
   insert t;
 }
@isTest static void test_method_d() {
     Account a = new Account();
     a.Name  = 'Bob Smith Household';
     insert a; 

     Contact c = new Contact();
     c.lastname = 'Smith';
     c.FirstName = 'Bob';
     c.AccountId = a.Id;
     c.npe01__HomeEmail__c = 'bob.test+5@gmail.com';
     c.npe01__WorkEmail__c = NULL;
     c.Email = NULL;
     c.npe01__Preferred_Email__c = 'Work';
     insert c;

    EmailMessage e = new EmailMessage();
    e.BccAddress            = 'reporting@foodcorps.org';
    e.FromAddress           = 'reporting@foodcorps.org';
    e.FromName              = 'Medhanie Habte';
    e.MessageDate           = datetime.now(); 
    e.MessageIdentifier     = '';
    e.Status                = '3';
    e.Subject               = 'test';
    e.TextBody              = 'test';
    e.RelatedToId           = c.AccountId;
    e.ToAddress             = 'bob.test+5@gmail.com';
    e.ValidatedFromAddress  = 'reporting@foodcorps.org';
    insert e;

   Task t =  new Task();
   t.ActivityDate  = date.today();
   t.Description   = e.TextBody;
   t.Move_Type__c  = 'Personal Note/Email from Donor';
   t.Priority      = 'Normal';
   t.Status        = 'Completed';
   t.Subject       = e.Subject;
   t.WhatId        = e.RelatedToId;
   t.WhoId         = c.Id;
   insert t;} @isTest static void test_method_e() {
     Account a = new Account();
     a.Name  = 'Bob Smith Household';
     insert a; 

     Contact c = new Contact();
     c.lastname = 'Smith';
     c.FirstName = 'Bob';
     c.AccountId = a.Id;
     c.npe01__HomeEmail__c = 'bob.test@gmail.com';
     c.npe01__WorkEmail__c = 'bob.test+5@gmail.com';
     c.Email = 'bob.test@aoltv.com';
     c.npe01__Preferred_Email__c = 'Work';
     insert c;

    EmailMessage e = new EmailMessage();
    e.BccAddress            = 'reporting@foodcorps.org';
    e.FromAddress           = 'reporting@foodcorps.org';
    e.FromName              = 'Medhanie Habte';
    e.MessageDate           = datetime.now(); 
    e.MessageIdentifier     = '';
    e.Status                = '3';
    e.Subject               = 'test';
    e.TextBody              = 'test';
    e.RelatedToId           = c.AccountId;
    e.ToAddress             = 'bob.test@gmail.com';
    e.ValidatedFromAddress  = 'reporting@foodcorps.org';
    insert e;

   Task t =  new Task();
   t.ActivityDate  = date.today();
   t.Description   = e.TextBody;
   t.Move_Type__c  = 'Personal Note/Email from Donor';
   t.Priority      = 'Normal';
   t.Status        = 'Completed';
   t.Subject       = e.Subject;
   t.WhatId        = e.RelatedToId;
   t.WhoId         = c.Id;
   insert t;}}

Currently this code acheives 90% code coverage, the only are of code that isn't covered is...

           || mapWorkEmail <> NULL && !mapWorkEmail.isEmpty()
       || mapHomeEmail <> NULL && !mapHomeEmail.isEmpty())

As well as t.WhoId = mapWorkEmail.get(e.ToAddress); and t.WhoId = mapEmail.get(e.ToAddress);

Are there any steps I should allow for the the mapWorkEmail and mapHomeEmail variables to be covered. I may be overthinking here but would love to have 100% coverage.

  • 1
    Verifying that your code works as you expect it to work is the most important part of unit testing. It’s also one of the things that Force.com developers commonly neglect. Unit tests that do not verify the results of the code aren’t true unit tests. They are commonly referred to as smoke tests, which aren’t nearly as effective or informative as true unit tests. - How to Write Good Unit Tests – Adrian Larson Jul 5 '17 at 20:20
  • As an aside, lstTask is never null. Also, DML statements on empty lists are allowed. You appear to be suffering from NullPointerException paranoia. NPE is incredibly rare as long as you're aware of what you're doing. It's not necessary to check if something is null if it will never be null. – sfdcfox Jul 5 '17 at 20:26
0

Your lists are never null, so you can simplify your logic. The oddity about the way the system counts "lines" means that you'll need to adjust your if statement to be completely on one line or somehow get to the last condition without triggering any of the prior conditions.

A simple fix could be this:

Boolean map1Empty = mapEmail.isEmpty(),
  map2Empty = mapWorkEmail.isEmpty(),
  map3Empty = mapHomeEmail.isEmpty(),
  createTask = e.RelatedToId != null && 
    !(map1Empty || map2Empty || map3Empty);
if(createTask) { // ...

Or, you might combine all three maps in to a single map, since it probably won't matter (you'll want to test to confirm this).

Or, changing just your test, specify a home email address but not a work or email address (Contact.Email and npe01__WorkEmail__c should both be null).

| improve this answer | |

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.