-
Notifications
You must be signed in to change notification settings - Fork 1
Feedback #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feedback
Are you sure you want to change the base?
Feedback #1
Changes from all commits
ba47e27
75c0944
df50c24
f0b5dea
a20a33d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,17 +32,32 @@ public with sharing class LeadTriggerHandler { | |
| */ | ||
| public static void handleTitleNormalization(List<Lead> leadsToNormalize) { | ||
| for (Lead ld : leadsToNormalize) { | ||
| if (ld.title == 'vp' || ld.title.contains('v.p.') || ld.title.contains('vice president')) { | ||
| if (String.isBlank(ld.Title)) { | ||
| continue; | ||
| } | ||
| if ( | ||
| ld.title.containsIgnoreCase('vp') || | ||
| ld.title.containsIgnoreCase('v.p.') || | ||
| ld.title.containsIgnoreCase('vice president') | ||
| ) { | ||
| ld.Title = 'Vice President'; | ||
| } else if ( | ||
| ld.title.contains('mgr') || | ||
| ld.title.contains('manage') || | ||
| ld.title.contains('head of department') | ||
| ld.title.containsIgnoreCase('mgr') || | ||
| ld.title.containsIgnoreCase('manage') || | ||
| ld.title.containsIgnoreCase('head of department') | ||
| ) { | ||
| ld.Title = 'Manager'; | ||
| } else if (ld.title.contains('exec') || ld.title == 'chief' || ld.title.contains('head')) { | ||
| } else if ( | ||
| ld.title.containsIgnoreCase('exec') || | ||
| ld.title.containsIgnoreCase('chief') || | ||
| ld.title.containsIgnoreCase('head') | ||
| ) { | ||
| ld.Title = 'Executive'; | ||
| } else if (ld.title.contains('assist') || ld.title.contains('deputy') || ld.title == 'jr') { | ||
| } else if ( | ||
| ld.title.containsIgnoreCase('assist') || | ||
| ld.title.containsIgnoreCase('deputy') || | ||
| ld.title.containsIgnoreCase('jr') | ||
| ) { | ||
| ld.Title = 'Assistant'; | ||
| } | ||
| } | ||
|
|
@@ -61,21 +76,18 @@ public with sharing class LeadTriggerHandler { | |
| */ | ||
| public static void handleAutoLeadScoring(List<Lead> leadsToScore) { | ||
| for (Lead ld : leadsToScore) { | ||
| Integer score = 10; | ||
| Integer score = 0; | ||
|
|
||
| // Check and add points based on the specified conditions | ||
| if (ld.LeadSource == 'Website' && ld.Email != null) { | ||
| score = 3; | ||
| if (ld.LeadSource == 'Web' && ld.Email != null) { | ||
| score += 3; | ||
| } | ||
|
Comment on lines
+82
to
84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put the condition values into a variable so it's easier to change in the future. |
||
|
|
||
| if (ld.Phone != null) { | ||
| score = 5; | ||
| score += 5; | ||
| } | ||
|
|
||
| if (ld.Industry == 'Technology') { | ||
| score = 10; | ||
| score += 10; | ||
| } | ||
|
|
||
| ld.Lead_Score__c = score; // Set the computed score back to the lead | ||
| } | ||
| } | ||
|
|
@@ -104,42 +116,58 @@ public with sharing class LeadTriggerHandler { | |
| * - One of the errors is map related. Make sure you are using the correct contact map key | ||
| */ | ||
| public static void handleLeadAutoConvert(List<Lead> leads) { | ||
| // Get convert status | ||
| LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted = TRUE LIMIT 1]; | ||
| // Step 1: Gather all lead emails | ||
| Map<Id,String> leadToEmailMap = new Map<Id,String>(); | ||
| for (Lead lead : leads) { | ||
| leadToEmailMap.put(lead.Id, lead.Email); | ||
| if (!lead.IsConverted && lead.Status != convertStatus.MasterLabel && lead.Email != null) { | ||
| leadToEmailMap.put(lead.Id, lead.Email); | ||
| } | ||
| } | ||
|
|
||
| if (leadToEmailMap.size() == 0) { | ||
| return; | ||
| } | ||
|
|
||
| // Step 2: Find matching contacts based on email | ||
| Map<String, Contact> emailToContactMap = new Map<String, Contact>(); | ||
| for (Contact c : [SELECT Id, Email, AccountId FROM Contact WHERE Email IN :leadToEmailMap.values()]) { | ||
| if (!emailToContactMap.containsKey(c.Email)) { | ||
| emailToContactMap.put(c.Email, c); | ||
| } else { | ||
| // If we found another contact with the same email, we don't auto-convert. | ||
| // So we remove the email from the map. | ||
| emailToContactMap.remove(c.Email); | ||
| } | ||
| List<AggregateResult> ars = [ | ||
| SELECT Email | ||
| FROM Contact | ||
| GROUP BY Email | ||
| HAVING COUNT(Id) = 1 | ||
| AND Email IN :leadToEmailMap.values() | ||
| ]; | ||
| List<String> singleMatchEmail = new List<String>(); | ||
| for (AggregateResult ar : ars) { | ||
| singleMatchEmail.add((String) ar.get('Email')); | ||
| } | ||
|
|
||
| // Step 3: Auto-convert leads | ||
| List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>(); | ||
| LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted = TRUE LIMIT 1]; | ||
| for (Id leadId : leadToEmailMap.keySet()) { | ||
| String leadEmail = leadToEmailMap.get(leadId); | ||
| if (emailToContactMap.containsKey(leadEmail)) { | ||
| Database.LeadConvert lc = new Database.LeadConvert(); | ||
| lc.setLeadId(leadId); | ||
| lc.setContactId(emailToContactMap.get(leadEmail).Id); // Use existing Contact Id | ||
| lc.setAccountId(emailToContactMap.get(leadEmail).AccountId); // Use existing Account Id | ||
| lc.setDoNotCreateOpportunity(true); // Assuming we don't want to create an opportunity | ||
| lc.setConvertedStatus(convertStatus.MasterLabel); // Set the converted status | ||
| leadConverts.add(lc); | ||
| // If we have matching contacts | ||
| if (singleMatchEmail.size() > 0) { | ||
| Map<String, Contact> emailToContactMap = new Map<String, Contact>(); | ||
| for (Contact contact : [SELECT Id, Email, AccountId FROM Contact WHERE Email IN :singleMatchEmail]) { | ||
| emailToContactMap.put(contact.Email, contact); | ||
| } | ||
|
|
||
| // Step 3: Auto-convert leads | ||
| List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>(); | ||
| for (Id leadId : leadToEmailMap.keySet()) { | ||
| if (emailToContactMap.containsKey(leadToEmailMap.get(leadId))) { | ||
| Contact cont = emailToContactMap.get(leadToEmailMap.get(leadId)); | ||
| Database.LeadConvert lc = new Database.LeadConvert(); | ||
| lc.setLeadId(leadId); | ||
| lc.setContactId(cont.Id); // Use existing Contact Id | ||
| lc.setAccountId(cont.AccountId); // Use existing Account Id | ||
| lc.setDoNotCreateOpportunity(true); // Assuming we don't want to create an opportunity | ||
| lc.setConvertedStatus(convertStatus.MasterLabel); // Set the converted status | ||
| leadConverts.add(lc); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (!leadConverts.isEmpty()) { | ||
| List<Database.LeadConvertResult> lcrs = Database.convertLead(leadConverts); | ||
| if (!leadConverts.isEmpty()) { | ||
| List<Database.LeadConvertResult> lcrs = Database.convertLead(leadConverts); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add additional test directly testing method like LeadTriggerHandler.handleTitleNormalization |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,218 @@ | ||
| /** | ||
| * This class contains unit tests for validating the behavior of | ||
| * Apex class LeadTriggerHandler | ||
| * and trigger LeadTrigger. | ||
| * | ||
| * Implemented by Oxana Suvorova | ||
| */ | ||
| @isTest | ||
| private class LeadTriggerHandlerTest { | ||
|
|
||
| /* | ||
| * LeadTriggerHandler.handleTitleNormalization insert test | ||
| */ | ||
| @isTest | ||
| static void testHandleTitleNormalization_insert() { | ||
| // Prepare the test data | ||
| List<String> titles = new List<String>{ | ||
| 'vp', 'v.p.', 'vice president', 'VPOTUS', 'V.P.', 'vice person', // 5 'Vice President' | ||
| 'mgr', 'manage', 'head of department', '', 'Manager', // 4 'Manager' | ||
| 'exec', 'chief', 'head', 'Chief Executive', null, // 4 'Executive' | ||
| 'assist', 'deputy', 'jr', 'DEPUTY', 'junior'}; // 4 'Assistant' | ||
|
|
||
| List<Lead> leadsToInsert = TestDataFactory.createLeadsByTitle(titles, false); | ||
|
|
||
| // Perform the test | ||
| Test.startTest(); | ||
| Database.insert(leadsToInsert); | ||
| Test.stopTest(); | ||
|
|
||
| // Retrieve the count of Leads grouped by Title | ||
| List<AggregateResult> groupedLeads = [ | ||
| SELECT | ||
| Title, | ||
| COUNT(Name) aggCount | ||
| FROM Lead | ||
| GROUP BY Title | ||
| ]; | ||
|
|
||
| Map<String, Integer> countsByTitle = new Map<String, Integer>(); | ||
| Integer totalRecords = 0; | ||
| for (AggregateResult ar : groupedLeads) { | ||
| totalRecords += (Integer) ar.get('aggCount'); | ||
| countsByTitle.put((String) ar.get('Title'), (Integer) ar.get('aggCount')); | ||
| } | ||
|
|
||
| // Assert that the Title have been correctly changed | ||
| Assert.isTrue(countsByTitle.get('Vice President') == 5, 'Expected 5 Leads with Title \'Vice President\''); | ||
| Assert.isTrue(countsByTitle.get('Manager') == 4, 'Expected 4 Leads with Title \'Manager\''); | ||
| Assert.isTrue(countsByTitle.get('Executive') == 4, 'Expected 4 Leads with Title \'Executive\''); | ||
| Assert.isTrue(countsByTitle.get('Assistant') == 4, 'Expected 4 Leads with Title \'Assistant\''); | ||
| Assert.areEqual(21, totalRecords, 'Expected 21 Lead records'); | ||
| } | ||
|
|
||
| /* | ||
| * LeadTriggerHandler.handleTitleNormalization update test | ||
| */ | ||
| @isTest | ||
| static void testHandleTitleNormalization_update() { | ||
| // Prepare the test data | ||
| List<String> titles = new List<String>{'asist', 'depty', 'junior', null, ''}; | ||
| List<Lead> leadsToUpdate = TestDataFactory.createLeadsByTitle(titles, true); | ||
|
|
||
| for (Lead lead : leadsToUpdate) { | ||
| lead.Title = 'jr'; | ||
| } | ||
| // Perform the test | ||
| Test.startTest(); | ||
| Database.update(leadsToUpdate); | ||
| Test.stopTest(); | ||
|
|
||
| // Retrieve updated Leads | ||
| List<Lead> leadsAfterUpdate = [ | ||
| SELECT | ||
| Title | ||
| FROM Lead | ||
| WHERE Id IN :leadsToUpdate | ||
| ]; | ||
|
|
||
| // Assert that the Title have been correctly updated | ||
| Assert.isTrue(leadsAfterUpdate.size() == 5, 'Expected 5 Lead records'); | ||
| for (Lead lead : leadsAfterUpdate) { | ||
| Assert.areEqual('Assistant', lead.Title, 'Expected Title \'Assistant\''); | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| * LeadTriggerHandler.handleTitleNormalization update test | ||
| */ | ||
| @isTest | ||
| static void testHandleAutoLeadScoring() { | ||
| // Prepare the test data | ||
| List<Map<String, Object>> params = new List<Map<String, Object>>(); | ||
| params.add(new Map<String, Object>{'Lead_Score__c' => 20, 'LeadSource' => null}); // 0 | ||
| params.add(new Map<String, Object>{'LeadSource' => 'Other', 'Email' => 'test@mail.com'}); // 0 | ||
| params.add(new Map<String, Object>{'LeadSource' => 'Web', 'Email' => 'test@mail.com'}); // 3 | ||
| params.add(new Map<String, Object>{'Phone' => '(908)345-1234', 'Industry' => 'Government'}); // 5 | ||
| params.add(new Map<String, Object>{'LeadSource' => 'Web', 'Email' => 'test2@mail.com', 'Phone' => '(908)345-2345'}); // 8 | ||
| params.add(new Map<String, Object>{'Lead_Score__c' => 10, 'Email' => 'test3@mail.com', 'Industry' => 'Technology'}); // 10 | ||
| params.add(new Map<String, Object>{'LeadSource' => 'Web', 'Email' => 'test4@mail.com', 'Industry' => 'Technology'}); // 13 | ||
| params.add(new Map<String, Object>{'LeadSource' => 'Web', 'Phone' => '(908)346-1234', 'Industry' => 'Technology'}); // 15 | ||
| params.add(new Map<String, Object>{'LeadSource' => 'Web', 'Email' => 'test5@mail.com', | ||
| 'Phone' => '(908)346-1234', 'Industry' => 'Technology'}); // 18 | ||
|
|
||
| List<Lead> leadsToScore = TestDataFactory.createLeadsByParams(params, false); | ||
|
|
||
| // Perform the test | ||
| Test.startTest(); | ||
| LeadTriggerHandler.handleAutoLeadScoring(leadsToScore); | ||
| Test.stopTest(); | ||
|
|
||
| // Assert that the Score calculates correctly | ||
| List<Integer> scoreVariants = new List<Integer>{0, 0, 3, 5, 8, 10, 13, 15, 18}; | ||
| for (Integer i = 0; i < leadsToScore.size(); i++) { | ||
| Assert.isTrue(leadsToScore[i].Lead_Score__c <= 18, 'Lead score shouldn\'t be more than 18'); | ||
| Assert.areEqual(scoreVariants[i], leadsToScore[i].Lead_Score__c, 'Score has not correctly calculated'); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| @isTest | ||
| static void testHandleLeadAutoConvert_insertPositive() { | ||
| // Prepare the test data | ||
| TestDataFactory.generateAccountWithContacts(50, 7); // 7 contacts with a unique email | ||
| Map<String, Object> params = new Map<String, Object>{'LeadSource' => 'Web', 'Email' => 'test'}; | ||
| List<Lead> leads = TestDataFactory.createLeadsWithParams(50, params, false); | ||
|
|
||
| // Perform the test | ||
| Test.startTest(); | ||
| Database.insert(leads); | ||
| Test.stopTest(); | ||
|
|
||
| // Request resulted Leads | ||
| List<Lead> insertedLeads = [ | ||
| SELECT Id, Email, IsConverted | ||
| FROM Lead | ||
| ]; | ||
| // Assertions | ||
| Assert.isTrue(insertedLeads.size() == 50, 'Expected 50 Leads inserted'); | ||
| Integer converted = 0; | ||
| for (Integer i = 0; i < 50; i++) { | ||
| if (i > 0 && Math.mod(i, 7) == 0) { | ||
| Assert.isTrue(insertedLeads[i].IsConverted, 'Lead with email ' + insertedLeads[i].Email + ' expected to be converted'); | ||
| converted++; | ||
| } else { | ||
| Assert.isFalse(insertedLeads[i].IsConverted, 'Lead with email ' + insertedLeads[i].Email + ' shouldn\t be converted'); | ||
| } | ||
| } | ||
| Assert.isTrue(converted == 7, 'Expected 7 Leads converted'); | ||
| } | ||
|
|
||
| @isTest | ||
| static void testHandleLeadAutoConvert_insertNegative() { | ||
| // Prepare the test data | ||
| TestDataFactory.generateAccountWithContacts(5, 2); // 2 contacts with a unique email | ||
| Map<String, Object> params = new Map<String, Object>{'LeadSource' => 'Web', | ||
| 'Status' => 'Closed - Converted', | ||
| 'Email' => 'test'}; | ||
| List<Lead> leads = TestDataFactory.createLeadsWithParams(5, params, false); | ||
|
|
||
| // Perform the test | ||
| Test.startTest(); | ||
| Database.insert(leads); | ||
| Test.stopTest(); | ||
|
|
||
| // Request resulted Leads | ||
| List<Lead> insertedLeads = [ | ||
| SELECT | ||
| Id, | ||
| Email, | ||
| IsConverted | ||
| FROM Lead | ||
| ]; | ||
| // Assertions | ||
| Assert.isTrue(insertedLeads.size() == 5, 'Expected 5 Leads inserted'); | ||
| for (Lead lead : insertedLeads) { | ||
| Assert.isFalse(lead.IsConverted, 'Lead should\'t be converted'); | ||
| } | ||
| } | ||
|
|
||
| @isTest | ||
| static void testHandleLeadAutoConvert_update() { | ||
| // Prepare the test data | ||
| TestDataFactory.generateAccountWithContacts(5, 2); // 2 contacts with a unique email | ||
| Map<String, Object> params = new Map<String, Object>{'LeadSource' => 'Web'}; | ||
| List<Lead> leads = TestDataFactory.createLeadsWithParams(2, params, true); | ||
|
|
||
| // Change email | ||
| List<Lead> leadsToUpdate = [ | ||
| SELECT | ||
| Id, | ||
| FROM Lead | ||
| WHERE Id IN :leads | ||
| AND IsConverted = false | ||
| ]; | ||
| Assert.areEqual(2, leadsToUpdate.size(), 'Expected to get 2 unconverted Leads'); | ||
| leadsToUpdate[0].Email = 'test0@mail.com'; // not going to be converted | ||
| leadsToUpdate[1].Email = 'test1@mail.com'; // going to be converted | ||
|
|
||
| // Perform the test | ||
| Test.startTest(); | ||
| Database.update(leadsToUpdate); | ||
| Test.stopTest(); | ||
|
|
||
| // Request resulted Leads | ||
| List<Lead> updatedLeads = [ | ||
| SELECT | ||
| Id, | ||
| Email, | ||
| IsConverted | ||
| FROM Lead | ||
| WHERE Id IN :leadsToUpdate | ||
| ]; | ||
| // Assertions | ||
| Assert.isFalse(updatedLeads[0].IsConverted, 'Lead with email ' + updatedLeads[0].Email + ' shouldn\'t be converted'); | ||
| Assert.isTrue(updatedLeads[1].IsConverted, 'Lead with email ' + updatedLeads[1].Email + ' expected to be converted'); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
| <apiVersion>59.0</apiVersion> | ||
| <status>Active</status> | ||
| </ApexClass> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For all of these examples try create a contains the values that you are looking for then do contain on the list.