diff --git a/framework/default/modules/logger/services/logger/classes/tests/LoggerServiceTest.cls b/framework/default/modules/logger/services/logger/classes/tests/LoggerServiceTest.cls new file mode 100644 index 00000000000..4da9a0318e4 --- /dev/null +++ b/framework/default/modules/logger/services/logger/classes/tests/LoggerServiceTest.cls @@ -0,0 +1,382 @@ +@isTest +private without sharing class LoggerServiceTest +{ + @isTest + private static void log_whenGivenALevelAndAMessageAndLoggingIsEnabledForThatLevel_callsToLog() // NOPMD: Test method name format + { + LoggerService.Level level = LoggerService.Level.INFO; + String message = 'the message'; + + FakeLogger fakeLogger = new FakeLogger(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_INFO_Level_Messages__c = true ); + + Test.startTest(); + LoggerService.log( level, message ); + Test.stopTest(); + + System.assertEquals( 'log', fakeLogger.methods[0], 'log, when given a level and a message, and logging is enabled for that level, calls the service to log' ); + System.assertEquals( new List{ level, message }, fakeLogger.parameters[0], 'log, when given a level and a message, and logging is enabled for that level, calls the service to log, passing parameters' ); + } + + @isTest + private static void log_whenGivenALevelAndAMessageAndLoggingIsDisabledForThatLevel_doesNotCallToLog() // NOPMD: Test method name format + { + LoggerService.Level level = LoggerService.Level.INFO; + String message = 'the message'; + + FakeLogger fakeLogger = new FakeLogger(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_INFO_Level_Messages__c = false ); + + Test.startTest(); + LoggerService.log( level, message ); + Test.stopTest(); + + System.assert( fakeLogger.methods.isEmpty(), 'log, when given a level and a message, and logging is disabled for that level, does not call against the service' ); + } + + @isTest + private static void log_whenGivenALevelAndAMessageAndLoggingAndNoConfig_asksServiceIfItShouldLog() // NOPMD: Test method name format + { + LoggerService.Level level = LoggerService.Level.INFO; + String message = 'the message'; + + FakeLogger fakeLogger = new FakeLogger().setDefaultLoggingEnabledReturns( true ); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c(); // nameless config means there's no config + + Test.startTest(); + LoggerService.log( level, message ); + Test.stopTest(); + + System.assertEquals( 'getDefaultLoggingEnabled', fakeLogger.methods[0], 'log, when given a level and a message, and config is missing, asks the service if it should log' ); + System.assertEquals( LoggerService.Level.INFO, fakeLogger.parameters[0][0], 'log, when given a level and a message, and config is missing, and config is missing, asks the service if it should log' ); + + System.assertEquals( 'log', fakeLogger.methods[1], 'log, when given a level and a message, and config is missing, asks the service if it should log, and calls the service if it should' ); + } + + @isTest + private static void log_whenGivenALevelAndAMessageAndLoggerThrowsException_doesNotThrow() // NOPMD: Test method name format + { + LoggerService.Level level = LoggerService.Level.INFO; + String message = 'the message'; + + FakeLogger fakeLogger = new FakeLogger().loggingThrowsException(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_INFO_Level_Messages__c = true ); + + Test.startTest(); + LoggerService.log( level, message ); + Test.stopTest(); + + System.assertEquals( 'log', fakeLogger.methods[0], 'log, when given a level and a message, and the logger throws an exception, does not throw' ); + } + + @isTest + private static void log_whenGivenALevelAndAMessageAndIdAndLoggingIsEnabledForThatLevel_callsToLog() // NOPMD: Test method name format + { + LoggerService.Level level = LoggerService.Level.WARN; + String message = 'the message'; + Id relatedSobjectId = TestIdUtils.generateId( Contact.SobjectType ); + + FakeLogger fakeLogger = new FakeLogger(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_WARN_Level_Messages__c = true ); + + Test.startTest(); + LoggerService.log( level, message, relatedSobjectId ); + Test.stopTest(); + + System.assertEquals( 'log', fakeLogger.methods[0], 'log, when given a level and a message and sobject id, and logging is enabled for that level, calls the service to log' ); + System.assertEquals( new List{ level, message, relatedSobjectId }, fakeLogger.parameters[0], 'log, when given a level and a message, and sobject id and logging is enabled for that level, calls the service to log, passing parameters' ); + } + + @isTest + private static void log_whenGivenALevelAndAMessageAndIdAndLoggingIsDisabledForThatLevel_doesNotCallToLog() // NOPMD: Test method name format + { + LoggerService.Level level = LoggerService.Level.WARN; + String message = 'the message'; + Id relatedSobjectId = TestIdUtils.generateId( Contact.SobjectType ); + + FakeLogger fakeLogger = new FakeLogger(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_WARN_Level_Messages__c = false ); + + Test.startTest(); + LoggerService.log( level, message, relatedSobjectId ); + Test.stopTest(); + + System.assert( fakeLogger.methods.isEmpty(), 'log, when given a level and a message and sobject id, and logging is disabled for that level, does not call against the service' ); + } + + @isTest + private static void log_whenGivenALevelAndAMessageAndIdAndLoggingAndNoConfig_asksServiceIfItShouldLog() // NOPMD: Test method name format + { + LoggerService.Level level = LoggerService.Level.WARN; + String message = 'the message'; + Id relatedSobjectId = TestIdUtils.generateId( Contact.SobjectType ); + + FakeLogger fakeLogger = new FakeLogger().setDefaultLoggingEnabledReturns( true ); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c(); // nameless config means there's no config + + Test.startTest(); + LoggerService.log( level, message, relatedSobjectId ); + Test.stopTest(); + + System.assertEquals( 'getDefaultLoggingEnabled', fakeLogger.methods[0], 'log, when given a level and a message and sobject id, and config is missing, asks the service if it should log' ); + System.assertEquals( LoggerService.Level.WARN, fakeLogger.parameters[0][0], 'log, when given a level and a message and sobject id, and config is missing, and config is missing, asks the service if it should log' ); + + System.assertEquals( 'log', fakeLogger.methods[1], 'log, when given a level and a message and sobject id, and config is missing, asks the service if it should log, and calls the service if it should' ); + } + + @isTest + private static void log_whenGivenALevelAndAMessageAndIdAndLoggerThrowsException_doesNotThrow() // NOPMD: Test method name format + { + LoggerService.Level level = LoggerService.Level.WARN; + String message = 'the message'; + Id relatedSobjectId = TestIdUtils.generateId( Contact.SobjectType ); + + FakeLogger fakeLogger = new FakeLogger().loggingThrowsException(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_WARN_Level_Messages__c = true ); + + Test.startTest(); + LoggerService.log( level, message, relatedSobjectId ); + Test.stopTest(); + + System.assertEquals( 'log', fakeLogger.methods[0], 'log, when given a level and a message and sobject id, and the logger throws an exception, does not throw' ); + } + + @isTest + private static void log_whenGivenExceptionAndLoggingIsEnabledForThatLevel_callsToLog() // NOPMD: Test method name format + { + Exception exceptionToLog = new LocalException( 'message' ); + + FakeLogger fakeLogger = new FakeLogger(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_ERROR_Level_Messages__c = true ); + + Test.startTest(); + LoggerService.log( exceptionToLog ); + Test.stopTest(); + + System.assertEquals( 'log', fakeLogger.methods[0], 'log, when given an exception, and logging is enabled for that level, calls the service to log' ); + } + + @isTest + private static void log_whenGivenExceptionAndLoggingIsDisabledForErrors_doesNotCallToLog() // NOPMD: Test method name format + { + Exception exceptionToLog = new LocalException( 'message' ); + + FakeLogger fakeLogger = new FakeLogger(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_ERROR_Level_Messages__c = false ); + + Test.startTest(); + LoggerService.log( exceptionToLog ); + Test.stopTest(); + + System.assert( fakeLogger.methods.isEmpty(), 'log, when given an exception, and logging is disabled for errors, does not call against the service' ); + } + + @isTest + private static void log_whenGivenExceptionAndLoggingAndNoConfig_asksServiceIfItShouldLog() // NOPMD: Test method name format + { + Exception exceptionToLog = new LocalException( 'message' ); + + FakeLogger fakeLogger = new FakeLogger().setDefaultLoggingEnabledReturns( true ); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c(); // nameless config means there's no config + + Test.startTest(); + LoggerService.log( exceptionToLog ); + Test.stopTest(); + + System.assertEquals( 'getDefaultLoggingEnabled', fakeLogger.methods[0], 'log, when given an exception, and config is missing, asks the service if it should log' ); + System.assertEquals( LoggerService.Level.ERROR, fakeLogger.parameters[0][0], 'log, when given an exception, and config is missing, asks the service if it should log' ); + + System.assertEquals( 'log', fakeLogger.methods[1], 'log, when given an exception, and config is missing, asks the service if it should log, and calls the service if it should' ); + } + + @isTest + private static void log_whenGivenExceptionAndLoggerThrowsException_doesNotThrow() // NOPMD: Test method name format + { + Exception exceptionToLog = new LocalException( 'message' ); + + FakeLogger fakeLogger = new FakeLogger().loggingThrowsException(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_ERROR_Level_Messages__c = true ); + + Test.startTest(); + LoggerService.log( exceptionToLog ); + Test.stopTest(); + + System.assertEquals( 'log', fakeLogger.methods[0], 'log, when given an exception, and the logger throws an exception, does not throw' ); + } + + @isTest + private static void log_whenGivenExceptionAndIdAndLoggingIsEnabledForThatLevel_callsToLog() // NOPMD: Test method name format + { + Exception exceptionToLog = new LocalException( 'message' ); + Id relatedSobjectId = TestIdUtils.generateId( Contact.SobjectType ); + + FakeLogger fakeLogger = new FakeLogger(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_ERROR_Level_Messages__c = true ); + + Test.startTest(); + LoggerService.log( exceptionToLog, relatedSobjectId ); + Test.stopTest(); + + System.assertEquals( 'log', fakeLogger.methods[0], 'log, when given an exception and an id, and logging is enabled for that level, calls the service to log' ); + } + + @isTest + private static void log_whenGivenExceptionAndIdAndLoggingIsDisabledForErrors_doesNotCallToLog() // NOPMD: Test method name format + { + Exception exceptionToLog = new LocalException( 'message' ); + Id relatedSobjectId = TestIdUtils.generateId( Contact.SobjectType ); + + FakeLogger fakeLogger = new FakeLogger(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_ERROR_Level_Messages__c = false ); + + Test.startTest(); + LoggerService.log( exceptionToLog, relatedSobjectId ); + Test.stopTest(); + + System.assert( fakeLogger.methods.isEmpty(), 'log, when given an exception and an id, and logging is disabled for errors, does not call against the service' ); + } + + @isTest + private static void log_whenGivenExceptionAndIdAndLoggingAndNoConfig_asksServiceIfItShouldLog() // NOPMD: Test method name format + { + Exception exceptionToLog = new LocalException( 'message' ); + Id relatedSobjectId = TestIdUtils.generateId( Contact.SobjectType ); + + FakeLogger fakeLogger = new FakeLogger().setDefaultLoggingEnabledReturns( true ); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c(); // nameless config means there's no config + + Test.startTest(); + LoggerService.log( exceptionToLog, relatedSobjectId ); + Test.stopTest(); + + System.assertEquals( 'getDefaultLoggingEnabled', fakeLogger.methods[0], 'log, when given an exception and an id, and config is missing, asks the service if it should log' ); + System.assertEquals( LoggerService.Level.ERROR, fakeLogger.parameters[0][0], 'log, when given an exception and an id, and config is missing, asks the service if it should log' ); + + System.assertEquals( 'log', fakeLogger.methods[1], 'log, when given an exception and an id, and config is missing, asks the service if it should log, and calls the service if it should' ); + } + + @isTest + private static void log_whenGivenExceptionAndIdAndLoggerThrowsException_doesNotThrow() // NOPMD: Test method name format + { + Exception exceptionToLog = new LocalException( 'message' ); + Id relatedSobjectId = TestIdUtils.generateId( Contact.SobjectType ); + + FakeLogger fakeLogger = new FakeLogger().loggingThrowsException(); + Application.SERVICE.setMock( ILoggerService.class, fakeLogger ); + + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_ERROR_Level_Messages__c = true ); + + Test.startTest(); + LoggerService.log( exceptionToLog, relatedSobjectId ); + Test.stopTest(); + + System.assertEquals( 'log', fakeLogger.methods[0], 'log, when given an exception and an id, and the logger throws an exception, does not throw' ); + } + + @isTest + private static void log_whenTheLoggerCannotBeFound_usesANullLogger() // NOPMD: Test method name format + { + Application.SERVICE.setMock( ILoggerService.class, null ); + LoggerService.config = new Logging_Configuration__c( Name = 'Name', Log_INFO_Level_Messages__c = true ); + + Test.startTest(); + LoggerService.log( LoggerService.Level.INFO, 'message' ); + Test.stopTest(); + + System.assert( true, 'log, when the logger service implementation cannot be found, will use a null logger and no exception is thrown' ); + } + + class LocalException extends Exception {} + // This exists because StubProvider has difficulty creating a stub for ILoggerService + // Potentially it's a problem with overloaded methods defined in an interface. + class FakeLogger implements ILoggerService + { + public List methods = new List(); + public List> parameters = new List>(); + Boolean defaultLoggingEnabledReturns = false; + Boolean loggingThrowsException = false; + + public FakeLogger loggingThrowsException() + { + loggingThrowsException = true; + return this; + } + public FakeLogger setDefaultLoggingEnabledReturns( Boolean returns ) + { + defaultLoggingEnabledReturns = returns; + return this; + } + public Boolean getDefaultLoggingEnabled( LoggerService.Level logLevel ) + { + methods.add( 'getDefaultLoggingEnabled' ); + parameters.add( new List{ logLevel } ); + return defaultLoggingEnabledReturns; + } + public void log( LoggerService.Level logLevel, String message ) + { + methods.add( 'log' ); + parameters.add( new List{ logLevel, message } ); + if ( loggingThrowsException ) + { + throw new LocalException( 'a message' ); + } + } + public void log( LoggerService.Level logLevel, String message, Id relatedSobjectId ) + { + methods.add( 'log' ); + parameters.add( new List{ logLevel, message, relatedSobjectId } ); + if ( loggingThrowsException ) + { + throw new LocalException( 'a message' ); + } + } + public void log( Exception exceptionToLog ) + { + methods.add( 'log' ); + parameters.add( new List{ exceptionToLog } ); + if ( loggingThrowsException ) + { + throw new LocalException( 'a message' ); + } + } + public void log( Exception exceptionToLog, Id relatedSobject ) + { + methods.add( 'log' ); + parameters.add( new List{ exceptionToLog, relatedSobject }); + if ( loggingThrowsException ) + { + throw new LocalException( 'a message' ); + } + } + } +} \ No newline at end of file diff --git a/framework/default/modules/logger/services/logger/classes/tests/LoggerServiceTest.cls-meta.xml b/framework/default/modules/logger/services/logger/classes/tests/LoggerServiceTest.cls-meta.xml new file mode 100644 index 00000000000..40d67933d00 --- /dev/null +++ b/framework/default/modules/logger/services/logger/classes/tests/LoggerServiceTest.cls-meta.xml @@ -0,0 +1,5 @@ + + + 54.0 + Active +