Skip to content

Commit

Permalink
Simplified passing of mapping into SearchOrderBy and added test for t…
Browse files Browse the repository at this point in the history
…he Null config
  • Loading branch information
rob-baillie-ortoo committed Apr 25, 2022
1 parent 502b1c6 commit 2685af3
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* * How to map from the result set fields to internal SObject fields
* * Which Base SObject is used to derive a record in the result set
*/
public interface ISearchConfiguration
public interface ISearchConfiguration extends IToSobjectFieldMapper
{
List<String> getRequiredFields();
List<String> getSortableFields();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Interface that defines classes that describe the configuration of searches.
*
* This includes the ability to define:
* * The fields that should be included in the result set
* * Which fields are sortable
* * How to map from the result set fields to internal SObject fields
* * Which Base SObject is used to derive a record in the result set
*/
public interface IToSobjectFieldMapper
{
String getMappedSobjectField( String resultField );
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>52.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,28 @@ public inherited sharing class SearchOrderBy
{
Contract.requires( properties != null, 'configure called with a null properties' );

return configure( properties, NullSearchConfiguration.class );
return configure( properties, NullToSobjectFieldMapper.class );
}

// TODO: add the interface IToSobjectFieldMapper
// TODO: Have ISearchConfiguration extend that
// TODO: Simplify NullSearchConfiguration and change to NullToSobjectFieldMapper

/**
* Configures the order by, defining its properties and the search configuration that defines the mappability
*
* @param Map<String,Object> The properties of the window. Should contain 'fieldName' and 'offset' properties as Strings
* @param Type The type of the SearchConfiguration object that should be used to determine the field mappings
* @param Type The type of the IToSobjectFieldMapper object that should be used to determine the field mappings
* @return SearchOrderBy Itself, allowing for a fluent interface
*/
public SearchOrderBy configure( Map<String,Object> properties, Type searchConfigurationType )
public SearchOrderBy configure( Map<String,Object> properties, Type toSobjectFieldMapperType )
{
Contract.requires( properties != null, 'configure called with a null properties' );
Contract.requires( searchConfigurationType != null, 'configure called with a null searchConfigurationType' );
Contract.requires( toSobjectFieldMapperType != null, 'configure called with a null toSobjectFieldMapperType' );

ISearchConfiguration searchConfiguration;
IToSobjectFieldMapper toSobjectFieldMapper;

try
{
searchConfiguration = (ISearchConfiguration)Application.APP_LOGIC.newInstance( searchConfigurationType );
toSobjectFieldMapper = (IToSobjectFieldMapper)Application.APP_LOGIC.newInstance( toSobjectFieldMapperType );
} catch ( Exception e ) {
Contract.assert( false, 'configure called with a searchConfigurationType ('+searchConfigurationType+') that does not implement ISearchConfiguration or does not have a parameterless constructor' );
Contract.assert( false, 'configure called with an Sobject Field Mapper ('+toSobjectFieldMapperType+') that does not implement IToSobjectFieldMapper or does not have a parameterless constructor' );
}

String resultsFieldName = (String)properties.get( 'fieldName' );
Expand All @@ -58,7 +54,7 @@ public inherited sharing class SearchOrderBy

if ( String.isNotBlank( resultsFieldName ) )
{
String mappedFieldName = searchConfiguration.getMappedSobjectField( resultsFieldName );
String mappedFieldName = toSobjectFieldMapper.getMappedSobjectField( resultsFieldName );

if ( String.isNotBlank( mappedFieldName ) )
{
Expand All @@ -82,26 +78,11 @@ public inherited sharing class SearchOrderBy
/**
* Null object implementation of the SearchConfiguration which allows unmapped Sobject fields to be used.
*/
public class NullSearchConfiguration implements ISearchConfiguration
public class NullToSobjectFieldMapper implements IToSobjectFieldMapper
{
public String getMappedSobjectField( String resultField )
{
return resultField;
}

public List<String> getRequiredFields()
{
return new List<String>();
}

public List<String> getSortableFields()
{
return new List<String>();
}

public SobjectType getBaseSobjectType()
{
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ public inherited sharing class SearchOrderByTest
'fieldName' => 'sourceFieldName',
'direction' => 'asc'
};
Type configurationType = ISearchConfiguration.class;
Type fieldMapperType = IToSobjectFieldMapper.class;

Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( configurationType );
Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( fieldMapperType );
configurationController
.expects( 'getMappedSobjectField' )
.withParameter( 'sourceFieldName' )
.returning( 'targetFieldName' );

Test.startTest();
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, configurationType );
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, fieldMapperType );
Test.stopTest();

configurationController.verify();
Expand All @@ -52,14 +52,14 @@ public inherited sharing class SearchOrderByTest
Map<String,Object> properties = new Map<String,Object>{
'direction' => 'asc'
};
Type configurationType = ISearchConfiguration.class;
Type fieldMapperType = IToSobjectFieldMapper.class;

Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( configurationType );
Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( fieldMapperType );
configurationController
.expectsNoCalls();

Test.startTest();
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, configurationType );
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, fieldMapperType );
Test.stopTest();

configurationController.verify();
Expand All @@ -77,14 +77,14 @@ public inherited sharing class SearchOrderByTest
'fieldName' => '',
'direction' => 'asc'
};
Type configurationType = ISearchConfiguration.class;
Type fieldMapperType = IToSobjectFieldMapper.class;

Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( configurationType );
Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( fieldMapperType );
configurationController
.expectsNoCalls();

Test.startTest();
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, configurationType );
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, fieldMapperType );
Test.stopTest();

