diff --git a/sfdx-source/apex-extensions/main/triggerHandler/classes/fflib_TriggerHandler.cls b/sfdx-source/apex-extensions/main/triggerHandler/classes/fflib_TriggerHandler.cls index e3a6a7c..40b669b 100644 --- a/sfdx-source/apex-extensions/main/triggerHandler/classes/fflib_TriggerHandler.cls +++ b/sfdx-source/apex-extensions/main/triggerHandler/classes/fflib_TriggerHandler.cls @@ -32,6 +32,23 @@ public virtual with sharing class fflib_TriggerHandler { public static final System.Type DEFAUT_TRIGGERCONTEXT_TYPE = fflib_TriggerContext.class; + /** + * Retains the trigger tracking configuration used for each domain + **/ + private static Map triggerEventByClass; + private static Boolean disabled = false; + + /** + * Retain instance of Trigger Action classes implementing stateful + */ + @TestVisible + private static Map triggerActionStateByClass; + + static + { + triggerEventByClass = new Map(); + } + @TestVisible protected System.Type triggerContextType { @@ -48,12 +65,6 @@ public virtual with sharing class fflib_TriggerHandler protected fflib_ITriggerContext triggerContext; - /** - * Retain instance of Trigger Action classes implementing stateful - */ - @TestVisible - private static Map triggerActionStateByClass; - /** * Provides access to the trigger action configurations and allowing it to be mocked in unit-tests */ @@ -65,11 +76,28 @@ public virtual with sharing class fflib_TriggerHandler */ public void run() { + if (fflib_TriggerHandler.disabled) return; + loadConfiguration(); fflib_ITriggerContext ctx = getTriggerContext(); execute(ctx); } + public static void disableTrigger() + { + fflib_TriggerHandler.disabled = true; + } + + public static fflib_SObjectDomain.TriggerEvent getTriggerEvent(Type triggerActionClass) + { + if(!triggerEventByClass.containsKey(triggerActionClass)) + { + triggerEventByClass.put(triggerActionClass, new fflib_SObjectDomain.TriggerEvent()); + } + + return triggerEventByClass.get(triggerActionClass); + } + /** * Tells the trigger handler in which trigger context it is running * @@ -109,7 +137,11 @@ public virtual with sharing class fflib_TriggerHandler { if (isValidExecutionContext(ctx, triggerActionConfig) == false || - isValidSObjectType(triggerActionConfig, ctx) == false) continue; + isValidSObjectType(triggerActionConfig, ctx) == false + || + !getTriggerEvent(triggerActionConfig.getImplementationType()) + .isEnabled(ctx.isBefore(), ctx.isAfter(), ctx.isInsert(), ctx.isUpdate(), ctx.isDelete(), ctx.isUndelete())) + continue; fflib_ITriggerAction triggerAction = getTriggerActionInstance(triggerActionConfig); diff --git a/sfdx-source/apex-extensions/tests/classes/triggerHandler/fflib_TriggerHandlerTest.cls b/sfdx-source/apex-extensions/tests/classes/triggerHandler/fflib_TriggerHandlerTest.cls index 0be6b87..053a8db 100644 --- a/sfdx-source/apex-extensions/tests/classes/triggerHandler/fflib_TriggerHandlerTest.cls +++ b/sfdx-source/apex-extensions/tests/classes/triggerHandler/fflib_TriggerHandlerTest.cls @@ -256,7 +256,6 @@ private class fflib_TriggerHandlerTest private static void itShouldUseTheStatefulTriggerActionClass() { fflib_LogEntry__c record = new fflib_LogEntry__c(LogLevel__c = 'INFO', Message__c = 'Unit Test'); - List records = new List {record}; fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_ITriggerAction triggerActionMock = (fflib_ITriggerAction) mocks.mock(fflib_ITriggerAction.class); @@ -296,6 +295,42 @@ private class fflib_TriggerHandlerTest ((fflib_ITriggerAction) mocks.verify(triggerActionMock)).doWork(); } + @IsTest + private static void itShouldNotExecuteBeforeDelete() + { + fflib_LogEntry__c record = new fflib_LogEntry__c(LogLevel__c = 'INFO', Message__c = 'Unit Test'); + + fflib_TriggerHandler.triggerActionStateByClass = + new Map{ MyTriggerBypassedAction.class => new MyTriggerBypassedAction() }; + + fflib_TriggerAction__mdt triggerAction = new fflib_TriggerAction__mdt( + ObjectType__c = null, + ObjectTypeAlternate__c = Schema.fflib_LogEntry__c.SObjectType.getDescribe().getName(), + BeforeDelete__c = true, + ImplementationType__c = 'fflib_TriggerHandlerTest.MyTriggerBypassedAction', + ExecutionContext__c = 'Realtime', + Stateful__c = true + ); + + fflib_TriggerHandler triggerHandler = new fflib_TriggerHandler(); + String ctxClassName = triggerHandler.triggerContextType.getName() + '.Constructor'; + fflib_TriggerContext ctx = + (fflib_TriggerContext) + ((fflib_IDomainConstructor) Type.forName(ctxClassName).newInstance()) + .construct(new List {record}); + ctx.triggerOperation = System.TriggerOperation.BEFORE_DELETE; + + // WHEN a record is inserted + System.Test.startTest(); + triggerHandler.addTriggerActionConfig(triggerAction); + + // Setting bypass & run trigger + fflib_TriggerHandler.getTriggerEvent(MyTriggerBypassedAction.class).disableAll(); + triggerHandler.setTriggerContext(ctx).run(); + + System.Test.stopTest(); + } + public class MyTriggerAction extends fflib_TriggerAction // Todo - rename handler to action { public override void onBeforeInsert() @@ -305,4 +340,12 @@ private class fflib_TriggerHandlerTest List records = triggerContext.getRecords(); } } + + public class MyTriggerBypassedAction extends fflib_TriggerAction + { + public override void onBeforeDelete() + { + System.Assert.fail('It should not have reach this point'); + } + } } \ No newline at end of file