diff --git a/force-app/main/adapter/in/sobjects/contact/ContactAdapter.cls b/force-app/main/adapter/in/sobjects/contact/ContactAdapter.cls index cd754a1703..afe554f10c 100644 --- a/force-app/main/adapter/in/sobjects/contact/ContactAdapter.cls +++ b/force-app/main/adapter/in/sobjects/contact/ContactAdapter.cls @@ -593,6 +593,13 @@ public inherited sharing class ContactAdapter extends fflib_SObjects2 { Address__c contactAddress = contactAddressesToInsertByContact.get(contact); contact.Current_Address__c = contactAddress.Id; } + + SfdoInstrumentationService.getInstance().log( + SfdoInstrumentationEnum.Feature.Addresses, + SfdoInstrumentationEnum.Component.TriggerAction, + SfdoInstrumentationEnum.Action.Dml_Insert, + new Map{ 'SourceClass' => 'ContactAdapter' }, + contactAddressesToInsertByContact.size()); } private void updateContactAddressFromExistingAddress(Contact contact, Address__c existingAddressFromContact) { diff --git a/force-app/main/default/classes/BDI_DataImportService.cls b/force-app/main/default/classes/BDI_DataImportService.cls index 465dbb71c6..2aa081825c 100644 --- a/force-app/main/default/classes/BDI_DataImportService.cls +++ b/force-app/main/default/classes/BDI_DataImportService.cls @@ -379,6 +379,7 @@ global with sharing class BDI_DataImportService { sfdoInstrumentationEnum.Feature.GiftEntry, sfdoInstrumentationEnum.Component.Page, sfdoInstrumentationEnum.Action.Save, + new Map{ 'SourceClass' => 'BDI_DataImportService' }, insertedGifts); } diff --git a/force-app/main/default/classes/BDI_DataImport_TEST.cls b/force-app/main/default/classes/BDI_DataImport_TEST.cls index 8bd41cfd75..c02fbee460 100644 --- a/force-app/main/default/classes/BDI_DataImport_TEST.cls +++ b/force-app/main/default/classes/BDI_DataImport_TEST.cls @@ -1949,10 +1949,10 @@ public with sharing class BDI_DataImport_TEST { ID ApexJobId = Database.executeBatch(bdi, 10); Test.stopTest(); - System.assertEquals(2, mockService.value, 'The instrumentation service should have indicated two new Gifts were inserted'); System.assertEquals(sfdoInstrumentationEnum.Feature.GiftEntry, mockService.feature, 'The instrumentation service should have indicated GiftEntry'); - } + System.assertEquals(2, mockService.value, 'The instrumentation service should have indicated two new Gifts were inserted'); + } /********************************************************************************************************* * @description When the Data Import Service has been mocked to simulate coming in through the UI, verify @@ -1963,6 +1963,9 @@ public with sharing class BDI_DataImport_TEST { private static void shouldNotInstrumentNewDonationsWhenNotThroughUserInterface() { SfdoInstrumentationMock_TEST.MockService mockService = SfdoInstrumentationMock_TEST.injectMockedInstrumentationService(); + // SfdoInstrumentationService.instance = null; // reset instrumentation + // UTIL_UnitTestData_TEST.turnOffAutomaticHHNaming(); // prevent this from running its instrumentation + List dataImports = new List(); dataImports.add(newDI('c1', 'C1', 100)); insert dataImports; @@ -1973,7 +1976,9 @@ public with sharing class BDI_DataImport_TEST { ID ApexJobId = Database.executeBatch(bdi, 10); Test.stopTest(); - System.assertEquals(null, mockService.value, 'The instrumentation service should have indicated two new Gifts were inserted'); + for (SfdoInstrumentationMock_TEST.LastCallData callData : mockService.lastCallStack) { + System.assertNotEquals(SfdoInstrumentationEnum.Feature.DataImportEngine, callData.feature, 'The BDI instrumentation should have executed'); + } } /********************************************************************************************************* diff --git a/force-app/main/default/classes/Callable_API.cls b/force-app/main/default/classes/Callable_API.cls index d99ef1b7a9..112dbbfa9e 100644 --- a/force-app/main/default/classes/Callable_API.cls +++ b/force-app/main/default/classes/Callable_API.cls @@ -96,7 +96,7 @@ global with sharing class Callable_API implements System.Callable { String oppStage = paramService.getString(CallableApiParameters.PARAM_OPPORTUNITY_STAGE); return OPP_StageMappingUtil.determineOppStateFromOppStage(oppStage); - } when 'crlp.getdefinitionsforrolluptype' { + } when 'crlp.getdefinitionsforrolluptype' { // internal use only, deprecated String rollupType = paramService.getString(CallableApiParameters.PARAM_ROLLUP_TYPE); CRLP_ApiService crlpApiSvc = new CRLP_ApiService(); @@ -104,7 +104,7 @@ global with sharing class Callable_API implements System.Callable { return JSON.serialize(response, true); - } when 'crlp.executerollups' { + } when 'crlp.executerollups' { // internal use only, deprecated Id parentId = paramService.getString(CallableApiParameters.PARAM_ROLLUP_PARENTID); String rollupType = paramService.getString(CallableApiParameters.PARAM_ROLLUP_TYPE); List rollupDefs = paramService.getRollupDefinitions(CallableApiParameters.PARAM_ROLLUP_DEFS); @@ -120,7 +120,7 @@ global with sharing class Callable_API implements System.Callable { CRLP_ApiService crlpApiSvc = new CRLP_ApiService(); return crlpApiSvc.isCrlpEnabled(); - } when 'err.dispatchaction' { + } when 'err.dispatchaction' { // internal use only // This method is to be used only by Salesforce.org apps and is subject to change at any time. Do NOT call this method. // If you do so, your functionality can break without any warning or liability from Salesforce. diff --git a/force-app/main/default/classes/ContactMergeService.cls b/force-app/main/default/classes/ContactMergeService.cls index 43823c969b..4d8c134e07 100644 --- a/force-app/main/default/classes/ContactMergeService.cls +++ b/force-app/main/default/classes/ContactMergeService.cls @@ -195,6 +195,7 @@ public class ContactMergeService { SfdoInstrumentationEnum.Feature.ContactMerge, SfdoInstrumentationEnum.Component.Page, SfdoInstrumentationEnum.Action.ContactMergeResultCount, + new Map{ 'SourceClass' => 'ContactMergeService' }, losers.size() + 1); successfulMerge = true; diff --git a/force-app/main/default/classes/EP_EngagementPlans_TDTM.cls b/force-app/main/default/classes/EP_EngagementPlans_TDTM.cls index f06b8a6323..6965a7b8c6 100644 --- a/force-app/main/default/classes/EP_EngagementPlans_TDTM.cls +++ b/force-app/main/default/classes/EP_EngagementPlans_TDTM.cls @@ -132,6 +132,7 @@ public with sharing class EP_EngagementPlans_TDTM extends TDTM_Runnable { SfdoInstrumentationEnum.Feature.EngagementPlans, SfdoInstrumentationEnum.Component.TriggerAction, SfdoInstrumentationEnum.Action.Create, + new Map{ 'SourceClass' => 'EP_EngagementPlans_TDTM' }, engagementPlans.size()); } diff --git a/force-app/main/default/classes/HH_Container_LCTRL.cls b/force-app/main/default/classes/HH_Container_LCTRL.cls index d32ced3da4..6a30c7d53a 100644 --- a/force-app/main/default/classes/HH_Container_LCTRL.cls +++ b/force-app/main/default/classes/HH_Container_LCTRL.cls @@ -434,6 +434,7 @@ public with sharing class HH_Container_LCTRL { SfdoInstrumentationEnum.Feature.ManageHousehold, SfdoInstrumentationEnum.Component.Page, SfdoInstrumentationEnum.Action.HouseholdMemberAdded, + new Map{ 'SourceClass' => 'HH_Container_LCTRL' }, listInsert.size()); } } @@ -515,6 +516,7 @@ public with sharing class HH_Container_LCTRL { SfdoInstrumentationEnum.Feature.ManageHousehold, SfdoInstrumentationEnum.Component.Page, SfdoInstrumentationEnum.Action.HouseholdMerged, + new Map{ 'SourceClass' => 'HH_Container_LCTRL' }, listHHMerge.size()); } @@ -570,7 +572,9 @@ public with sharing class HH_Container_LCTRL { SfdoInstrumentationService.getInstance().log( SfdoInstrumentationEnum.Feature.ManageHousehold, SfdoInstrumentationEnum.Component.Page, - SfdoInstrumentationEnum.Action.HouseholdNamingSettingsUpdated, 1); + SfdoInstrumentationEnum.Action.HouseholdNamingSettingsUpdated, + new Map{ 'SourceClass' => 'HH_Container_LCTRL' }, + 1); originalHouseholdCustomNameSetting = (String) hh.get('npo02__SYSTEM_CUSTOM_NAMING__c'); } } diff --git a/force-app/main/default/classes/HH_Container_TEST.cls b/force-app/main/default/classes/HH_Container_TEST.cls index 779d0af85b..22989bccbf 100644 --- a/force-app/main/default/classes/HH_Container_TEST.cls +++ b/force-app/main/default/classes/HH_Container_TEST.cls @@ -398,7 +398,7 @@ private class HH_Container_TEST { Contact[] hhContactsToRemove = new Contact[0]; Account[] accountsToMerge = new Account[] { accounts[1], accounts[2] }; - System.assertEquals(null, SfdoInstrumentationService.instance, 'The Instrumentation Service Instance should not have been instantiated yet'); + SfdoInstrumentationService.instance = null; Test.startTest(); accounts[0].npo02__SYSTEM_CUSTOM_NAMING__c = 'npo02__Formal_Greeting__c'; diff --git a/force-app/main/default/classes/LVL_LevelAssignBATCH_TEST.cls b/force-app/main/default/classes/LVL_LevelAssignBATCH_TEST.cls index cf6d519c9c..21f97e4859 100644 --- a/force-app/main/default/classes/LVL_LevelAssignBATCH_TEST.cls +++ b/force-app/main/default/classes/LVL_LevelAssignBATCH_TEST.cls @@ -44,6 +44,9 @@ private class LVL_LevelAssignBATCH_TEST { private static Level__c lvlPlatinum { get; set; } private static Level__c lvlAcctZinc { get; set; } + private static final Integer CONTACT_COUNT = 8; + private static final Integer ACCOUNT_COUNT = 2; + /********************************************************************************************************* * @description creates Bronze, Silver, and Gold Level records for test code to use. */ @@ -161,7 +164,7 @@ private class LVL_LevelAssignBATCH_TEST { private static DateTime dtCon6Modified { get; set; } private static void createTestContacts(String uniqueCounter) { - contacts = UTIL_UnitTestData_TEST.createMultipleTestContacts(8); + contacts = UTIL_UnitTestData_TEST.createMultipleTestContacts(CONTACT_COUNT); for (Contact c : contacts) { c.LastName += uniqueCounter; } @@ -199,7 +202,7 @@ private class LVL_LevelAssignBATCH_TEST { */ private static List accounts { get; set; } private static void createTestAccounts(String uniqueCounter) { - accounts = UTIL_UnitTestData_TEST.createMultipleTestAccounts(2, null); + accounts = UTIL_UnitTestData_TEST.createMultipleTestAccounts(ACCOUNT_COUNT, null); for (Account a : accounts) { a.Name += uniqueCounter; } @@ -232,6 +235,16 @@ private class LVL_LevelAssignBATCH_TEST { verifyContactLevels(); + System.assertEquals(SfdoInstrumentationEnum.Feature.EngagementPlans.name(), SfdoInstrumentationService.lastCallData.lastFeatureName, + 'The Instrumentation LastFeatureName should be EngagementPlans'); + System.assertEquals(1, SfdoInstrumentationService.lastCallData.lastValue, + 'The Instrumentation LastValue should be 1'); + // System.assertEquals(true, new Map{ 'SourceClass' => 'LVL_LevelAssign_BATCH', 'Target Object' => 'Contact' }, SfdoInstrumentationService.lastCallData.lastContext, + System.assertEquals('LVL_LevelAssign_BATCH', SfdoInstrumentationService.lastCallData.lastContext.get('SourceClass'), + 'The Instrumentation LastContext should be LVL_Batch'); + System.assertEquals('Contact', SfdoInstrumentationService.lastCallData.lastContext.get('Target Object'), + 'The Instrumentation LastContext should be Contact'); + Levels_Settings__c levelSettings = Levels_Settings__c.getInstance(); System.assertEquals(null, levelSettings.LastJobStartTimeAccount__c, 'The LastJobStartTimeAccount__c should not be populated'); @@ -262,6 +275,17 @@ private class LVL_LevelAssignBATCH_TEST { Database.executeBatch(batch); Test.stopTest(); + System.assertEquals(SfdoInstrumentationEnum.Feature.Levels.name(), SfdoInstrumentationService.lastCallData.lastFeatureName, + 'The Instrumentation LastFeatureName should be Levels'); + System.assertEquals(SfdoInstrumentationEnum.Component.Batch.name(), SfdoInstrumentationService.lastCallData.lastComponentName, + 'The Instrumentation LastComponentName should be Batch'); + System.assertEquals(CONTACT_COUNT-1, SfdoInstrumentationService.lastCallData.lastValue, + 'The Instrumentation LastValue should be 7'); + System.assertEquals('LVL_LevelAssign_BATCH', SfdoInstrumentationService.lastCallData.lastContext.get('SourceClass'), + 'The Instrumentation LastContext should be LVL_Batch'); + System.assertEquals('Contact', SfdoInstrumentationService.lastCallData.lastContext.get('Target Object'), + 'The Instrumentation LastContext should be Contact'); + Contact conZero = [SELECT Id, npo02__LastMembershipLevel__c FROM Contact WHERE Id = :contacts[0].Id]; System.assertEquals(null, conZero.npo02__LastMembershipLevel__c); } diff --git a/force-app/main/default/classes/LVL_LevelAssign_BATCH.cls b/force-app/main/default/classes/LVL_LevelAssign_BATCH.cls index 702e44ff60..8254155a5c 100644 --- a/force-app/main/default/classes/LVL_LevelAssign_BATCH.cls +++ b/force-app/main/default/classes/LVL_LevelAssign_BATCH.cls @@ -163,9 +163,22 @@ public without sharing class LVL_LevelAssign_BATCH implements Database.Batchable } // ladder } // scope + SfdoInstrumentationService.getInstance().log( + SfdoInstrumentationEnum.Feature.Levels, + SfdoInstrumentationEnum.Component.Batch, + SfdoInstrumentationEnum.Action.Dml_Update, + new Map{ 'Target Object' => sObjectName, 'SourceClass' => 'LVL_LevelAssign_BATCH' }, + recordsById.size()); + update recordsById.values(); if (!newEngagementPlans.isEmpty()) { insert newEngagementPlans; + SfdoInstrumentationService.getInstance().log( + SfdoInstrumentationEnum.Feature.EngagementPlans, + SfdoInstrumentationEnum.Component.Batch, + SfdoInstrumentationEnum.Action.Dml_Insert, + new Map{ 'Target Object' => sObjectName, 'SourceClass' => 'LVL_LevelAssign_BATCH' }, + newEngagementPlans.size()); } if (!errorsCreatingEngagementPlans.isEmpty()) { insert errorsCreatingEngagementPlans; diff --git a/force-app/main/default/classes/RD2_ApiService.cls b/force-app/main/default/classes/RD2_ApiService.cls index eedfaaef95..2bb38444de 100644 --- a/force-app/main/default/classes/RD2_ApiService.cls +++ b/force-app/main/default/classes/RD2_ApiService.cls @@ -68,6 +68,7 @@ public inherited sharing class RD2_ApiService { SfdoInstrumentationEnum.Feature.EnhancedRecurringDonations, SfdoInstrumentationEnum.Component.API, SfdoInstrumentationEnum.Action.QuerySchedules, + new Map{ 'SourceClass' => 'RD2_ApiService' }, schedulesByRdId.size()); return JSON.serialize(schedulesByRdId); @@ -223,6 +224,7 @@ public inherited sharing class RD2_ApiService { SfdoInstrumentationEnum.Feature.EnhancedRecurringDonations, SfdoInstrumentationEnum.Component.API, SfdoInstrumentationEnum.Action.QueryInstallments, + new Map{ 'SourceClass' => 'RD2_ApiService' }, installmentsByRdId.size()); return JSON.serialize(installmentsByRdId); @@ -281,6 +283,7 @@ public inherited sharing class RD2_ApiService { SfdoInstrumentationEnum.Feature.EnhancedRecurringDonations, SfdoInstrumentationEnum.Component.API, SfdoInstrumentationEnum.Action.Pause, + new Map{ 'SourceClass' => 'RD2_ApiService' }, Limits.getDmlRows() - startingDmlRows); return response; diff --git a/force-app/main/default/classes/RD2_OpportunityEvaluation_BATCH.cls b/force-app/main/default/classes/RD2_OpportunityEvaluation_BATCH.cls index 10349cbb54..0aca1fea85 100644 --- a/force-app/main/default/classes/RD2_OpportunityEvaluation_BATCH.cls +++ b/force-app/main/default/classes/RD2_OpportunityEvaluation_BATCH.cls @@ -291,7 +291,8 @@ public without sharing class RD2_OpportunityEvaluation_BATCH new Map{ 'RD Records Processed' => recordsProcessed, 'RD Records Failed' => recordsFailed, - 'Opportunity Records Created ' => recordsCreated + 'Opportunity Records Created ' => recordsCreated, + 'SourceClass' => 'RD2_OpportunityEvaluation_BATCH' }, recordsCreated ); diff --git a/force-app/main/default/classes/RD2_RecurringDonations_TDTM.cls b/force-app/main/default/classes/RD2_RecurringDonations_TDTM.cls index 1360f17506..25e1cb31f9 100644 --- a/force-app/main/default/classes/RD2_RecurringDonations_TDTM.cls +++ b/force-app/main/default/classes/RD2_RecurringDonations_TDTM.cls @@ -150,6 +150,7 @@ public class RD2_RecurringDonations_TDTM extends TDTM_Runnable { SfdoInstrumentationEnum.Feature.EnhancedRecurringDonations, SfdoInstrumentationEnum.Component.TriggerAction, SfdoInstrumentationEnum.Action.Create, + new Map{ 'SourceClass' => 'RD2_RecurringDonations_TDTM' }, rds.size()); } diff --git a/force-app/main/default/classes/RD_RecurringDonations_TDTM.cls b/force-app/main/default/classes/RD_RecurringDonations_TDTM.cls index 1ad70f8ace..334f54cb88 100644 --- a/force-app/main/default/classes/RD_RecurringDonations_TDTM.cls +++ b/force-app/main/default/classes/RD_RecurringDonations_TDTM.cls @@ -122,6 +122,7 @@ public class RD_RecurringDonations_TDTM extends TDTM_Runnable { SfdoInstrumentationEnum.Feature.LegacyRecurringDonations, SfdoInstrumentationEnum.Component.TriggerAction, SfdoInstrumentationEnum.Action.Create, + new Map{ 'SourceClass' => 'RD_RecurringDonations_TDTM' }, newlist.size()); } diff --git a/force-app/main/default/classes/STG_PanelRDHealthCheck_TEST.cls b/force-app/main/default/classes/STG_PanelRDHealthCheck_TEST.cls index bb4104b94f..cbeaabc54c 100644 --- a/force-app/main/default/classes/STG_PanelRDHealthCheck_TEST.cls +++ b/force-app/main/default/classes/STG_PanelRDHealthCheck_TEST.cls @@ -49,6 +49,11 @@ private class STG_PanelRDHealthCheck_TEST { */ @IsTest private static void shouldValidateLegacyRecurringDonationsConfig() { + if (isRD2MetadataDeployed()) { + // don't run this if RD2 metadata is already deployed + return; + } + configureLegacyRDSettings(); STG_PanelHealthCheck_CTRL ctrl = new STG_PanelHealthCheck_CTRL(); @@ -69,6 +74,11 @@ private class STG_PanelRDHealthCheck_TEST { */ @IsTest private static void shouldValidateLegacyWithCustomInstallmentPeriods() { + if (isRD2MetadataDeployed()) { + // don't run this if RD2 metadata is already deployed + return; + } + npe03__Custom_Installment_Settings__c customInstallment = new npe03__Custom_Installment_Settings__c( npe03__Increment__c = 'Weeks', npe03__Value__c = 2, @@ -146,6 +156,7 @@ private class STG_PanelRDHealthCheck_TEST { @IsTest private static void shouldValidateLegacyPeriodPicklistEntries() { if (isRD2MetadataDeployed()) { + // don't run this if RD2 metadata is already deployed return; } diff --git a/force-app/main/domain/Addresses.cls b/force-app/main/domain/Addresses.cls index 71a316b9cb..66df58c03b 100644 --- a/force-app/main/domain/Addresses.cls +++ b/force-app/main/domain/Addresses.cls @@ -35,6 +35,9 @@ public inherited sharing class Addresses extends fflib_SObjects2 { private Map oldMap; + private static SfdoInstrumentationEnum.Action triggerAction; + private static Integer triggerCount; + private static Boolean isSeasonalAddressBatchMode = false; @TestVisible private TDTM_Runnable.DmlWrapper dmlWrapperLocal { @@ -70,10 +73,12 @@ public inherited sharing class Addresses extends fflib_SObjects2 { public Addresses(List addresses) { super(addresses, Address__c.SObjectType); + triggerCount = addresses.size(); } public Addresses(List addresses, List oldList) { super(addresses, Address__c.SObjectType); + triggerCount = addresses.size(); this.oldMap = oldList == NULL ? new Map() : new Map(oldList); @@ -86,6 +91,7 @@ public inherited sharing class Addresses extends fflib_SObjects2 { } public void onAfterInsert() { + triggerAction = SfdoInstrumentationEnum.Action.AfterInsert; syncAddressesForAccountsAndContacts(addressChangesToSyncToHouseholdAccountsAndContacts(), dmlWrapperLocal, false); @@ -110,7 +116,7 @@ public inherited sharing class Addresses extends fflib_SObjects2 { } public void onAfterUpdate() { - + triggerAction = SfdoInstrumentationEnum.Action.AfterUpdate; if (addressChangesToSyncToHouseholdAccountsAndContacts().size() > 0) { syncAddressesForAccountsAndContacts(addressChangesToSyncToHouseholdAccountsAndContacts(), dmlWrapperLocal, false); @@ -134,6 +140,7 @@ public inherited sharing class Addresses extends fflib_SObjects2 { } public void onAfterDelete() { + triggerAction = SfdoInstrumentationEnum.Action.AfterDelete; Map addressesByAccountId = addressesByAccountId(); if (!addressesByAccountId.isEmpty()) { clearAddressesForEachAccount(addressesByAccountId); @@ -206,6 +213,19 @@ public inherited sharing class Addresses extends fflib_SObjects2 { dmlWrapper.objectsToUpdate.addAll((List)addressAndRelationshipsToUpdate.contactsToUpdate); } + if ((isSeasonalAddressBatchMode || triggerAction != null) && dmlWrapper.objectsToUpdate.size() > 0) { + SfdoInstrumentationService.getInstance().log( + isSeasonalAddressBatchMode ? SfdoInstrumentationEnum.Feature.SeasonalAddresses : SfdoInstrumentationEnum.Feature.Addresses, + isSeasonalAddressBatchMode ? SfdoInstrumentationEnum.Component.Batch : SfdoInstrumentationEnum.Component.TriggerAction, + isSeasonalAddressBatchMode ? SfdoInstrumentationEnum.Action.Dml_Update : triggerAction, + new Map{ + 'AccountsToUpdate' => addressAndRelationshipsToUpdate.accountsToUpdate.size(), + 'ContactsToUpdate' => addressAndRelationshipsToUpdate.contactsToUpdate.size(), + 'AddressesToUpdate' => addressAndRelationshipsToUpdate.addressesToUpdate.size(), + 'SourceClass' => 'Addresses' + }, + triggerCount); + } return householdInfoByAccountId; } @@ -787,6 +807,9 @@ public inherited sharing class Addresses extends fflib_SObjects2 { return; } + isSeasonalAddressBatchMode = true; + triggerCount = listAcc.size(); + Map mapAccIdAddr = new Map(); for (Account acc : listAcc) { mapAccIdAddr.put(acc.Id, null); @@ -828,6 +851,8 @@ public inherited sharing class Addresses extends fflib_SObjects2 { syncAddressesForAccountsAndContacts(mapAccIdAddr, dmlWrapper, false); TDTM_TriggerHandler.processDML(dmlWrapper); TDTM_ProcessControl.setRecursionFlag(TDTM_ProcessControl.flag.ADDR_hasRunTrigger, false); + + isSeasonalAddressBatchMode = false; } /******************************************************************************************************* diff --git a/force-app/main/domain/Households.cls b/force-app/main/domain/Households.cls index 1512ab1b0b..a3a7e26b9a 100644 --- a/force-app/main/domain/Households.cls +++ b/force-app/main/domain/Households.cls @@ -363,6 +363,14 @@ public inherited sharing class Households extends fflib_SObjects2 { if (mapConAddrInsertNow.size() > 0) { UTIL_DMLService.insertRecords(mapConAddrInsertNow.values()); + + SfdoInstrumentationService.getInstance().log( + SfdoInstrumentationEnum.Feature.Addresses, + SfdoInstrumentationEnum.Component.TriggerAction, + SfdoInstrumentationEnum.Action.Dml_Insert, + new Map{ 'SourceClass' => 'Households' }, + mapConAddrInsertNow.size()); + // Since we're inserting new Addresses in a Before Insert/Update scenario, set the flag to // prevent the After Insert/Update Contact logic from executing when it's eventually called. TDTM_ProcessControl.setRecursionFlag(TDTM_ProcessControl.flag.ADDR_hasRunContactOnBefore, true); diff --git a/force-app/main/instrumentation/classes/SfdoInstrumentationEnum.cls b/force-app/main/instrumentation/classes/SfdoInstrumentationEnum.cls index dbcf708da3..62541f51ed 100644 --- a/force-app/main/instrumentation/classes/SfdoInstrumentationEnum.cls +++ b/force-app/main/instrumentation/classes/SfdoInstrumentationEnum.cls @@ -42,6 +42,7 @@ public with sharing class SfdoInstrumentationEnum { TDTM, ErrorHandling, Addresses, + SeasonalAddresses, GetStarted, AccountModelConversion, Settings, @@ -70,7 +71,8 @@ public with sharing class SfdoInstrumentationEnum { LeadConversion, RecordMerge, ContactMerge, - ManageHousehold + ManageHousehold, + HouseholdNaming } /** @@ -145,6 +147,7 @@ public with sharing class SfdoInstrumentationEnum { HouseholdNamingSettingsUpdated, HouseholdMerged, HouseholdMemberAdded, - HouseholdAddressChanged + HouseholdAddressChanged, + HouseholdNamesUpdated } } diff --git a/force-app/main/instrumentation/classes/SfdoInstrumentationMock_TEST.cls b/force-app/main/instrumentation/classes/SfdoInstrumentationMock_TEST.cls index 4273ea1c11..fff8a62836 100644 --- a/force-app/main/instrumentation/classes/SfdoInstrumentationMock_TEST.cls +++ b/force-app/main/instrumentation/classes/SfdoInstrumentationMock_TEST.cls @@ -54,11 +54,13 @@ public without sharing class SfdoInstrumentationMock_TEST { @TestVisible private class MockService implements StubProvider { + public List lastCallStack = new List(); + public SfdoInstrumentationEnum.Feature feature; public SfdoInstrumentationEnum.Component component; public SfdoInstrumentationEnum.Action actionName; public Integer value; - public Map context; + public Map context; public Object handleMethodCall(Object stubbedObject, String stubbedMethodName, Type returnType, List paramTypes, List paramNames, @@ -68,17 +70,41 @@ public without sharing class SfdoInstrumentationMock_TEST { this.feature = (SfdoInstrumentationEnum.Feature) params[0]; this.component = (SfdoInstrumentationEnum.Component)params[1]; this.actionName = (SfdoInstrumentationEnum.Action)params[2]; + this.value = null; + this.context = null; for (Integer n=3; n)params[n]; + this.context = (Map)params[n]; } } + this.lastCallStack.add(new LastCallData(this.feature, this.component, this.actionName, this.context, this.value)); } return null; } } + /** + * @description Class to store the last call data for all instrumentation calls, allow for deeper validation + */ + @TestVisible + private class LastCallData { + + public LastCallData(SfdoInstrumentationEnum.Feature feature, SfdoInstrumentationEnum.Component component, + SfdoInstrumentationEnum.Action actionName, Map context, Integer value) { + this.feature = feature; + this.component = component; + this.actionName = actionName; + this.value = value; + this.context = context; + } + + public SfdoInstrumentationEnum.Feature feature; + public SfdoInstrumentationEnum.Component component; + public SfdoInstrumentationEnum.Action actionName; + public Integer value; + public Map context; + } } diff --git a/force-app/main/instrumentation/classes/SfdoInstrumentationService.cls b/force-app/main/instrumentation/classes/SfdoInstrumentationService.cls index ef78650f4b..17d8541093 100644 --- a/force-app/main/instrumentation/classes/SfdoInstrumentationService.cls +++ b/force-app/main/instrumentation/classes/SfdoInstrumentationService.cls @@ -41,6 +41,9 @@ public inherited sharing class SfdoInstrumentationService { @TestVisible private static LastCallData lastCallData; + + @TestVisible + private static String requestQuiddity = getRequestQuiddity(); class LastCallData { public String lastFeatureName; @@ -109,6 +112,7 @@ public inherited sharing class SfdoInstrumentationService { * @param context Map of additional content as context to include in the log (DO NOT INCLUDE PII or NON-GPDR COMPLIANT DATA) */ public void log(SfdoInstrumentationEnum.Feature featureName, SfdoInstrumentationEnum.Component componentName, SfdoInstrumentationEnum.Action actionName, Map context) { + context = applyRequestQuiddity(context); SfdoLogUtils.log(featureName?.name(), componentName?.name(), actionName?.name(), context); lastCallData = new LastCallData(featureName?.name(), componentName?.name(), actionName?.name(), context); } @@ -121,6 +125,7 @@ public inherited sharing class SfdoInstrumentationService { * @param value Duration or other value to include in the log */ public void log(SfdoInstrumentationEnum.Feature featureName, SfdoInstrumentationEnum.Component componentName, SfdoInstrumentationEnum.Action actionName, Map context, Integer value) { + context = applyRequestQuiddity(context); SfdoLogUtils.log(featureName?.name(), componentName?.name(), actionName?.name(), context, value); lastCallData = new LastCallData(featureName?.name(), componentName?.name(), actionName?.name(), context, value); } @@ -132,8 +137,9 @@ public inherited sharing class SfdoInstrumentationService { * @param value Duration or other value to include in the log */ public void log(SfdoInstrumentationEnum.Feature featureName, SfdoInstrumentationEnum.Component componentName, SfdoInstrumentationEnum.Action actionName, Integer value) { - SfdoLogUtils.log(featureName?.name(), componentName?.name(), actionName?.name(), value); - lastCallData = new LastCallData(featureName?.name(), componentName?.name(), actionName?.name(), value); + Map context = applyRequestQuiddity(null); + SfdoLogUtils.log(featureName?.name(), componentName?.name(), actionName?.name(), context, value); + lastCallData = new LastCallData(featureName?.name(), componentName?.name(), actionName?.name(), context, value); } /** @@ -142,8 +148,9 @@ public inherited sharing class SfdoInstrumentationService { * @param actionName String - define the action of the feature or component */ public void log(SfdoInstrumentationEnum.Feature featureName, SfdoInstrumentationEnum.Component componentName, SfdoInstrumentationEnum.Action actionName) { - SfdoLogUtils.log(featureName?.name(), componentName?.name(), actionName?.name()); - lastCallData = new LastCallData(featureName?.name(), componentName?.name(), actionName?.name()); + Map context = applyRequestQuiddity(null); + SfdoLogUtils.log(featureName?.name(), componentName?.name(), actionName?.name(), context); + lastCallData = new LastCallData(featureName?.name(), componentName?.name(), actionName?.name(), context); } // ============================================================================================================================= @@ -157,6 +164,7 @@ public inherited sharing class SfdoInstrumentationService { * @param context Map of additional content as context to include in the log (DO NOT INCLUDE PII or NON-GPDR COMPLIANT DATA) */ public void log(SfdoInstrumentationEnum.Feature featureName, SObjectType objType, SfdoInstrumentationEnum.Action actionName, Map context) { + context = applyRequestQuiddity(context); SfdoLogUtils.log(featureName?.name(), String.valueOf(objType), actionName?.name(), context); lastCallData = new LastCallData(featureName?.name(), String.valueOf(objType), actionName?.name(), context); } @@ -169,6 +177,7 @@ public inherited sharing class SfdoInstrumentationService { * @param value Duration or other value to include in the log */ public void log(SfdoInstrumentationEnum.Feature featureName, SObjectType objType, SfdoInstrumentationEnum.Action actionName, Map context, Integer value) { + context = applyRequestQuiddity(context); SfdoLogUtils.log(featureName?.name(), String.valueOf(objType), actionName?.name(), context, value); lastCallData = new LastCallData(featureName?.name(), String.valueOf(objType), actionName?.name(), context, value); } @@ -180,8 +189,9 @@ public inherited sharing class SfdoInstrumentationService { * @param value Duration or other value to include in the log */ public void log(SfdoInstrumentationEnum.Feature featureName, SObjectType objType, SfdoInstrumentationEnum.Action actionName, Integer value) { - SfdoLogUtils.log(featureName?.name(), String.valueOf(objType), actionName?.name(), value); - lastCallData = new LastCallData(featureName?.name(), String.valueOf(objType), actionName?.name(), value); + Map context = applyRequestQuiddity(null); + SfdoLogUtils.log(featureName?.name(), String.valueOf(objType), actionName?.name(), context, value); + lastCallData = new LastCallData(featureName?.name(), String.valueOf(objType), actionName?.name(), context, value); } /** @@ -190,14 +200,46 @@ public inherited sharing class SfdoInstrumentationService { * @param actionName String - define the action of the feature or component */ public void log(SfdoInstrumentationEnum.Feature featureName, SObjectType objType, SfdoInstrumentationEnum.Action actionName) { - SfdoLogUtils.log(featureName?.name(), String.valueOf(objType), actionName?.name()); - lastCallData = new LastCallData(featureName?.name(), String.valueOf(objType), actionName?.name()); + Map context = applyRequestQuiddity(null); + SfdoLogUtils.log(featureName?.name(), String.valueOf(objType), actionName?.name(), context); + lastCallData = new LastCallData(featureName?.name(), String.valueOf(objType), actionName?.name(), context); } // ============================================================================================================================= // Helper Methods // ============================================================================================================================= + /** + * @description Retrieve the Quiddity of the current request + * @return String + */ + private static String getRequestQuiddity() { + try { + Request reqInfo = Request.getCurrent(); + String currentRequestId = reqInfo.getRequestId(); + Quiddity currentType = reqInfo.getQuiddity(); + return currentType.name(); + } catch (Exception e) { + return '(error)'; + } + } + + /** + * @description Always add the Request Quiddity to the context map + * @return Map + */ + private static Map applyRequestQuiddity(Map context) { + try { + if (context == null) { + context = new Map(); + } else { + context = new Map(context); + } + context.put('RequestQuiddity', requestQuiddity); + } catch (Exception e) { + } + return context; + } /** * @description Retrieve the Action Enum for a specific TriggerHandler Event Type * @param thisAction thisAction diff --git a/force-app/main/instrumentation/classes/SfdoInstrumentationService_TEST.cls b/force-app/main/instrumentation/classes/SfdoInstrumentationService_TEST.cls index bfbb859d00..ebc40c347d 100644 --- a/force-app/main/instrumentation/classes/SfdoInstrumentationService_TEST.cls +++ b/force-app/main/instrumentation/classes/SfdoInstrumentationService_TEST.cls @@ -85,25 +85,27 @@ public with sharing class SfdoInstrumentationService_TEST { @IsTest private static void shouldInstrumentActionWithContextMap() { - Map context = new Map{ 'Test' => System.currentTimeMillis()}; + Map context = new Map{ 'Test' => System.currentTimeMillis()}; SfdoInstrumentationService.getInstance().log( SfdoInstrumentationEnum.Feature.Donations, SfdoInstrumentationEnum.Component.Queueable, SfdoInstrumentationEnum.Action.Save, context); + context.put('RequestQuiddity', SfdoInstrumentationService.requestQuiddity); assertLastCallData(SfdoInstrumentationEnum.Feature.Donations, SfdoInstrumentationEnum.Component.Queueable, SfdoInstrumentationEnum.Action.Save, context); } @IsTest private static void shouldInstrumentActionWithMapAndValue() { Integer value = System.currentTimeMillis().intValue(); - Map context = new Map{ 'Test' => System.currentTimeMillis()}; + Map context = new Map{ 'Test' => System.currentTimeMillis()}; SfdoInstrumentationService.getInstance().log( SfdoInstrumentationEnum.Feature.Allocations, SfdoInstrumentationEnum.Component.Future, SfdoInstrumentationEnum.Action.ProcessedCount, context, value); + context.put('RequestQuiddity', SfdoInstrumentationService.requestQuiddity); assertLastCallData(SfdoInstrumentationEnum.Feature.Allocations, SfdoInstrumentationEnum.Component.Future, SfdoInstrumentationEnum.Action.ProcessedCount, context, value); } @@ -119,13 +121,14 @@ public with sharing class SfdoInstrumentationService_TEST { @IsTest private static void shouldInstrumentActionWithSObjectAndContextMap() { - Map context = new Map{ 'Test' => System.currentTimeMillis()}; + Map context = new Map{ 'Test' => System.currentTimeMillis()}; SfdoInstrumentationService.getInstance().log( SfdoInstrumentationEnum.Feature.TDTM, General_Accounting_Unit__c.getSObjectType(), SfdoInstrumentationEnum.Action.BeforeUpdate, context, 25); + context.put('RequestQuiddity', SfdoInstrumentationService.requestQuiddity); assertLastCallData(SfdoInstrumentationEnum.Feature.TDTM, General_Accounting_Unit__c.getSObjectType(), SfdoInstrumentationEnum.Action.BeforeUpdate, context, 25); } @@ -140,12 +143,13 @@ public with sharing class SfdoInstrumentationService_TEST { @IsTest private static void shouldInstrumentActionWithSObjectContextMap() { - Map context = new Map{ 'Test' => System.currentTimeMillis()}; + Map context = new Map{ 'Test' => System.currentTimeMillis()}; SfdoInstrumentationService.getInstance().log( SfdoInstrumentationEnum.Feature.Donations, Opportunity.getSObjectType(), SfdoInstrumentationEnum.Action.Open, context); + context.put('RequestQuiddity', SfdoInstrumentationService.requestQuiddity); assertLastCallData(SfdoInstrumentationEnum.Feature.Donations, Opportunity.getSObjectType(), SfdoInstrumentationEnum.Action.Open, context); } @@ -157,13 +161,13 @@ public with sharing class SfdoInstrumentationService_TEST { System.assertEquals(action.name(), SfdoInstrumentationService.lastCallData.lastActionName); System.assertEquals(value, SfdoInstrumentationService.lastCallData.lastValue); } - static void assertLastCallData(SfdoInstrumentationEnum.Feature feature, SfdoInstrumentationEnum.Component component, SfdoInstrumentationEnum.Action action, Map context) { + static void assertLastCallData(SfdoInstrumentationEnum.Feature feature, SfdoInstrumentationEnum.Component component, SfdoInstrumentationEnum.Action action, Map context) { System.assertEquals(feature.name(), SfdoInstrumentationService.lastCallData.lastFeatureName); System.assertEquals(component.name(), SfdoInstrumentationService.lastCallData.lastComponentName); System.assertEquals(action.name(), SfdoInstrumentationService.lastCallData.lastActionName); System.assertEquals(context, SfdoInstrumentationService.lastCallData.lastContext); } - static void assertLastCallData(SfdoInstrumentationEnum.Feature feature, SfdoInstrumentationEnum.Component component, SfdoInstrumentationEnum.Action action, Map context, Integer value) { + static void assertLastCallData(SfdoInstrumentationEnum.Feature feature, SfdoInstrumentationEnum.Component component, SfdoInstrumentationEnum.Action action, Map context, Integer value) { System.assertEquals(feature.name(), SfdoInstrumentationService.lastCallData.lastFeatureName); System.assertEquals(component.name(), SfdoInstrumentationService.lastCallData.lastComponentName); System.assertEquals(action.name(), SfdoInstrumentationService.lastCallData.lastActionName); @@ -186,14 +190,14 @@ public with sharing class SfdoInstrumentationService_TEST { System.assertEquals(action.name(), SfdoInstrumentationService.lastCallData.lastActionName); System.assertEquals(value, SfdoInstrumentationService.lastCallData.lastValue); } - static void assertLastCallData(SfdoInstrumentationEnum.Feature feature, SObjectType objType, SfdoInstrumentationEnum.Action action, Map context, Integer value) { + static void assertLastCallData(SfdoInstrumentationEnum.Feature feature, SObjectType objType, SfdoInstrumentationEnum.Action action, Map context, Integer value) { System.assertEquals(feature.name(), SfdoInstrumentationService.lastCallData.lastFeatureName); System.assertEquals(String.valueOf(objType), SfdoInstrumentationService.lastCallData.lastComponentName); System.assertEquals(action.name(), SfdoInstrumentationService.lastCallData.lastActionName); System.assertEquals(context, SfdoInstrumentationService.lastCallData.lastContext); System.assertEquals(value, SfdoInstrumentationService.lastCallData.lastValue); } - static void assertLastCallData(SfdoInstrumentationEnum.Feature feature, SObjectType objType, SfdoInstrumentationEnum.Action action, Map context) { + static void assertLastCallData(SfdoInstrumentationEnum.Feature feature, SObjectType objType, SfdoInstrumentationEnum.Action action, Map context) { System.assertEquals(feature.name(), SfdoInstrumentationService.lastCallData.lastFeatureName); System.assertEquals(String.valueOf(objType), SfdoInstrumentationService.lastCallData.lastComponentName); System.assertEquals(action.name(), SfdoInstrumentationService.lastCallData.lastActionName); diff --git a/force-app/main/selector/ContactMergeSelector.cls b/force-app/main/selector/ContactMergeSelector.cls index 2ef6ce522c..bd79a2ee20 100644 --- a/force-app/main/selector/ContactMergeSelector.cls +++ b/force-app/main/selector/ContactMergeSelector.cls @@ -107,6 +107,7 @@ public with sharing class ContactMergeSelector { SfdoInstrumentationEnum.Feature.ContactMerge, SfdoInstrumentationEnum.Component.Page, SfdoInstrumentationEnum.Action.DuplicateRecordSetResultCount, + new Map{ 'SourceClass' => 'ContactMergeSelector' }, results.size()); return results; diff --git a/force-app/main/service/HouseholdNamingService.cls b/force-app/main/service/HouseholdNamingService.cls index dd99cb522b..00ba801cb0 100644 --- a/force-app/main/service/HouseholdNamingService.cls +++ b/force-app/main/service/HouseholdNamingService.cls @@ -79,6 +79,11 @@ public without sharing class HouseholdNamingService { set; } + // Track these for instrumentation + private Integer numHouseholdNamesSet = 0; + private Integer numFormalGreetingsSet = 0; + private Integer numInformalGreetingsSet = 0; + /******************************************************************************************************* * @description turns off household naming in the current execution context. provided for other * components, like Batch Data Import, to momentarily turn off the household naming logic. there is no @@ -144,6 +149,31 @@ public without sharing class HouseholdNamingService { unitOfWork.save(); + // Instrumentation + if (numHouseholdNamesSet > 0 || numFormalGreetingsSet > 0 || numInformalGreetingsSet > 0) { + Map context = new Map{ + 'SourceClass' => 'HouseholdNamingService' + }; + if (numHouseholdNamesSet > 0) { + context.put('Household Names Updated', numHouseholdNamesSet); + } + if (numFormalGreetingsSet > 0) { + context.put('Formal Greetings Updated', numFormalGreetingsSet); + } + if (numInformalGreetingsSet > 0) { + context.put('Informal Greetings Updated', numInformalGreetingsSet); + } + SfdoInstrumentationService.getInstance().log( + SfdoInstrumentationEnum.Feature.HouseholdNaming, + SfdoInstrumentationEnum.Component.TriggerAction, + SfdoInstrumentationEnum.Action.HouseholdNamesUpdated, + context, + householdsOrAccounts.size()); + numHouseholdNamesSet = 0; + numFormalGreetingsSet = 0; + numInformalGreetingsSet = 0; + } + TDTM_ProcessControl.setRecursionFlag(TDTM_ProcessControl.flag.HH, false); } @@ -448,6 +478,7 @@ public without sharing class HouseholdNamingService { unitOfWork.registerDirty(new List{ household }); + numHouseholdNamesSet++; } if (!namingOverrides.isFormalGreetingControlledByUser() && @@ -456,6 +487,7 @@ public without sharing class HouseholdNamingService { unitOfWork.registerDirty(new List{ household }); + numFormalGreetingsSet++; } if (!namingOverrides.isInformalGreetingControlledByUser() && informalGreetingNeedsUpdate(household, householdName)) { @@ -463,6 +495,7 @@ public without sharing class HouseholdNamingService { unitOfWork.registerDirty(new List{ household }); + numInformalGreetingsSet++; } } diff --git a/force-app/main/service/HouseholdService.cls b/force-app/main/service/HouseholdService.cls index 69ba9f00ab..ac1edd0476 100644 --- a/force-app/main/service/HouseholdService.cls +++ b/force-app/main/service/HouseholdService.cls @@ -91,6 +91,11 @@ public inherited sharing class HouseholdService { set; } + // Track these for instrumentation + private Integer numHouseholdNamesSet = 0; + private Integer numFormalGreetingsSet = 0; + private Integer numInformalGreetingsSet = 0; + public Set fieldsUsedForHouseholdNaming() { return householdNamingServiceInst.getHouseholdNamingContactFields(); } @@ -395,6 +400,30 @@ public inherited sharing class HouseholdService { ); } } + + if (accountsToInsert.size() > 0 && (numHouseholdNamesSet > 0 || numFormalGreetingsSet > 0 || numInformalGreetingsSet > 0)) { + Map context = new Map{ + 'SourceClass' => 'HouseholdService' + }; + if (numHouseholdNamesSet > 0) { + context.put('Household Names Updated', numHouseholdNamesSet); + } + if (numFormalGreetingsSet > 0) { + context.put('Formal Greetings Updated', numFormalGreetingsSet); + } + if (numInformalGreetingsSet > 0) { + context.put('Informal Greetings Updated', numInformalGreetingsSet); + } + SfdoInstrumentationService.getInstance().log( + SfdoInstrumentationEnum.Feature.HouseholdNaming, + SfdoInstrumentationEnum.Component.TriggerAction, + SfdoInstrumentationEnum.Action.HouseholdNamesUpdated, + context, + accountsToInsert.size()); + numHouseholdNamesSet = 0; + numFormalGreetingsSet = 0; + numInformalGreetingsSet = 0; + } } private void insertNewHouseholds(List accountsToInsert, List contactRecords) { @@ -494,10 +523,13 @@ public inherited sharing class HouseholdService { contactRecord })); accountRecord.Name = householdName.asName(); + numHouseholdNamesSet++; accountRecord.npo02__Formal_Greeting__c = householdName.asFormalGreeting(); + if (accountRecord.npo02__Formal_Greeting__c != null) numFormalGreetingsSet++; accountRecord.npo02__Informal_Greeting__c = householdName.asInformalGreeting(); + if (accountRecord.npo02__Informal_Greeting__c != null) numInformalGreetingsSet++; } else { accountRecord.Name = Households.strNameHHAccountForContact(contactRecord); diff --git a/force-app/test/ADDR_Addresses_TEST.cls b/force-app/test/ADDR_Addresses_TEST.cls index 29c08a6e24..575c44c167 100644 --- a/force-app/test/ADDR_Addresses_TEST.cls +++ b/force-app/test/ADDR_Addresses_TEST.cls @@ -185,6 +185,9 @@ public with sharing class ADDR_Addresses_TEST { npe01__Contacts_And_Orgs_Settings__c contactSettingsForTests = UTIL_CustomSettingsFacade.getContactsSettings(); + // disable household naming so that its instrumentation doesn't interfere with the test + UTIL_UnitTestData_TEST.turnOffAutomaticHHNaming(); + testContacts = UTIL_UnitTestData_TEST.createMultipleTestContacts(totalContactsToCreate); for (Contact con : testContacts) { con.MailingStreet = 'new street'; @@ -216,6 +219,15 @@ public with sharing class ADDR_Addresses_TEST { for (Address__c addr : listAddr) { System.assertEquals('Other', addr.Address_Type__c); } + + System.assertEquals(SfdoInstrumentationEnum.Feature.Addresses.name(), SfdoInstrumentationService.lastCallData.lastFeatureName, + 'The Instrumentation LastFeatureName should be Addresses'); + System.assertEquals(SfdoInstrumentationEnum.Component.TriggerAction.name(), SfdoInstrumentationService.lastCallData.lastComponentName, + 'The Instrumentation LastComponentName should be TriggerAction'); + System.assertEquals(SfdoInstrumentationEnum.Action.Dml_Insert.name(), SfdoInstrumentationService.lastCallData.lastActionName, + 'The Instrumentation LastActionName should be DmlInsert'); + System.assertEquals(totalContactsToCreate, SfdoInstrumentationService.lastCallData.lastValue, + 'The Instrumentation LastValue should be ' + totalContactsToCreate); } /********************************************************************************************************* diff --git a/force-app/test/HouseholdNamingService_TEST.cls b/force-app/test/HouseholdNamingService_TEST.cls index f53c31705d..e018d2d4ac 100644 --- a/force-app/test/HouseholdNamingService_TEST.cls +++ b/force-app/test/HouseholdNamingService_TEST.cls @@ -157,6 +157,13 @@ public class HouseholdNamingService_TEST { system.assertEquals('FirstName0',con.npo02__household__r.npo02__Informal_Greeting__c); system.assert(con.npo02__household__r.npo02__Formal_greeting__c.endsWith('FirstName0 LastName0')); + System.assertEquals(SfdoInstrumentationEnum.Feature.HouseholdNaming.name(), SfdoInstrumentationService.lastCallData.lastFeatureName); + System.assertEquals(SfdoInstrumentationEnum.Component.TriggerAction.name(), SfdoInstrumentationService.lastCallData.lastComponentName); + System.assertEquals(SfdoInstrumentationEnum.Action.HouseholdNamesUpdated.name(), SfdoInstrumentationService.lastCallData.lastActionName); + System.assertEquals('HouseholdNamingService', SfdoInstrumentationService.lastCallData.lastContext.get('SourceClass')); + System.assertEquals(20, (Integer)SfdoInstrumentationService.lastCallData.lastContext.get('Informal Greetings Updated')); + System.assertEquals(20, (Integer)SfdoInstrumentationService.lastCallData.lastContext.get('Formal Greetings Updated')); + System.assertEquals(20, SfdoInstrumentationService.lastCallData.lastValue); } /********************************************************************************************************* @@ -873,7 +880,7 @@ public class HouseholdNamingService_TEST { // Verify the household name was still automatically generated System.assertEquals('Test Contact Household', household.Name, - 'Household name should still be auto-generated: ' + household.Name); + 'Household name should still be auto-generated: ' + household.Name); } @@ -922,12 +929,18 @@ public class HouseholdNamingService_TEST { System.assertEquals('Name', household.npo02__SYSTEM_CUSTOM_NAMING__c, 'SYSTEM_CUSTOM_NAMING should indicate name is user-controlled: ' + household.npo02__SYSTEM_CUSTOM_NAMING__c); + SfdoInstrumentationService.instance = null; // reset the instance + // Now simulate subsequent updates that should NOT revert the name household.Phone = '555-5678'; update household; + + System.assertEquals(null, SfdoInstrumentationService.instance, 'The Instrumentation Service instance should be null'); household.Website = 'www.test.com'; update household; + + System.assertEquals(null, SfdoInstrumentationService.instance, 'The Instrumentation Service instance should be null'); Test.stopTest(); @@ -980,6 +993,8 @@ public class HouseholdNamingService_TEST { con.FirstName = 'Jane'; con.LastName = 'Smith'; update con; + + SfdoInstrumentationService.instance = null; // reset the instance // Trigger household naming service explicitly to simulate what would happen in real scenarios HouseholdNamingService service = new HouseholdNamingService(); @@ -987,6 +1002,8 @@ public class HouseholdNamingService_TEST { Test.stopTest(); + System.assertEquals(null, SfdoInstrumentationService.instance, 'The Instrumentation Service instance should be null'); + // Verify the household name DID NOT change despite the contact name change household = [SELECT Id, Name, npo02__SYSTEM_CUSTOM_NAMING__c FROM Account WHERE Id = :household.Id]; System.assertEquals(customName, household.Name,