Skip to content

Commit

Permalink
Improving test coverage and fixing bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
rob-baillie-ortoo committed Dec 2, 2021
1 parent 47050d0 commit dfbc9bc
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,10 @@ public virtual class ortoo_Exception extends Exception implements IRenderableMes
Set<Sobject> objectContexts = new Set<Sobject>();
for ( MessageDetail thisMessageDetail : messageDetails )
{
objectContexts.add( thisMessageDetail.getObjectContext() );
if ( thisMessageDetail.getObjectContext() != null )
{
objectContexts.add( thisMessageDetail.getObjectContext() );
}
}

List<Sobject> returnList = new List<Sobject>( objectContexts );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,35 @@ private without sharing class ExceptionsTest

System.assertEquals( 'CONF-123', e.getErrorCode(), 'ConfigurationException.setErrorCode, when called, will add a prefix to the code' );
}

@isTest
private static void validationExceptionSetErrorCode_whenCalled_willNotAddAPrefixToTheCode() // NOPMD: Test method name format
{
Exceptions.ValidationException e = new Exceptions.ValidationException( new List<MessageDetail>() );
e.setErrorCode( '123' );

System.assertEquals( '123', e.getErrorCode(), 'ValidationException.setErrorCode, when called, will NOT add a prefix to the code' );
}

@isTest
private static void validationException_whenConstructed_willSetTheMessage() // NOPMD: Test method name format
{
Exceptions.ValidationException e = new Exceptions.ValidationException( new List<MessageDetail>() );

System.assertEquals( Label.ortoo_core_validation_errors_occurred, e.getMessage(), 'ValidationException, when constructed, will set the message' );
}

@isTest
private static void validationException_whenConstructed_willSetTheMessageDetails() // NOPMD: Test method name format
{
List<MessageDetail> messageDetails = new List<MessageDetail>
{
new MessageDetail( 'content1' ),
new MessageDetail( 'content2' )
};

Exceptions.ValidationException e = new Exceptions.ValidationException( messageDetails );

System.assertEquals( messageDetails, e.getMessageDetails(), 'ValidationException, when constructed, will set the message' );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,29 @@ public with sharing class ortoo_ExceptionTest {
Test.stopTest();

System.assertEquals( 'ErrorCode', e.getErrorCode(), 'setErrorCode, will set the error code that is returned by getErrorCode' );
System.assertEquals( 'ErrorCode', e.getCode(), 'setErrorCode, will set the error code that is returned by getCode' );
}

@isTest
private static void getStackTrace_whenCalled_willReturnAStackTraceObjectBasedOnWhenTheExceptionWasConstructed() // NOPMD: Test method name format
private static void getSeverity_willReturnError() // NOPMD: Test method name format
{
Test.startTest();
ortoo_Exception e = new ortoo_Exception();
MessageRendererEngine.Severity severity = e.getSeverity();
Test.stopTest();

System.assertEquals( MessageRendererEngine.Severity.Error, severity, 'getSeverity, will return error' );
}

@isTest
private static void getStackTrace_whenCalled_willReturnAStackBasedOnConstruct() // NOPMD: Test method name format
{
Test.startTest();
ortoo_Exception e = new ortoo_Exception();
StackTrace trace = e.getStackTrace();
Test.stopTest();

System.assertEquals( 'getStackTrace_whenCalled_willReturnAStackTraceObjectBasedOnWhenTheExceptionWasConstructed', trace.getInnermostMethodName(), 'getStackTrace, when called, will return a stack trace based on when the exception was constructed (method name)' );
System.assertEquals( 'getStackTrace_whenCalled_willReturnAStackBasedOnConstruct', trace.getInnermostMethodName(), 'getStackTrace, when called, will return a stack trace based on when the exception was constructed (method name)' );
Amoss_Asserts.assertEndsWith( 'ortoo_ExceptionTest', trace.getInnermostClassName(), 'getStackTrace, when called, will return a stack trace based on when the exception was constructed (class name)' );
}

Expand Down Expand Up @@ -65,7 +77,7 @@ public with sharing class ortoo_ExceptionTest {
}

@isTest
private static void getStackTraceString_whenConstructionIsInsideMultipleLayers_willReturnTheStackTrace()
private static void getStackTraceString_whenBuiltInsideLayers_willReturnTheStackTrace()
{
String stackTrace;
Test.startTest();
Expand All @@ -82,7 +94,7 @@ public with sharing class ortoo_ExceptionTest {
Amoss_Asserts.assertDoesNotContain( '<init>', stackTrace, 'getStackTraceString, when construction is inside multiple layers of methods, will return the Stack Trace based on where the exception was raised - with each level (not the exception constructor)' );
Amoss_Asserts.assertContains( 'ortoo_ExceptionTest.throwAnOrtooExceptionInnerMethodCall', stackTrace, 'getStackTraceString, when construction is inside multiple layers of methods, will return the Stack Trace based on where the exception was raised - with each level (method 1)' );
Amoss_Asserts.assertContains( 'ortoo_ExceptionTest.throwAnOrtooException', stackTrace, 'getStackTraceString, when construction is inside multiple layers of methods, will return the Stack Trace based on where the exception was raised - with each level (method 2)' );
Amoss_Asserts.assertContains( 'ortoo_ExceptionTest.getStackTraceString_whenConstructionIsInsideMultipleLayers_willReturnTheStackTrace', stackTrace, 'getStackTraceString, when construction is inside multiple layers of methods, will return the Stack Trace based on where the exception was raised - with each level (method 3)' );
Amoss_Asserts.assertContains( 'ortoo_ExceptionTest.getStackTraceString_whenBuiltInsideLayers_willReturnTheStackTrace', stackTrace, 'getStackTraceString, when construction is inside multiple layers of methods, will return the Stack Trace based on where the exception was raised - with each level (method 3)' );
}

@isTest
Expand Down Expand Up @@ -131,7 +143,7 @@ public with sharing class ortoo_ExceptionTest {
}

@isTest
private static void addContext_whenCalledInAnInnerClass_willAddItToTheExceptionWithStackInfo() // NOPMD: Test method name format
private static void addContext_whenCalledInInnerClass_willAddIncludeInStack() // NOPMD: Test method name format
{
ortoo_Exception e = new ortoo_Exception( 'message' );

Expand Down Expand Up @@ -249,6 +261,82 @@ public with sharing class ortoo_ExceptionTest {
System.assertEquals( true, exceptionCaught, 'next, when there are no entries in the list, will throw a NoSuchElementException exception' );
}

@isTest
private static void getObjectContext_whenMessageDetailsAdded_willReturnTheSobjects() // NOPMD: Test method name format
{
ortoo_Exception exceptionUnderTest = new ortoo_Exception( 'message' );

List<Sobject> objectContexts = new List<Sobject>
{
new Contact( Id = TestIdUtils.generateId( Contact.sobjectType ) ),
new Contact( Id = TestIdUtils.generateId( Contact.sobjectType ) ),
new Contact( Id = TestIdUtils.generateId( Contact.sobjectType ) )
};

Test.startTest();
exceptionUnderTest.setMessageDetails(
new List<MessageDetail>
{
new MessageDetail( objectContexts[0], 'message1' ),
new MessageDetail( objectContexts[1], 'message2' ),
new MessageDetail( objectContexts[1], 'message3' ),
new MessageDetail( objectContexts[0], 'message4' )
}
);
List<Sobject> returnedObjectContexts = exceptionUnderTest.getObjectContexts();

Test.stopTest();

List<Sobject> expectedObjectContexts = new List<Sobject>{ objectContexts[0], objectContexts[1] };

System.assertEquals( expectedObjectContexts, returnedObjectContexts, 'getObjectContext, when some message details have been added, will return those objects' );
}

@isTest
private static void getObjectContext_whenNoMessageDetails_willReturnEmptySet() // NOPMD: Test method name format
{
ortoo_Exception exceptionUnderTest = new ortoo_Exception( 'message' );

Test.startTest();
List<Sobject> returnedObjectContexts = exceptionUnderTest.getObjectContexts();
Test.stopTest();

List<Sobject> expectedObjectContexts = new List<Sobject>();

System.assertEquals( expectedObjectContexts, returnedObjectContexts, 'getObjectContext, when no message details have been added, will return an empty set' );
}

@isTest
private static void getObjectContext_whenSomeDetailsHaveNull_willNotReturnTheNulls() // NOPMD: Test method name format
{
ortoo_Exception exceptionUnderTest = new ortoo_Exception( 'message' );

List<Sobject> objectContexts = new List<Sobject>
{
new Contact( Id = TestIdUtils.generateId( Contact.sobjectType ) ),
new Contact( Id = TestIdUtils.generateId( Contact.sobjectType ) ),
new Contact( Id = TestIdUtils.generateId( Contact.sobjectType ) )
};

Test.startTest();
exceptionUnderTest.setMessageDetails(
new List<MessageDetail>
{
new MessageDetail( objectContexts[0], 'message1' ),
new MessageDetail( objectContexts[2], 'message2' ),
new MessageDetail( 'message3' ),
new MessageDetail( objectContexts[0], 'message4' )
}
);
List<Sobject> returnedObjectContexts = exceptionUnderTest.getObjectContexts();

Test.stopTest();

List<Sobject> expectedObjectContexts = new List<Sobject>{ objectContexts[0], objectContexts[2] };

System.assertEquals( expectedObjectContexts, returnedObjectContexts, 'getObjectContext, when some message details have been added with null objects, will not return the nulls' );
}

private class ContextAdder
{
private void addContext( ortoo_Exception e, String name, String value )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ private without sharing class MessageRendererEngineTest
Amoss_Asserts.assertContains( 'render called before the message was set', exceptionMessage, 'render, when no message has been set, will throw an exception' );
}

@isTest
private static void getRenderer_whenTheRendererHasBeenSet_willReturnTheRenderer() // NOPMD: Test method name format
{
IMessageRenderer renderer = (IMessageRenderer)new Amoss_Instance( IMessageRenderer.class ).generateDouble();
MessageRendererEngine engine = new MessageRendererEngine().setRenderer( renderer );

IMessageRenderer returnedRenderer = engine.getRenderer();
System.assertEquals( renderer, returnedRenderer, 'getRenderer, when the renderer has been set, will return the renderer' );
}

@isTest
private static void render_whenCalledAgainstAConfiguredEngine_willCallRenderAgainstTheRenderer() // NOPMD: Test method name format
{
Expand Down Expand Up @@ -282,58 +292,6 @@ private without sharing class MessageRendererEngineTest
System.assertEquals( 'Field detail content', detailError.getMessage(), 'SobjectMessageAdder, when render is called, will add messages of severity error to the related SObjects - setting the content a the detail error with a field' );
}

@isTest
private static void SobjectMessageAdder_whenRenderIsCalled_willNotAddInfoOrWarnAsErrors() // NOPMD: Test method name format
{
Amoss_Instance messageController = new Amoss_Instance( IRenderableMessageHeader.class );
IRenderableMessageHeader message = (IRenderableMessageHeader)messageController.generateDouble();

Amoss_Instance fieldDetailController = new Amoss_Instance( IRenderableMessageDetail.class );
IRenderableMessageDetail fieldDetail = (IRenderableMessageDetail)fieldDetailController.generateDouble();

List<Sobject> objectContexts = new List<Sobject> {
new Contact()
};

messageController
.when( 'getSeverity' )
.returns( MessageRendererEngine.Severity.Info )
.also()
.when( 'getObjectContexts' )
.returns( objectContexts )
.also()
.when( 'getMessage' )
.returns( 'The header message' )
.also()
.when( 'getMessageDetails' )
.returns( new List<IRenderableMessageDetail>{ fieldDetail } );

fieldDetailController
.when( 'getContent' )
.returns( 'Field detail content' )
.also()
.when( 'getObjectContext' )
.returns( objectContexts[0] )
.also()
.when( 'getFieldContext' )
.returns( Contact.FirstName )
.also()
.when( 'getSeverity' )
.returns( MessageRendererEngine.Severity.Error );

MessageRendererEngine.SobjectMessageAdder renderer = new MessageRendererEngine.SobjectMessageAdder();

Test.startTest();
Boolean messageRendered = renderer.render( message );
Test.stopTest();

System.assert( ! messageRendered, 'SobjectMessageAdder, when render is called with an info or warning header message, will return false' );

List<Database.Error> errors;
errors = objectContexts[0].getErrors();
System.assertEquals( 0, errors.size(), 'SobjectMessageAdder, when render is called with an info or warning header message, will not add any messages to the sobjects' );
}

@isTest
private static void SobjectMessageAdder_whenRenderIsCalled_willNotAddInfoOrWarnDetailsAsErrors() // NOPMD: Test method name format
{
Expand Down Expand Up @@ -403,4 +361,59 @@ private without sharing class MessageRendererEngineTest

System.assertEquals( 'The header message', errors[0].getMessage(), 'SobjectMessageAdder, when render is called with an error message that has no error details, will add the header message to the sobjects - checking the content' );
}

@isTest
private static void SobjectMessageAdder_whenRenderIsCalled_willNotAddInfoOrWarnAsErrors() // NOPMD: Test method name format
{
Amoss_Instance messageController = new Amoss_Instance( IRenderableMessageHeader.class );
IRenderableMessageHeader message = (IRenderableMessageHeader)messageController.generateDouble();

List<Sobject> objectContexts = new List<Sobject> {
new Contact()
};

messageController
.when( 'getSeverity' )
.returns( MessageRendererEngine.Severity.Info )
.also()
.when( 'getObjectContexts' )
.returns( objectContexts );

MessageRendererEngine.SobjectMessageAdder renderer = new MessageRendererEngine.SobjectMessageAdder();

Test.startTest();
Boolean messageRendered = renderer.render( message );
Test.stopTest();

System.assert( ! messageRendered, 'SobjectMessageAdder, when render is called with an info or warning header message, will return false' );

List<Database.Error> errors;
errors = objectContexts[0].getErrors();
System.assertEquals( 0, errors.size(), 'SobjectMessageAdder, when render is called with an info or warning header message, will not add any messages to the sobjects' );
}

@isTest
private static void SobjectMessageAdder_whenRenderIsCalledAndThereAreNoObjectContexts_willNotAddErrors() // NOPMD: Test method name format
{
Amoss_Instance messageController = new Amoss_Instance( IRenderableMessageHeader.class );
IRenderableMessageHeader message = (IRenderableMessageHeader)messageController.generateDouble();

Amoss_Instance detailController = new Amoss_Instance( IRenderableMessageDetail.class );
IRenderableMessageDetail detail = (IRenderableMessageDetail)detailController.generateDouble();

messageController
.when( 'getSeverity' )
.returns( MessageRendererEngine.Severity.Error )
.also()
.when( 'getObjectContexts' )
.returns( new List<Sobject>() );

MessageRendererEngine.SobjectMessageAdder renderer = new MessageRendererEngine.SobjectMessageAdder();

Test.startTest();
Boolean messageRendered = renderer.render( message );
Test.stopTest();

System.assert( ! messageRendered, 'SobjectMessageAdder, when render is called with an error message that has no object contexts, will return false' );
}
}
File renamed without changes.

0 comments on commit dfbc9bc

Please sign in to comment.