6

This is scaled down code from SF's own examples on how to find dupe email addresses. I have purpose commented out the Alert for now. There is a more elaborate trigger (that also works in Sandbox) but this keeps things simpler. The problem is in deploying to PRODUCTION (well over 100k records) and errors gotten there...

trigger leadDuplicatePreventer on Lead(before insert) {

    Map<String, Lead> leadMap = new Map<String, Lead>();
    //Create a map of the new leads, excluding any dupes

    for (Lead lead : System.Trigger.new) {
        //Make sure the new leads don't have any duplicates of each other  
        if (lead.Email != null && leadMap.containsKey(lead.Email)) {
            // commented to avoid users being alerted at this time     lead.Email.addError('Another new lead has the same email address.');
        } else {
            leadMap.put(lead.Email, lead);
        }
    }

    //Eliminate any new leads whose emails are already in the system
    for (Lead lead : [SELECT Email FROM Lead WHERE Email IN :leadMap.KeySet()]) {
        Lead newLead = leadMap.get(lead.Email);
        // commented to avoid users being alerted at this time             newLead.Email.addError('A lead with this email address already exists.');
    }
}

This trigger works fine in Sandbox. I have 100s of thousands of records in Production so I have to worry about errors pertaining to queries that are too large. I'm down to a couple errors that I'm just not clear on. In the CLASS below, it is complaining about an Assertion Fail at the first System.assert(false). If I comment out that TRY section, it just complains at the NEXT assert.

  • Failure Message: "System.AssertException: Assertion Failed", Failure Stack Trace: "Class.leadDupePreventerTests_v2.testLeadDupPreventer: line 51, column 1"

There are several lines commented out throughout the class referencing "Email" as well - it will not even work in Sandbox with those active. (sigh) This code must be OLD because it now won't work out of the box from SF's Dev site into Enterprise Release 12 environment.

Help? :-/ Thanks.

public class leadDupePreventerTests_v2{
    static testMethod void testLeadDupPreventer() {

      // First make sure there are no leads already in the system  
      // that have the email addresses used for testing  

      Set<String> testEmailAddress = new Set<String>();
      testEmailAddress.add('[email protected]');
      testEmailAddress.add('[email protected]');
      testEmailAddress.add('[email protected]');
      testEmailAddress.add('[email protected]');
      testEmailAddress.add('[email protected]');
      System.assert([SELECT count() FROM Lead
                     WHERE Email IN :testEmailAddress] == 0);

      // Seed the database with some leads, and make sure they can  
      // be bulk inserted successfully.  

      Lead lead1 = new Lead(LastName='Test1', Company='Test1 Inc.',
                            Email='[email protected]');
      Lead lead2 = new Lead(LastName='Test2', Company='Test2 Inc.',
                            Email='[email protected]');
      Lead lead3 = new Lead(LastName='Test3', Company='Test3 Inc.',
                            Email='[email protected]');
      Lead[] leads = new Lead[] {lead1, lead2, lead3};
      insert leads;

      // Now make sure that some of these leads can be changed and  
      // then bulk updated successfully. Note that lead1 is not  
      // being changed, but is still being passed to the update  
      // call. This should be OK.  

      lead2.Email = '[email protected]';
      lead3.Email = '[email protected]';
      update leads;

      // Make sure that single row lead duplication prevention works  
      // on insert.  

      Lead dup1 = new Lead(LastName='Test1Dup',
                           Company='Test1Dup Inc.',
                           Email='[email protected]');
      try {
         insert dup1;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 1);
         System.assert(e.getDmlIndex(0) == 0);
         System.assert(e.getDmlFields(0).size() == 1);
         System.assert(e.getDmlFields(0)[0] == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'A lead with this email address already exists.') > -1);
      }

      // Make sure that single row lead duplication prevention works  
      // on update.  

      dup1 = new Lead(Id = lead1.Id, LastName='Test1Dup',
                      Company='Test1Dup Inc.',
                      Email='[email protected]');
      try {
         update dup1;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 1);
         System.assert(e.getDmlIndex(0) == 0);
         System.assert(e.getDmlFields(0).size() == 1);
//         System.assert(e.getDmlFields(0)[0] == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'A lead with this email address already exists.') > -1);
        }

      // Make sure that bulk lead duplication prevention works on  
      // insert. Note that the first item being inserted is fine,  
      // but the second and third items are duplicates. Note also  
      // that since at least one record insert fails, the entire  
      // transaction will be rolled back.  

      dup1 = new Lead(LastName='Test1Dup', Company='Test1Dup Inc.',
                      Email='[email protected]');
      Lead dup2 = new Lead(LastName='Test2Dup',
                           Company='Test2Dup Inc.',
                           Email='[email protected]');
      Lead dup3 = new Lead(LastName='Test3Dup',
                           Company='Test3Dup Inc.',
                           Email='[email protected]');
      Lead[] dups = new Lead[] {dup1, dup2, dup3};
      try {
         insert dups;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 2);
         System.assert(e.getDmlIndex(0) == 1);
         System.assert(e.getDmlFields(0).size() == 1);
//         System.assert(e.getDmlFields(0)[0] == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'A lead with this email address already exists.') > -1);
         System.assert(e.getDmlIndex(1) == 2);
         System.assert(e.getDmlFields(1).size() == 1);
