+ Start a Discussion
Liz Gibbons 16Liz Gibbons 16 

Test class for Email Trigger

Hello,

I am working on writing a test class for an email trigger. The trigger fires when a Community user self-registers. I'm struggling to get the test class to test this though. 

Here's the trigger:
trigger LearnerWelcomeEmail on Contact (after insert) {
    
    //Prepare to send welcome emails
    List<Messaging.SingleEmailMessage> welcome = new List<Messaging.SingleEmailMessage>();
    
    for (Contact learner : Trigger.New){
        if(trigger.isInsert && learner.Self_Registered__c == true)
        {
           Messaging.SingleEmailMessage learnerEmail = new Messaging.SingleEmailMessage();
                List<String> sendTo = new List<String>();
                sendTo.add(learner.Email);
                learnerEmail.setToAddresses(sendTo);
                learnerEmail.setReplyTo('info@digitalonramps.com');
                learnerEmail.setSenderDisplayName('Digital On-Ramps');
                learnerEmail.setTemplateId('00X17000000DnrL');
                learnerEmail.setTargetObjectId(learner.Id);

            
            welcome.add(learnerEmail);
            }
    }
    if(welcome.size()>0){
        Messaging.sendEmail(welcome);
    }
}

And here's the test class I have:
@isTest public class TestLearnerWelcome {
    @isTest public static void emailUser(){
        Id p = [SELECT id FROM Profile WHERE name = 'Learner Profile Community User'].id;
        
        Account acct = new Account(name= 'TestAcct');
        insert acct;
        
        Contact con = new Contact(LastName = 'Learner', AccountId = acct.Id, email = 'learner@test.edu');
        insert con;
        
        User u = new User(alias = 'learner1', email = 'learner@test.edu', emailencodingkey='UTF-8', lastname='Learner', languagelocalekey='en_US',
                localesidkey='en_US', profileid = p, country='United States',IsActive =true,
                ContactId = con.Id,
                timezonesidkey='America/Los_Angeles', username='tester@noemail.com');
        insert u;
        
                
        System.runAs(u){
 
        }

        
    }

}

I currently have 28% coverage. Any insight would be greatly appreciated!
James LoghryJames Loghry
The primary issue is that your trigger is handling contact inserts only, and it appears that Self_Register__c is not being set on insert of the contact record.  Is that a formula field or does it get set via a trigger on the User record?  If the latter, you'll need to insert the user first.  My suggestion would be to use the Site.createExternalUser() instead of handling the insert of the contact / user record separately.  If that doesn't work, then you need to somehow set the Self_Registered__c field on the contact to kick off your logic at any rate.
Abhishek BansalAbhishek Bansal
Hi Liz,

Please use the below test class :
@isTest(seeAllData = false)
private class TestLearnerWelcome {
    static testMethod void emailUser() {
       Account acct = new Account(name= 'TestAcct');
       insert acct;
       
       Contact testContact = new Contact();
       testContact.LastName = 'Test Contact';
       testContact.AccountId = acct.id;
       testContact.Self_Registered__c = true;
       
       Test.startTest();
       insert testContact;
       Test.stopTest();
    }
}
The If condition in your trigger is executing when "Self_Registered__c" field is set to true so in your test class you must set it as true.
Please use the above test class and let me know if you have any issue.

Thanks,
Abhishek
Liz Gibbons 16Liz Gibbons 16
Hi James,

Using Site.createExternalUser() seems to have me on the right path (the class is passing), but I'm now at 0% coverage. Self_Registered__c is a formula field that looks at the Created By user. Here's what I have now:
@isTest public class TestLearnerWelcome {
    @isTest public static void emailUser(){
        Id p = [SELECT id FROM Profile WHERE name = 'Learner Profile Community User'].id;
            
        Account acct = new Account(name= 'TestAcct');
        insert acct;
        
        User u = new User(alias = 'learner1', email = 'learner@test.edu', emailencodingkey='UTF-8', lastname='Learner', languagelocalekey='en_US',
                localesidkey='en_US', profileid = p, country='United States',IsActive =true,
                timezonesidkey='America/Los_Angeles', username='tester@noemail.com');
        
        Site.createExternalUser(u, acct.Id);
        

        
    }

}

 
Liz Gibbons 16Liz Gibbons 16
Hi Abhishek,

Because Self_Registered__c is a formula field, I cannot set a value in the class.  I am getting the above test class (using createExternalUser) to pass, but the code coverage for the trigger remains at 0%.
Abhishek BansalAbhishek Bansal
Hi Liz,