configurationController.verify();
Expand All @@ -102,15 +102,15 @@ public inherited sharing class SearchOrderByTest
'fieldName' => 'unmapped',
'direction' => 'asc'
};
Type configurationType = ISearchConfiguration.class;
Type fieldMapperType = IToSobjectFieldMapper.class;

Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( configurationType );
Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( fieldMapperType );
configurationController
.when( 'getMappedSobjectField' )
.returns( null );

Test.startTest();
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, configurationType );
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, fieldMapperType );
Test.stopTest();

configurationController.verify();
Expand All @@ -127,15 +127,15 @@ public inherited sharing class SearchOrderByTest
Map<String,Object> properties = new Map<String,Object>{
'fieldName' => 'source'
};
Type configurationType = ISearchConfiguration.class;
Type fieldMapperType = IToSobjectFieldMapper.class;

Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( configurationType );
Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( fieldMapperType );
configurationController
.when( 'getMappedSobjectField' )
.returns( 'target' );

Test.startTest();
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, configurationType );
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, fieldMapperType );
Test.stopTest();

configurationController.verify();
Expand All @@ -153,15 +153,15 @@ public inherited sharing class SearchOrderByTest
'fieldName' => 'source',
'direction' => 'asc'
};
Type configurationType = ISearchConfiguration.class;
Type fieldMapperType = IToSobjectFieldMapper.class;

Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( configurationType );
Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( fieldMapperType );
configurationController
.when( 'getMappedSobjectField' )
.returns( 'target' );

Test.startTest();
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, configurationType );
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, fieldMapperType );
Test.stopTest();

configurationController.verify();
Expand All @@ -177,15 +177,15 @@ public inherited sharing class SearchOrderByTest
'fieldName' => 'source',
'direction' => 'desc'
};
Type configurationType = ISearchConfiguration.class;
Type fieldMapperType = IToSobjectFieldMapper.class;

Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( configurationType );
Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( fieldMapperType );
configurationController
.when( 'getMappedSobjectField' )
.returns( 'target' );

Test.startTest();
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, configurationType );
SearchOrderBy orderBy = new SearchOrderBy().configure( properties, fieldMapperType );
Test.stopTest();

configurationController.verify();
Expand All @@ -201,9 +201,9 @@ public inherited sharing class SearchOrderByTest
'fieldName' => 'source',
'direction' => 'invalid'
};
Type configurationType = ISearchConfiguration.class;
Type fieldMapperType = IToSobjectFieldMapper.class;

Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( configurationType );
Amoss_Instance configurationController = ApplicationMockRegistrar.registerMockAppLogic( fieldMapperType );
configurationController
.when( 'getMappedSobjectField' )
.returns( 'target' );
Expand All @@ -212,7 +212,7 @@ public inherited sharing class SearchOrderByTest
String exceptionMessage;
try
{
new SearchOrderBy().configure( properties, configurationType );
new SearchOrderBy().configure( properties, fieldMapperType );
}
catch ( Contract.AssertException e )
{
Expand All @@ -230,7 +230,7 @@ public inherited sharing class SearchOrderByTest
String exceptionMessage;
try
{
new SearchOrderBy().configure( null, ISearchConfiguration.class );
new SearchOrderBy().configure( null, IToSobjectFieldMapper.class );
}
catch ( Contract.RequiresException e )
{
Expand All @@ -256,7 +256,7 @@ public inherited sharing class SearchOrderByTest
}
Test.stopTest();

ortoo_Asserts.assertContains( 'configure called with a null searchConfigurationType', exceptionMessage, 'configure, when passed a null searchConfigurationType, will throw an exception' );
ortoo_Asserts.assertContains( 'configure called with a null toSobjectFieldMapperType', exceptionMessage, 'configure, when passed a null toSobjectFieldMapperType, will throw an exception' );
}

@isTest
Expand All @@ -274,7 +274,7 @@ public inherited sharing class SearchOrderByTest
}
Test.stopTest();

ortoo_Asserts.assertContains( 'configure called with a searchConfigurationType ('+SearchOrderByTest.class+') that does not implement ISearchConfiguration or does not have a parameterless constructor', exceptionMessage, 'configure, when passed an invalid searchConfigurationType, will throw an exception' );
ortoo_Asserts.assertContains( 'configure called with an Sobject Field Mapper ('+SearchOrderByTest.class+') that does not implement IToSobjectFieldMapper or does not have a parameterless constructor', exceptionMessage, 'configure, when passed an invalid toSobjectFieldMapperType, will throw an exception' );
}

@isTest
Expand All @@ -292,29 +292,26 @@ public inherited sharing class SearchOrderByTest
}
Test.stopTest();

ortoo_Asserts.assertContains( 'configure called with a searchConfigurationType ('+SearchOrderByTest.NoParameterlessConstructor.class+') that does not implement ISearchConfiguration or does not have a parameterless constructor', exceptionMessage, 'configure, when passed an invalid searchConfigurationType, will throw an exception' );
ortoo_Asserts.assertContains( 'configure called with an Sobject Field Mapper ('+SearchOrderByTest.NoParameterlessConstructor.class+') that does not implement IToSobjectFieldMapper or does not have a parameterless constructor', exceptionMessage, 'configure, when passed an invalid toSobjectFieldMapperType, will throw an exception' );
}

@isTest
private static void nullToSobjectFieldMapper_getMappedSobjectField_whenCalled_returnsWhatWasPassedIn() // NOPMD: Test method name format
{
Test.startTest();
String got = new SearchOrderBy.NullToSobjectFieldMapper().getMappedSobjectField( 'expected' );
Test.stopTest();

class NoParameterlessConstructor implements ISearchConfiguration
System.assertEquals( 'expected', got, 'NullToSobjectFieldMapper_getMappedSobjectField, when called, will return what was passed in' );
}

class NoParameterlessConstructor implements IToSobjectFieldMapper
{
public NoParameterlessConstructor( String parameter ) {}

public List<String> getRequiredFields()
{
return null;
}
public List<String> getSortableFields()
{
return null;
}
public String getMappedSobjectField( String resultField )
{
return null;
}
public SobjectType getBaseSobjectType()
{
return null;
}
}
}

0 comments on commit 2685af3

Please sign in to comment.