From 9395e08df79629b98258ac1db2bf43ad224a5402 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 12 Sep 2024 14:52:25 -0400 Subject: [PATCH] [WIP] --- .../logger-engine/classes/CallableLogger.cls | 154 +++--------------- .../classes/CallableLogger_Tests.cls | 106 ++++++++---- 2 files changed, 102 insertions(+), 158 deletions(-) diff --git a/nebula-logger/core/main/logger-engine/classes/CallableLogger.cls b/nebula-logger/core/main/logger-engine/classes/CallableLogger.cls index 3be000605..199134d00 100644 --- a/nebula-logger/core/main/logger-engine/classes/CallableLogger.cls +++ b/nebula-logger/core/main/logger-engine/classes/CallableLogger.cls @@ -44,27 +44,25 @@ global without sharing class CallableLogger implements System.Callable { CallableHandler handler; Map input; Map output; - if (isOmniStudioCall(arguments)) { + // if (isOmniStudioCall(arguments)) { + if (arguments.containsKey(OMNISTUDIO_ARGUMENT_INPUT) || arguments.containsKey(OMNISTUDIO_ARGUMENT_OUTPUT)) { handler = new OmniStudioCallableHandler(); input = (Map) arguments.get(OMNISTUDIO_ARGUMENT_INPUT); output = (Map) arguments.get(OMNISTUDIO_ARGUMENT_OUTPUT); } else { - handler = new BaseCallableHandler(); - input = new Map(); + handler = new StandardCallableHandler(); + input = arguments; output = new Map(); } - return handler.handleCall(action, input, output); + + handler.handleCall(action, input, output); + + return output; } + @SuppressWarnings('PMD.ApexDoc') private abstract class CallableHandler { - public virtual Object handleCall(String action, Map input, Map output) { - return 'TODO'; - } - - public virtual Object handleCall(String action, Map arguments) { - // TODO consider always returning a Map for all methods - // And in the case of OmniStudio, its `output` Map would be the return value - Map output = new Map(); + public virtual void handleCall(String action, Map input, Map output) { Boolean isSuccess = true; String errorMessage; @@ -76,23 +74,22 @@ global without sharing class CallableLogger implements System.Callable { when 'getParentLogTransactionId' { output.put(ARGUMENT_PARENT_LOG_TRANSACTION_ID, Logger.getParentLogTransactionId()); } - when 'setparentlogTransactionId' { - Logger.setParentLogTransactionId((String) arguments.get(ARGUMENT_PARENT_LOG_TRANSACTION_ID)); + when 'setParentLogTransactionId' { + Logger.setParentLogTransactionId((String) input.get(ARGUMENT_PARENT_LOG_TRANSACTION_ID)); } // Methods for scenario-based logging when 'getScenario' { output.put(ARGUMENT_SCENARIO, Logger.getScenario()); } when 'setScenario' { - Logger.setScenario((String) arguments.get(ARGUMENT_SCENARIO)); + Logger.setScenario((String) input.get(ARGUMENT_SCENARIO)); } when 'endScenario' { - Logger.endScenario((String) arguments.get(ARGUMENT_SCENARIO)); + Logger.endScenario((String) input.get(ARGUMENT_SCENARIO)); } when else { isSuccess = false; errorMessage = 'Unsupported action: ' + action; - // throw new System.IllegalArgumentException('Unsupported action: ' + action); } } @@ -100,22 +97,6 @@ global without sharing class CallableLogger implements System.Callable { if (String.isNotBlank(errorMessage)) { output.put(OUTPUT_ARGUMENT_CALL_ERROR_MESSAGE, errorMessage); } - - return output; - } - - public virtual void getCleansedArguments(Map originalArguments) { - // TODO figure out how to convert/parse OmniStudio parameters - // https://help.salesforce.com/s/articleView?id=sf.os_callable_implementations.htm&type=5 - - originalArguments = originalArguments ?? new Map(); - originalArguments.remove(null); - - Map cleansedArguments = new Map(); - for (String key : originalArguments.keySet()) { - cleansedArguments.put(key, originalArguments.get(key)); - } - // return cleansedArguments; } protected LogEntryEventBuilder newEntry(Map arguments) { @@ -157,51 +138,35 @@ global without sharing class CallableLogger implements System.Callable { // Handler used when Apex developers/ISVs/package creators are directly creating // interacting with `CallableLogger` (i.e., anyone not using this for OmniStudio) - private class BaseCallableHandler extends CallableHandler { - public override void getCleansedArguments(Map originalArguments) { - // return null; - } - - public override Object handleCall(String action, Map arguments) { - this.getCleansedArguments(arguments); - // arguments = this.getCleansedArguments(arguments); - - Map output; + @SuppressWarnings('PMD.ApexDoc') + private class StandardCallableHandler extends CallableHandler { + public override void handleCall(String action, Map input, Map output) { switch on action { // Methods for adding entries & saving when 'newEntry' { - return this.newEntry(arguments); + this.newEntry(input); + output.put(OUTPUT_ARGUMENT_CALL_IS_SUCCESS, true); } when 'saveLog' { // System.debug('>>> action: ' + action); - // System.debug('>>> arguments: ' + System.JSON.serializePretty(arguments)); - // String stuff = '>>> action: ' + action + '\n' + '>>> arguments: ' + System.JSON.serializePretty(arguments); + // System.debug('>>> input: ' + System.JSON.serializePretty(input)); + // String stuff = '>>> action: ' + action + '\n' + '>>> input: ' + System.JSON.serializePretty(input); // System.Assert.fail('>>> stuff: ' + stuff); - this.saveLog(arguments); - return new Map{ OUTPUT_ARGUMENT_CALL_IS_SUCCESS => true }; + this.saveLog(input); + output.put(OUTPUT_ARGUMENT_CALL_IS_SUCCESS, true); } when else { - return super.handleCall(action, arguments); + super.handleCall(action, input, output); } } } } // Handler used when OmniStudio designers & developers are using `CallableLogger` for logging in OmniStudio + @SuppressWarnings('PMD.ApexDoc') private class OmniStudioCallableHandler extends CallableHandler { - public override void getCleansedArguments(Map originalArguments) { - // return null; - } - - public override Object handleCall(String action, Map originalArguments) { - Map input = (Map) originalArguments.get(OMNISTUDIO_ARGUMENT_INPUT); - Map output = (Map) originalArguments.get(OMNISTUDIO_ARGUMENT_OUTPUT); - // Map options = (Map) originalArguments.get(OMNISTUDIO_ARGUMENT_OPTIONS); - - input = input ?? new Map(); - output = output ?? new Map(); - + public override void handleCall(String action, Map input, Map output) { switch on action { // TODO revisit if using 'addnewentry' and ''addnewentry' is the best approach for OmniStudio: // - For omniscripts, there's no state, so calling saveLog() doesn't make sense @@ -216,24 +181,9 @@ global without sharing class CallableLogger implements System.Callable { output.put(OUTPUT_ARGUMENT_CALL_IS_SUCCESS, true); } when else { - System.Assert.fail(); - output.putAll((Map) super.handleCall(action, input)); + super.handleCall(action, input, output); } } - - Map convertedArguments = new Map(); - - return output; - } - - private Map convertOmniScriptArguments(Map originalArguments) { - Map convertedArguments = new Map(); - - Map input = (Map) originalArguments.get(OMNISTUDIO_ARGUMENT_INPUT); - Map output = (Map) originalArguments.get(OMNISTUDIO_ARGUMENT_OUTPUT); - Map options = (Map) originalArguments.get(OMNISTUDIO_ARGUMENT_OPTIONS); - - return null; } } @@ -241,54 +191,4 @@ global without sharing class CallableLogger implements System.Callable { private Boolean isOmniStudioCall(Map arguments) { return arguments.containsKey(OMNISTUDIO_ARGUMENT_INPUT) || arguments.containsKey(OMNISTUDIO_ARGUMENT_OUTPUT); } - - private Map getCleansedArguments(Map originalArguments) { - // TODO figure out how to convert/parse OmniStudio parameters - // https://help.salesforce.com/s/articleView?id=sf.os_callable_implementations.htm&type=5 - - originalArguments = originalArguments ?? new Map(); - originalArguments.remove(null); - - Map cleansedArguments = new Map(); - for (String key : originalArguments.keySet()) { - cleansedArguments.put(key, originalArguments.get(key)); - } - return cleansedArguments; - } - - // private LogEntryEventBuilder newEntry(Map arguments) { - // // The value of loggingLevel could be either a string name or enum value, - // // so coerce it to a string for consistency - // String loggingLevelName = '' + arguments.get(ARGUMENT_LOGGING_LEVEL); - // System.LoggingLevel loggingLevel = Logger.getLoggingLevel(loggingLevelName); - // String message = (String) arguments.get(ARGUMENT_MESSAGE); - - // LogEntryEventBuilder logEntryEventBuilder = Logger.newEntry(loggingLevel, message); - - // if (arguments.containsKey(ARGUMENT_EXCEPTION)) { - // logEntryEventBuilder.setExceptionDetails((System.Exception) arguments.get(ARGUMENT_EXCEPTION)); - // } - // if (arguments.containsKey(ARGUMENT_RECORD_ID)) { - // logEntryEventBuilder.setRecord((String) arguments.get(ARGUMENT_RECORD_ID)); - // } - // if (arguments.containsKey(ARGUMENT_RECORD)) { - // logEntryEventBuilder.setRecord((SObject) arguments.get(ARGUMENT_RECORD)); - // } - // if (arguments.containsKey(ARGUMENT_RECORD_LIST)) { - // logEntryEventBuilder.setRecord((List) arguments.get(ARGUMENT_RECORD_LIST)); - // } - // if (arguments.containsKey(ARGUMENT_RECORD_MAP)) { - // logEntryEventBuilder.setRecord((Map) arguments.get(ARGUMENT_RECORD_MAP)); - // } - // if (arguments.containsKey(ARGUMENT_TAGS)) { - // logEntryEventBuilder.addTags((List) arguments.get(ARGUMENT_TAGS)); - // } - - // return logEntryEventBuilder; - // } - - // private void saveLog(Map arguments) { - // String saveMethodName = ((String) arguments.get(ARGUMENT_SAVE_METHOD_NAME)) ?? Logger.getUserSettings().DefaultSaveMethod__c; - // Logger.saveLog(saveMethodName); - // } } diff --git a/nebula-logger/core/tests/logger-engine/classes/CallableLogger_Tests.cls b/nebula-logger/core/tests/logger-engine/classes/CallableLogger_Tests.cls index 3d9664c6d..fbd026111 100644 --- a/nebula-logger/core/tests/logger-engine/classes/CallableLogger_Tests.cls +++ b/nebula-logger/core/tests/logger-engine/classes/CallableLogger_Tests.cls @@ -7,7 +7,7 @@ @IsTest(IsParallel=true) private class CallableLogger_Tests { @IsTest - static void it_returns_error_message_for_unsupported_action() { + static void it_returns_error_message_for_unsupported_action_when_using_standard_approach() { String fakeActionName = 'some-action-that-will-never-exist-i-hope'; System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); @@ -19,7 +19,7 @@ private class CallableLogger_Tests { } @IsTest - static void it_returns_error_message_for_unsupported_action_when_running_in_omnistudio() { + static void it_returns_error_message_for_unsupported_action_when_using_omnistudio_approach() { String fakeActionName = 'some-action-that-will-never-exist-i-hope'; Map omnistudioOutput = new Map(); @@ -32,7 +32,7 @@ private class CallableLogger_Tests { } @IsTest - static void it_gets_transaction_id() { + static void it_gets_transaction_id_when_using_standard_approach() { System.Assert.isNotNull(Logger.getTransactionId(), 'Test has started under the wrong conditions'); System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); @@ -44,7 +44,7 @@ private class CallableLogger_Tests { } @IsTest - static void it_gets_transaction_id_when_running_in_omnistudio() { + static void it_gets_transaction_id_when_using_omnistudio_approach() { System.Assert.isNotNull(Logger.getTransactionId(), 'Test has started under the wrong conditions'); Map omnistudioOutput = new Map(); @@ -57,7 +57,7 @@ private class CallableLogger_Tests { } @IsTest - static void it_gets_parent_log_transaction_id() { + static void it_gets_parent_log_transaction_id_when_using_standard_approach() { String mockParentLogTransactionId = 'some transaction id'; Logger.setParentLogTransactionId(mockParentLogTransactionId); System.Assert.areEqual(mockParentLogTransactionId, Logger.getParentLogTransactionId(), 'Test has started under the wrong conditions'); @@ -70,96 +70,140 @@ private class CallableLogger_Tests { System.Assert.areEqual(mockParentLogTransactionId, returnedOutput.get('parentLogTransactionId')); } - // TODO refactor below tests + add omnistudio equivalent for all of them @IsTest - static void it_sets_parent_log_transaction_id() { + static void it_gets_parent_log_transaction_id_when_using_omnistudio_approach() { + String mockParentLogTransactionId = 'some transaction id'; + Logger.setParentLogTransactionId(mockParentLogTransactionId); + System.Assert.areEqual(mockParentLogTransactionId, Logger.getParentLogTransactionId(), 'Test has started under the wrong conditions'); + Map omnistudioOutput = new Map(); + + System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); + callableLoggerInstance.call('getParentLogTransactionId', new Map{ 'output' => omnistudioOutput }); + + System.Assert.areEqual(2, omnistudioOutput.size()); + System.Assert.areEqual(true, omnistudioOutput.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + omnistudioOutput); + System.Assert.areEqual(mockParentLogTransactionId, omnistudioOutput.get('parentLogTransactionId')); + } + + @IsTest + static void it_sets_parent_log_transaction_id_when_using_standard_approach() { System.Assert.isNull(Logger.getParentLogTransactionId(), 'Test has started under the wrong conditions'); String mockParentLogTransactionId = 'some transaction id'; System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); - Map output = (Map) callableLoggerInstance + Map returnedOutput = (Map) callableLoggerInstance .call('setParentLogTransactionId', new Map{ 'parentLogTransactionId' => mockParentLogTransactionId }); - System.Assert.areEqual(1, output.size()); - System.Assert.areEqual(true, output.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + output); + System.Assert.areEqual(1, returnedOutput.size()); + System.Assert.areEqual(true, returnedOutput.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + returnedOutput); System.Assert.areEqual(mockParentLogTransactionId, Logger.getParentLogTransactionId()); } @IsTest - static void it_sets_parent_log_transaction_id_when_running_in_omnistudio() { + static void it_sets_parent_log_transaction_id_when_using_omnistudio_approach() { System.Assert.isNull(Logger.getParentLogTransactionId(), 'Test has started under the wrong conditions'); String mockParentLogTransactionId = 'some transaction id'; Map omnistudioInput = new Map{ 'parentLogTransactionId' => mockParentLogTransactionId }; + Map omnistudioOutput = new Map(); System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); - Object returnedValue = callableLoggerInstance.call('setParentLogTransactionId', new Map{ 'input' => omnistudioInput }); + callableLoggerInstance.call('setParentLogTransactionId', new Map{ 'input' => omnistudioInput, 'returnedOutput' => omnistudioOutput }); - System.Assert.isNull(returnedValue, 'No return value expected for Logger.getParentLogTransactionId(), received ' + returnedValue); + System.Assert.areEqual(1, omnistudioOutput.size()); + System.Assert.areEqual(true, omnistudioOutput.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + omnistudioOutput); System.Assert.areEqual(mockParentLogTransactionId, Logger.getParentLogTransactionId()); } @IsTest - static void it_gets_scenario() { + static void it_gets_scenario_when_using_standard_approach() { String mockScenario = 'some scenario'; Logger.setScenario(mockScenario); System.Assert.areEqual(mockScenario, Logger.getScenario(), 'Test has started under the wrong conditions'); System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); - Object returnedValue = callableLoggerInstance.call('getScenario', null); + Map returnedOutput = (Map) callableLoggerInstance.call('getScenario', null); - System.Assert.isNotNull(returnedValue); - System.Assert.areEqual(Logger.getScenario(), returnedValue); + System.Assert.areEqual(2, returnedOutput.size()); + System.Assert.areEqual(true, returnedOutput.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + returnedOutput); + System.Assert.areEqual(Logger.getScenario(), returnedOutput.get('scenario')); } @IsTest - static void it_sets_scenario() { + static void it_gets_scenario_when_using_omnistudio_approach() { + String mockScenario = 'some scenario'; + Logger.setScenario(mockScenario); + System.Assert.areEqual(mockScenario, Logger.getScenario(), 'Test has started under the wrong conditions'); + Map omnistudioOutput = new Map(); + + System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); + callableLoggerInstance.call('getScenario', new Map{ 'output' => omnistudioOutput }); + + System.Assert.areEqual(2, omnistudioOutput.size()); + System.Assert.areEqual(true, omnistudioOutput.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + omnistudioOutput); + System.Assert.areEqual(Logger.getScenario(), omnistudioOutput.get('scenario')); + } + + @IsTest + static void it_sets_scenario_when_using_standard_approach() { System.Assert.isNull(Logger.getScenario(), 'Test has started under the wrong conditions'); String mockScenario = 'some scenario'; System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); - Object returnedValue = callableLoggerInstance.call('setScenario', new Map{ 'scenario' => mockScenario }); + Map returnedOutput = (Map) callableLoggerInstance.call( + 'setScenario', + new Map{ 'scenario' => mockScenario } + ); - System.Assert.isNull(returnedValue, 'No return value expected for Logger.setScenario(), received ' + returnedValue); + System.Assert.areEqual(1, returnedOutput.size()); + System.Assert.areEqual(true, returnedOutput.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + returnedOutput); System.Assert.areEqual(mockScenario, Logger.getScenario()); } @IsTest - static void it_sets_scenario_when_running_in_omnistudio() { + static void it_sets_scenario_when_using_omnistudio_approach() { System.Assert.isNull(Logger.getScenario(), 'Test has started under the wrong conditions'); String mockScenario = 'some scenario'; Map omnistudioInput = new Map{ 'scenario' => mockScenario }; + Map omnistudioOutput = new Map(); System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); - Object returnedValue = callableLoggerInstance.call('setScenario', new Map{ 'input' => omnistudioInput }); + callableLoggerInstance.call('setScenario', new Map{ 'input' => omnistudioInput, 'output' => omnistudioOutput }); - System.Assert.isNull(returnedValue, 'No return value expected for Logger.setScenario(), received ' + returnedValue); + System.Assert.areEqual(1, omnistudioOutput.size()); + System.Assert.areEqual(true, omnistudioOutput.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + omnistudioOutput); System.Assert.areEqual(mockScenario, Logger.getScenario()); } @IsTest - static void it_ends_scenario() { + static void it_ends_scenario_when_using_standard_approach() { String mockScenario = 'some scenario'; Logger.setScenario(mockScenario); System.Assert.areEqual(mockScenario, Logger.getScenario(), 'Test has started under the wrong conditions'); System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); - Object returnedValue = callableLoggerInstance.call('endScenario', new Map{ 'scenario' => mockScenario }); + Map returnedOutput = (Map) callableLoggerInstance.call( + 'endScenario', + new Map{ 'scenario' => mockScenario } + ); - System.Assert.isNull(returnedValue, 'No return value expected for Logger.endScenario(), received ' + returnedValue); + System.Assert.areEqual(1, returnedOutput.size()); + System.Assert.areEqual(true, returnedOutput.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + returnedOutput); System.Assert.isNull(Logger.getScenario()); } @IsTest - static void it_ends_scenario_when_running_in_omnistudio() { + static void it_ends_scenario_when_using_omnistudio_approach() { String mockScenario = 'some scenario'; Logger.setScenario(mockScenario); System.Assert.areEqual(mockScenario, Logger.getScenario(), 'Test has started under the wrong conditions'); Map omnistudioInput = new Map{ 'scenario' => mockScenario }; + Map omnistudioOutput = new Map(); System.Callable callableLoggerInstance = (System.Callable) System.Type.forName('CallableLogger').newInstance(); - Object returnedValue = callableLoggerInstance.call('endScenario', new Map{ 'input' => omnistudioInput }); + Object returnedValue = callableLoggerInstance.call('endScenario', new Map{ 'input' => omnistudioInput, 'output' => omnistudioOutput }); - System.Assert.isNull(returnedValue, 'No return value expected for Logger.endScenario(), received ' + returnedValue); + System.Assert.areEqual(1, omnistudioOutput.size()); + System.Assert.areEqual(true, omnistudioOutput.get('isSuccess'), 'Expected isSuccess == true. Output received: ' + omnistudioOutput); System.Assert.isNull(Logger.getScenario()); } @@ -304,7 +348,7 @@ private class CallableLogger_Tests { } @IsTest - static void it_adds_new_entry_when_running_in_omnistudio() { + static void it_adds_new_entry_when_using_omnistudio_approach() { String loggingLevelName = System.LoggingLevel.FINE.name(); String message = 'some log entry message'; Map omnistudioInput = new Map{ 'loggingLevel' => loggingLevelName, 'message' => message }; @@ -349,7 +393,7 @@ private class CallableLogger_Tests { } @IsTest - static void it_adds_and_saves_new_entry_when_running_in_omnistudio() { + static void it_adds_and_saves_new_entry_when_using_omnistudio_approach() { System.Assert.isNull(Logger.lastSaveMethodNameUsed); String loggingLevelName = System.LoggingLevel.FINE.name(); String message = 'some log entry message';