Please try with the below test class :
@isTest public class TestLearnerWelcome {
    @isTest public static void emailUser(){
        Id p = [SELECT id FROM Profile WHERE name = 'Learner Profile Community User'].id;
        
        Account acct = new Account(name= 'TestAcct');
        insert acct;
        
        Contact con = new Contact(LastName = 'Learner', AccountId = acct.Id, email = 'learner@test.edu');
        //insert con;
        
        User u = new User(alias = 'learner1', email = 'learner@test.edu', emailencodingkey='UTF-8', lastname='Learner', languagelocalekey='en_US',
                localesidkey='en_US', profileid = p, country='United States',IsActive =true,
                timezonesidkey='America/Los_Angeles', username='tester@noemail.com');
        insert u;
        
                
        System.runAs(u){
 			insert con;
        }

        
    }

}

Let me know if you still have any issue with this class.

Thanks,
Abhishek
Liz Gibbons 16Liz Gibbons 16
Hi Abhishek,

I just ran your class. It failed and got an error that I got yesterday trying a similar class. 

Error Message: System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, Cannot create a portal user without contact: [ContactId]

Stack Trace: Class.TestLearnerWelcome.emailUser: line 15, column 1

Thanks,
Liz
Abhishek BansalAbhishek Bansal
Hi Liz,

You can give a try to the below test class :
@isTest public class TestLearnerWelcome {
    @isTest public static void emailUser(){
        Id p = [SELECT id FROM Profile WHERE name = 'Learner Profile Community User'].id;
        
        Account acct = new Account(name= 'TestAcct');
        insert acct;
        
        Contact con = new Contact(LastName = 'Learner', AccountId = acct.Id, email = 'learner@test.edu');
        //insert con;
        
        User u = new User(alias = 'learner1', email = 'learner@test.edu', emailencodingkey='UTF-8', lastname='Learner', languagelocalekey='en_US',
                localesidkey='en_US', profileid = p, country='United States',IsActive =true,
                ContactId = con.Id,
                timezonesidkey='America/Los_Angeles', username='tester@noemail.com');
        insert u;
        
        delete con; 
        System.runAs(u){
 			insert con;
        }

        
    }

}

I am not 100% sure that it will run successfully or not but you can give a try to this.
Let mer know if you any issue with it.

Thanks,
Abhishek
Liz Gibbons 16Liz Gibbons 16
Hi Abhishek,

Same error as before. I think the issue lies in how our users are registering. I think I may need to talk with our development partners to figure this out.

Best,
Liz
James LoghryJames Loghry
Liz, is there a reason you have a separate formula field for tracking self registered users?  Salesforce has this field out of the box (IsSelfRegistered is the API Name) https://help.salesforce.com/apex/HTViewHelpDoc?id=user_fields.htm&language=en

Another thing you could try is querying the contact record in your trigger before you chek the Self Regsitered formula field like so:
 
trigger LearnerWelcomeEmail on Contact (after insert) {
    
    //Prepare to send welcome emails
    List<Messaging.SingleEmailMessage> welcome = new List<Messaging.SingleEmailMessage>();
    
    for (Contact learner : [Select Email,Self_Registered__c From Contact Where Id in :Trigger.newMap.keySet()]){
        if(trigger.isInsert && learner.Self_Registered__c == true)
        {
           Messaging.SingleEmailMessage learnerEmail = new Messaging.SingleEmailMessage();
                List<String> sendTo = new List<String>();
                sendTo.add(learner.Email);
                learnerEmail.setToAddresses(sendTo);
                learnerEmail.setReplyTo('info@digitalonramps.com');
                learnerEmail.setSenderDisplayName('Digital On-Ramps');
                learnerEmail.setTemplateId('00X17000000DnrL');
                learnerEmail.setTargetObjectId(learner.Id);

            
            welcome.add(learnerEmail);
            }
    }
    if(welcome.size()>0){
        Messaging.sendEmail(welcome);
    }
}

 
Liz Gibbons 16Liz Gibbons 16
Hi James,

I did try originally using IsSelfRegistered. Somehow our registration process is not ticking that box. So I'm left to create a custom field checked when the user is created by the 'eportfolio Site Guest User' which functions to give non-Community members access to certain of our pages. 

The trigger itself is functioning correctly. Is there an advantage to doing as you do above? I'm a new developer, so I'm always looking to write better code than I currently am.