//         System.assert(e.getDmlFields(1)[0] == 'Email');
         System.assert(e.getDmlMessage(1).indexOf(
            'A lead with this email address already exists.') > -1);
      }

      // Make sure that bulk lead duplication prevention works on  
      // update. Note that the first item being updated is fine,  
      // because the email address is new, and the second item is  
      // also fine, but in this case it's because the email  
      // address doesn't change. The third case is flagged as an  
      // error because it is a duplicate of the email address of the  
      // first lead's value in the database, even though that value  
      // is changing in this same update call. It would be an  
      // interesting exercise to rewrite the trigger to allow this  
      // case. Note also that since at least one record update  
      // fails, the entire transaction will be rolled back.  

      dup1 = new Lead(Id=lead1.Id, Email='[email protected]');
      dup2 = new Lead(Id=lead2.Id, Email='[email protected]');
      dup3 = new Lead(Id=lead3.Id, Email='[email protected]');
      dups = new Lead[] {dup1, dup2, dup3};
      try {
         update dups;
         System.assert(false);
      } catch (DmlException e) {
         System.debug(e.getNumDml());
         System.debug(e.getDmlMessage(0));
         System.assert(e.getNumDml() == 1);
         System.assert(e.getDmlIndex(0) == 2);
         System.assert(e.getDmlFields(0).size() == 1);
//         System.assert(e.getDmlFields(0)[0] == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'A lead with this email address already exists.') > -1);
        }

      // Make sure that duplicates in the submission are caught when  
      // inserting leads. Note that this test also catches an  
      // attempt to insert a lead where there is an existing  
      // duplicate.  

      dup1 = new Lead(LastName='Test1Dup', Company='Test1Dup Inc.',
                      Email='[email protected]');
      dup2 = new Lead(LastName='Test2Dup', Company='Test2Dup Inc.',
                      Email='[email protected]');
      dup3 = new Lead(LastName='Test3Dup', Company='Test3Dup Inc.',
                      Email='[email protected]');
      dups = new Lead[] {dup1, dup2, dup3};
      try {
         insert dups;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 2);
         System.assert(e.getDmlIndex(0) == 1);
         System.assert(e.getDmlFields(0).size() == 1);
//         System.assert(e.getDmlFields(0)[0] == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'Another new lead has the same email address.') > -1);
         System.assert(e.getDmlIndex(1) == 2);
         System.assert(e.getDmlFields(1).size() == 1);
//         System.assert(e.getDmlFields(1)[0] == 'Email');
         System.assert(e.getDmlMessage(1).indexOf(
            'A lead with this email address already exists.') > -1);
      }

      // Make sure that duplicates in the submission are caught when  
      // updating leads. Note that this test also catches an attempt  
      // to update a lead where there is an existing duplicate.  

      dup1 = new Lead(Id=lead1.Id, Email='[email protected]');
      dup2 = new Lead(Id=lead2.Id, Email='[email protected]');
      dup3 = new Lead(Id=lead3.Id, Email='[email protected]');
      dups = new Lead[] {dup1, dup2, dup3};
      try {
         update dups;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 2);
         System.assert(e.getDmlIndex(0) == 1);
         System.assert(e.getDmlFields(0).size() == 1);
//         System.assert(e.getDmlFields(0)[0] == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'Another new lead has the same email address.') > -1);
         System.assert(e.getDmlIndex(1) == 2);
         System.assert(e.getDmlFields(1).size() == 1);
//         System.assert(e.getDmlFields(1)[0] == 'Email');
         System.assert(e.getDmlMessage(1).indexOf(
            'A lead with this email address already exists.') > -1);
      }
   }
}
2
  • 1
    Just to be clear, are the addError() calls commented when you run the test? As far as I can see, that first assert(false) would fail, since there's no error being set on the dupe insertion.
    – metadaddy
    Commented Sep 6, 2012 at 14:55
  • This code is as-is, no extra commenting being done. :-/ I'm not clear on how to set the error (I'm about a level 1.5 out of 10 right now in the Apex world, learning the hard way).
    – AMM
    Commented Sep 6, 2012 at 15:08

1 Answer 1

7

You can't comment out the errors or the test won't work.

 try {
        insert dup1;
        System.assert(false);
     } catch (DmlException e) {
       ....
     }

That line is currently working as it's written. It does the insert, but since there is no error in the trigger, it continues to the next line which explicitly states to fail the assertion (because it shouldn't have gotten there). The execution path the test case is intending is that it will do the insert, which will throw an exception, skipping the assert and going in to the exception block.

You'll have to either uncomment the error code in the trigger or find some other way to throw an exception when a duplicate is detected from the trigger in order for this test to work.

The main problem is that without either of those, the trigger doesn't really do anything right now - it detects a duplicate but it doesn't try to stop it.

It sounds like what you want is some way to stop the insert from happening but without alerting the user. I'm not sure this is possible since it usually takes them to the lead's detail page after insert - where would it take them now? They'd probably also be confused if they tried to navigate back to that lead.

9
  • Yes - this scaled down version does nothing, no prob.
    – AMM
    Commented Sep 6, 2012 at 15:21
  • (sorry, didn't know C/R submitted).... As for error throwing.. can someone give an example of this? Or is it a huge ordeal? :-/
    – AMM
    Commented Sep 6, 2012 at 15:22
  • here is the URL to the original code being ripped off: salesforce.com/docs/developer/cookbook/Content/apex_dedupe.htm
    – AMM
    Commented Sep 6, 2012 at 15:30
  • 1
    @AMM - the addError() call is documented here. I'm not sure why you're commenting it out. The test won't pass if the errors are not thrown. In fact, the test is working perfectly right now - it's telling you that the trigger is not preventing duplicates.
    – metadaddy
    Commented Sep 6, 2012 at 17:17
  • 2
    Yes - right now all the System.assert() calls in the test method will fail, since the trigger is not raising the expected error. You will need to rework the test method to match the changes to the trigger.
    – metadaddy
    Commented Sep 6, 2012 at 18:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .