Skip to content

Commit

Permalink
Merge pull request apex-enterprise-patterns#31 from OrtooApps/feature…
Browse files Browse the repository at this point in the history
…/block-duplicate-configs

Block duplicate config records
  • Loading branch information
rob-baillie-ortoo authored Apr 21, 2022
2 parents 52c2442 + baaf94d commit bf2ffc9
Show file tree
Hide file tree
Showing 3 changed files with 272 additions and 3 deletions.
34 changes: 32 additions & 2 deletions framework/default/ortoo-core/default/classes/Application.cls
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,18 @@ public inherited sharing class Application {

public void put( Application_Configuration__mdt thisConfiguration )
{
configuration.put( classTypeBuilder.build( thisConfiguration.Object_Type__c ), classTypeBuilder.build( thisConfiguration.Implementation__c ) );
Type objectType = classTypeBuilder.build( thisConfiguration.Object_Type__c );
Type implementation = classTypeBuilder.build( thisConfiguration.Implementation__c );

if ( configuration.containsKey( objectType ) )
{
throw new InvalidApplicationConfigurationException( 'Duplicate configuration exists for ' + thisConfiguration.Type__c + ' - ' + thisConfiguration.Object_Type__c )
.setErrorCode( FrameworkErrorCodes.CONFIGURATION_WITH_DUPLICATE_TYPE )
.addContext( 'typeName', thisConfiguration.Type__c )
.addContext( 'objectType', thisConfiguration.Object_Type__c );
}

configuration.put( objectType, implementation );
}

public Map<Type,Type> getConfiguration()
Expand All @@ -143,6 +154,14 @@ public inherited sharing class Application {

public void put( Application_Configuration__mdt thisConfiguration )
{
if ( configuration.containsKey( thisConfiguration.Object_Type__c ) )
{
throw new InvalidApplicationConfigurationException( 'Duplicate configuration exists for ' + thisConfiguration.Type__c + ' - ' + thisConfiguration.Object_Type__c )
.setErrorCode( FrameworkErrorCodes.CONFIGURATION_WITH_DUPLICATE_TYPE )
.addContext( 'typeName', thisConfiguration.Type__c )
.addContext( 'objectType', thisConfiguration.Object_Type__c );
}

configuration.put( thisConfiguration.Object_Type__c, thisConfiguration.Implementation__c );
}

Expand All @@ -163,7 +182,18 @@ public inherited sharing class Application {

public void put( Application_Configuration__mdt thisConfiguration )
{
configuration.put( sobjectTypeBuilder.build( thisConfiguration.Object_Type__c ), classTypeBuilder.build( thisConfiguration.Implementation__c ) );
SobjectType objectType = sobjectTypeBuilder.build( thisConfiguration.Object_Type__c );
Type implementation = classTypeBuilder.build( thisConfiguration.Implementation__c );

if ( configuration.containsKey( objectType ) )
{
throw new InvalidApplicationConfigurationException( 'Duplicate configuration exists for ' + thisConfiguration.Type__c + ' - ' + thisConfiguration.Object_Type__c )
.setErrorCode( FrameworkErrorCodes.CONFIGURATION_WITH_DUPLICATE_TYPE )
.addContext( 'typeName', thisConfiguration.Type__c )
.addContext( 'objectType', thisConfiguration.Object_Type__c );
}

configuration.put( objectType, implementation );
}

public Map<SobjectType,Type> getConfiguration()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public inherited sharing class FrameworkErrorCodes {
public final static String CONFIGURATION_WITH_INVALID_TYPE = 'APP-00001';
public final static String CONFIGURATION_WITH_INVALID_CLASS = 'APP-00002';
public final static String CONFIGURATION_WITH_INVALID_SOBJECT_TYPE = 'APP-00003';
public final static String CONFIGURATION_WITH_DUPLICATE_TYPE = 'APP-00004';

public final static String NON_EVALUATABLE_CRITERIA = 'CRI-00000';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,40 @@ private without sharing class ApplicationTest
System.assertEquals( fflib_ISObjectSelector.class, Application.SELECTOR.getSelectorType( Contact.sobjectType ), 'selector, when referenced, will be configured based on metadata' );
}

@isTest
private static void selector_whenConfiguredWithDuplicates_throwsAnException() // NOPMD: Test method name format
{
List<Application_Configuration__mdt> configurations = new List<Application_Configuration__mdt>
{
new Application_Configuration__mdt
(
Type__c = 'Selector',
Object_Type__c = 'Contact',
Implementation__c = 'fflib_ISObjectSelector'
),
new Application_Configuration__mdt
(
Type__c = 'Selector',
Object_Type__c = 'Contact',
Implementation__c = 'fflib_ISObjectSelector'
)
};

Test.startTest();
String exceptionMessage;
try
{
Application.applyConfiguration( configurations );
}
catch ( Application.InvalidApplicationConfigurationException e )
{
exceptionMessage = e.getMessage();
}
Test.stopTest();

ortoo_Asserts.assertContains( 'Duplicate configuration exists for Selector - Contact', exceptionMessage, 'selector, when configured with duplicates, will throw an exception' );
}

@isTest
private static void domain_whenReferenced_willBeConfiguredBasedOnMetadata() // NOPMD: Test method name format
{
Expand All @@ -65,6 +99,40 @@ private without sharing class ApplicationTest
System.assert( true, 'domain, when referenced, will be configured based on metadata - unfortunately it is too much hassle to actually test it returns the right thing, so we do not' );
}

@isTest
private static void domain_whenConfiguredWithDuplicates_throwsAnException() // NOPMD: Test method name format
{
List<Application_Configuration__mdt> configurations = new List<Application_Configuration__mdt>
{
new Application_Configuration__mdt
(
Type__c = 'Domain',
Object_Type__c = 'Contact',
Implementation__c = 'fflib_ISObjectSelector'
),
new Application_Configuration__mdt
(
Type__c = 'Domain',
Object_Type__c = 'Contact',
Implementation__c = 'fflib_ISObjectSelector'
)
};

Test.startTest();
String exceptionMessage;
try
{
Application.applyConfiguration( configurations );
}
catch ( Application.InvalidApplicationConfigurationException e )
{
exceptionMessage = e.getMessage();
}
Test.stopTest();

ortoo_Asserts.assertContains( 'Duplicate configuration exists for Domain - Contact', exceptionMessage, 'domain, when configured with duplicates, will throw an exception' );
}

@isTest
private static void service_whenReferenced_willBeConfiguredBasedOnMetadata() // NOPMD: Test method name format
{
Expand Down Expand Up @@ -92,6 +160,40 @@ private without sharing class ApplicationTest
System.assert( service instanceOf ServiceClass , 'Service, when referenced, will be configured based on metadata' );
}

@isTest
private static void service_whenConfiguredWithDuplicates_throwsAnException() // NOPMD: Test method name format
{
List<Application_Configuration__mdt> configurations = new List<Application_Configuration__mdt>
{
new Application_Configuration__mdt
(
Type__c = 'Service',
Object_Type__c = 'ApplicationTest.IServiceInterface',
Implementation__c = 'ApplicationTest.ServiceClass'
),
new Application_Configuration__mdt
(
Type__c = 'Service',
Object_Type__c = 'ApplicationTest.IServiceInterface',
Implementation__c = 'ApplicationTest.ServiceClass'
)
};

Test.startTest();
String exceptionMessage;
try
{
Application.applyConfiguration( configurations );
}
catch ( Application.InvalidApplicationConfigurationException e )
{
exceptionMessage = e.getMessage();
}
Test.stopTest();

ortoo_Asserts.assertContains( 'Duplicate configuration exists for Service - ApplicationTest.IServiceInterface', exceptionMessage, 'service, when configured with duplicates, will throw an exception' );
}

@isTest
private static void validator_whenReferenced_willBeConfiguredBasedOnMetadata() // NOPMD: Test method name format
{
Expand All @@ -105,7 +207,7 @@ private without sharing class ApplicationTest
),
new Application_Configuration__mdt
(
Type__c = 'Service',
Type__c = 'Validator',
Object_Type__c = 'Account',
Implementation__c = 'ApplicationTest.AccountValidator'
)
Expand All @@ -119,6 +221,40 @@ private without sharing class ApplicationTest
System.assert( validator instanceOf ContactValidator , 'Validator, when referenced, will be configured based on metadata' );
}

@isTest
private static void validator_whenConfiguredWithDuplicates_throwsAnException() // NOPMD: Test method name format
{
List<Application_Configuration__mdt> configurations = new List<Application_Configuration__mdt>
{
new Application_Configuration__mdt
(
Type__c = 'Validator',
Object_Type__c = 'Contact',
Implementation__c = 'ApplicationTest.ContactValidator'
),
new Application_Configuration__mdt
(
Type__c = 'Validator',
Object_Type__c = 'Contact',
Implementation__c = 'ApplicationTest.ContactValidator'
)
};

Test.startTest();
String exceptionMessage;
try
{
Application.applyConfiguration( configurations );
}
catch ( Application.InvalidApplicationConfigurationException e )
{
exceptionMessage = e.getMessage();
}
Test.stopTest();

ortoo_Asserts.assertContains( 'Duplicate configuration exists for Validator - Contact', exceptionMessage, 'validator, when configured with duplicates, will throw an exception' );
}

@isTest
private static void appLogic_whenReferenced_willBeConfiguredBasedOnMetadata() // NOPMD: Test method name format
{
Expand Down Expand Up @@ -146,6 +282,40 @@ private without sharing class ApplicationTest
System.assert( appLogic instanceOf AppLogicClass , 'AppLogic, when referenced, will be configured based on metadata' );
}

@isTest
private static void appLogic_whenConfiguredWithDuplicates_throwsAnException() // NOPMD: Test method name format
{
List<Application_Configuration__mdt> configurations = new List<Application_Configuration__mdt>
{
new Application_Configuration__mdt
(
Type__c = 'App Logic',
Object_Type__c = 'ApplicationTest.IAppLogicInterface',
Implementation__c = 'ApplicationTest.AppLogicClass'
),
new Application_Configuration__mdt
(
Type__c = 'App Logic',
Object_Type__c = 'ApplicationTest.IAppLogicInterface',
Implementation__c = 'ApplicationTest.AppLogicClass'
)
};

Test.startTest();
String exceptionMessage;
try
{
Application.applyConfiguration( configurations );
}
catch ( Application.InvalidApplicationConfigurationException e )
{
exceptionMessage = e.getMessage();
}
Test.stopTest();

ortoo_Asserts.assertContains( 'Duplicate configuration exists for App Logic - ApplicationTest.IAppLogicInterface', exceptionMessage, 'app logic, when configured with duplicates, will throw an exception' );
}

@isTest
private static void childRecordFinder_whenReferenced_willBeConfiguredBasedOnMetadata() // NOPMD: Test method name format
{
Expand Down Expand Up @@ -173,6 +343,40 @@ private without sharing class ApplicationTest
System.assert( childRecordFinder instanceOf ChildRecordFinderClass , 'childRecordFinder, when referenced, will be configured based on metadata' );
}

@isTest
private static void childRecordFinder_whenConfiguredWithDuplicates_throwsAnException() // NOPMD: Test method name format
{
List<Application_Configuration__mdt> configurations = new List<Application_Configuration__mdt>
{
new Application_Configuration__mdt
(
Type__c = 'Child Record Finder',
Object_Type__c = 'ApplicationTest.IChildRecordFinderInterface',
Implementation__c = 'ApplicationTest.ChildRecordFinderClass'
),
new Application_Configuration__mdt
(
Type__c = 'Child Record Finder',
Object_Type__c = 'ApplicationTest.IChildRecordFinderInterface',
Implementation__c = 'ApplicationTest.ChildRecordFinderClass'
)
};

Test.startTest();
String exceptionMessage;
try
{
Application.applyConfiguration( configurations );
}
catch ( Application.InvalidApplicationConfigurationException e )
{
exceptionMessage = e.getMessage();
}
Test.stopTest();

ortoo_Asserts.assertContains( 'Duplicate configuration exists for Child Record Finder - ApplicationTest.IChildRecordFinderInterface', exceptionMessage, 'child record finder, when configured with duplicates, will throw an exception' );
}

@isTest
private static void messageRenderer_whenReferenced_willBeConfiguredBasedOnMetadata() // NOPMD: Test method name format
{
Expand Down Expand Up @@ -200,6 +404,40 @@ private without sharing class ApplicationTest
System.assert( messageRenderer.getRenderer() instanceOf MessageRendererEngine.SobjectMessageAdder , 'messageRenderer, when referenced, will be configured based on metadata' );
}

@isTest
private static void messageRenderer_whenConfiguredWithDuplicates_throwsAnException() // NOPMD: Test method name format
{
List<Application_Configuration__mdt> configurations = new List<Application_Configuration__mdt>
{
new Application_Configuration__mdt
(
Type__c = 'Message Renderer',
Object_Type__c = 'MessageRendererEngine.VisualforceMessageRenderer',
Implementation__c = 'MessageRendererEngine.SobjectMessageAdder'
),
new Application_Configuration__mdt
(
Type__c = 'Message Renderer',
Object_Type__c = 'MessageRendererEngine.VisualforceMessageRenderer',
Implementation__c = 'MessageRendererEngine.SobjectMessageAdder'
)
};

Test.startTest();
String exceptionMessage;
try
{
Application.applyConfiguration( configurations );
}
catch ( Application.InvalidApplicationConfigurationException e )
{
exceptionMessage = e.getMessage();
}
Test.stopTest();

ortoo_Asserts.assertContains( 'Duplicate configuration exists for Message Renderer - MessageRendererEngine.VisualforceMessageRenderer', exceptionMessage, 'messageRenderer, when configured with duplicates, will throw an exception' );
}

@isTest
private static void applyConfiguration_whenARecordHasAnInvalidType_willThrowAnException() // NOPMD: Test method name format
{
Expand Down

0 comments on commit bf2ffc9

Please sign in to comment.