Skip to content

Commit

Permalink
Merge pull request apex-enterprise-patterns#24 from OrtooApps/main
Browse files Browse the repository at this point in the history
Update to latest main
  • Loading branch information
rob-baillie-ortoo committed Mar 24, 2022
2 parents aedd0a1 + 69a9fea commit 2ccc43a
Show file tree
Hide file tree
Showing 15 changed files with 378 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ public virtual with sharing class fflib_Criteria
public virtual fflib_Criteria addOrCriteria(fflib_Criteria subCriteria)
{
subCriteria.orCriteria();
subCriteria.setEmbraced(true);
evaluators.add(subCriteria);
addCriteria( subCriteria );
return this;
}

Expand All @@ -152,6 +151,31 @@ public virtual with sharing class fflib_Criteria
public virtual fflib_Criteria addAndCriteria(fflib_Criteria subCriteria)
{
subCriteria.andCriteria();
addCriteria( subCriteria );
return this;
}

/**
* Adds a sub criteria, not altering the join (AND / OR)
*
* @param subCriteria The condition of the sub criteria
*
* @return An instance of itself to enable method chaining
*
* @example
* new fflib_Criteria()
* .orCriteria()
* .equalTo(Account.Name, 'Example')
* .addCriteria(
* new fflib_Criteria()
* .equalTo(Account.AccountNumber, '0001')
* .equalTo(Account.ShippingCountry, 'USA'))
*
* Evaluates:
* Name = 'Example' OR (AccountNumber = '0001' AND ShippingCountry = 'USA')
*/
public fflib_Criteria addCriteria(fflib_Criteria subCriteria)
{
subCriteria.setEmbraced(true);
evaluators.add(subCriteria);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,23 @@ private with sharing class fflib_CriteriaTest
);
}

@IsTest
static void itShouldEvaluateAddCondition_First()
{
System.assert(
new fflib_Criteria()
.orCriteria()
.equalTo(Account.Name, A_STRING)
.equalTo(Account.Name, ANOTHER_STRING)
.addCriteria(
new fflib_Criteria()
.equalTo(Account.Name, HELLO_WORLD)
.equalTo(Account.AccountNumber, '002')
)
.evaluate(new Account(Name = ANOTHER_STRING))
);
}

@IsTest
static void itShouldEvaluateAddAndCondition_First()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,33 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria
return this;
}

/**
* Adds a sub-criteria
*
* @param ortoo_Criteria The condition of the sub criteria
* @return ortoo_Criteria Itself, allowing for a fluent interface
*
* @example
* new ortoo_Criteria()
* .orCriteria()
* .equalTo(Account.Name, 'Example')
* .addCriteria(
* new ortoo_Criteria()
* .equalTo(Account.AccountNumber, '0001')
* .equalTo(Account.ShippingCountry, 'USA'))
*
* Evaluates:
* Name = 'Example' OR (AccountNumber = '0001' AND ShippingCountry = 'USA')
*/
public ortoo_Criteria addCriteria( ortoo_Criteria subCriteria )
{
Contract.requires( subCriteria != null, 'addCriteria called with a null subCriteria' );
Contract.requires( subCriteria.criteria != null, 'addCriteria called with a subCriteria that has no criteria defined' );

criteria.addCriteria( subCriteria.criteria );
return this;
}

/**
* Adds a sub-criteria with AND comparator
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,48 @@ private without sharing class ortoo_CriteriaTest
System.assertEquals( expected, got, 'andAndCriteria, when given sub criteria, will add the subcriteria set as AND criteria' );
}

@isTest
private static void andCriteria_whenGivenSubCriteria_addsTheSubCriteriaSetAsOriginalSpec() // NOPMD: Test method name format
{
ortoo_Criteria criteria = new ortoo_Criteria();

Test.startTest();
String got = criteria
.equalTo(Account.Name, 'Example')
.addCriteria(
new ortoo_Criteria()
.andCriteria()
.equalTo(Account.AccountNumber, '0001')
.equalTo(Account.AccountNumber, '0002'))
.toSoql();
Test.stopTest();

String expected = 'Name=\'Example\' AND (AccountNumber=\'0001\' AND AccountNumber=\'0002\')';

System.assertEquals( expected, got, 'andCriteria, when given sub criteria, will add the subcriteria set as originally configured (was and)' );
}

@isTest
private static void andCriteria_whenGivenSubCriteria_addsTheSubCriteriaSetAsOriginalSpec_2() // NOPMD: Test method name format
{
ortoo_Criteria criteria = new ortoo_Criteria();

Test.startTest();
String got = criteria
.equalTo(Account.Name, 'Example')
.addCriteria(
new ortoo_Criteria()
.orCriteria()
.equalTo(Account.AccountNumber, '0001')
.equalTo(Account.AccountNumber, '0002'))
.toSoql();
Test.stopTest();

String expected = 'Name=\'Example\' AND (AccountNumber=\'0001\' OR AccountNumber=\'0002\')';

System.assertEquals( expected, got, 'andCriteria, when given sub criteria, will add the subcriteria set as originally configured (was or)' );
}

@isTest
private static void formulaCriteria_whenGivenCriteria_addsTheCriteriaInLineWithTheFormula() // NOPMD: Test method name format
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,10 @@ public inherited sharing class DmlChildContext
uow.registerRelationship( child, relatedByField, parent );
}
}

@testVisible
private SobjectField getRelatedByField()
{
return relatedByField;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,16 @@ public inherited sharing class DmlDefiner
return sobjects;
}

/**
* States if this definer is configured to ensure that other records are deleted
*
* @return Boolean Will other records be deleted
*/
public Boolean getWillDeleteOtherRecords() {
Contract.assert( options != null, 'getWillDeleteOtherRecords was called when options was null' );
return options.getWillDeleteOtherRecords();
}

@testVisible
private List<DmlRecord> getDmlRecords() {
return recordsToDml;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,14 @@ public inherited sharing class DmlDefinerOptions
return new DmlDefinerOptions()
.setOtherRecordsMode( OtherRecordsOption.IGNORE_RECORDS );
}

/**
* States if this definer will instruct to delete other records
*
* @return Boolean Should other records be deleted?
*/
public Boolean getWillDeleteOtherRecords()
{
return getOtherRecordsMode() == OtherRecordsOption.DELETE_RECORDS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,27 @@ public virtual inherited sharing class DmlRecord
@testVisible
protected DmlDefiner getChildDefiner( String childRecordType )
{
Contract.requires( childRecordType != null, 'getChildDefiner called with a null childRecordType' );

checkTypeIsValid( childRecordType );
return this.childRecordsByType.get( childRecordType );
}


/**
* Returns the Sobjects that represent the child records for the given relationship
*
* @param String The 'Type' that will identify the child relationship for which to return
* @return List<Sobject> The List representing the child records currently on this DmlRecord
*/
@testVisible
protected List<Sobject> getChildSobjects( String childRecordType )
{
Contract.requires( childRecordType != null, 'getChildSobjects called with a null childRecordType' );

return getChildDefiner( childRecordType ).getSobjects();
}

/**
* Sets the DmlDefinerOptions for the given child relationship.
*
Expand Down Expand Up @@ -266,4 +283,10 @@ public virtual inherited sharing class DmlRecord
checkTypeIsValid( childRecordType );
return childContextsByType.get( childRecordType );
}

@testVisible
private Boolean getWillDeleteOtherRecords( String childRecordType )
{
return getChildDefiner( childRecordType )?.getWillDeleteOtherRecords();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,30 @@ private without sharing class DmlDefinerOptionsTest

ortoo_Asserts.assertContains( 'setOtherRecordsMode called with a null otherRecordsMode', exceptionMessage, 'setOtherRecordsMode, when called with null, will throw an exception' );
}

@isTest
private static void getWillDeleteOtherRecords_whenRecordModeIsDelete_returnsTrue() // NOPMD: Test method name format
{
DmlDefinerOptions options = new DmlDefinerOptions();

Test.startTest();
options.setOtherRecordsMode( DmlDefinerOptions.OtherRecordsOption.DELETE_RECORDS );
Boolean got = options.getWillDeleteOtherRecords();
Test.stopTest();

System.assertEquals( true, got, 'getWillDeleteOtherRecords, when the record mode is DELETE_RECORDS, will return true' );
}

@isTest
private static void getWillDeleteOtherRecords_whenRecordModeIsIgnore_returnsFalse() // NOPMD: Test method name format
{
DmlDefinerOptions options = new DmlDefinerOptions();

Test.startTest();
options.setOtherRecordsMode( DmlDefinerOptions.OtherRecordsOption.IGNORE_RECORDS );
Boolean got = options.getWillDeleteOtherRecords();
Test.stopTest();

System.assertEquals( false, got, 'getWillDeleteOtherRecords, when the record mode is IGNORE_RECORDS, will return false' );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,4 +311,24 @@ private without sharing class DmlDefinerTest

ortoo_Asserts.assertContains( 'addPreSaveAction called with a null action', exceptionMessage, 'addPreSaveAction, when given null, will throw an exception' );
}

@isTest
private static void getWillDeleteOtherRecords_willReturnTheValueFromTheDefiner() // NOPMD: Test method name format
{
DmlDefiner dmlDefiner = new DmlDefiner();

Amoss_Instance optionsController = new Amoss_Instance( DmlDefinerOptions.class );
optionsController
.expects( 'getWillDeleteOtherRecords' )
.returning( true );

Test.startTest();
dmlDefiner.setOptions( (DmlDefinerOptions)optionsController.generateDouble() );
Boolean got = dmlDefiner.getWillDeleteOtherRecords();
Test.stopTest();

optionsController.verify();

System.assertEquals( true, got, 'getWillDeleteOtherRecords, will call getWillDeleteOtherRecords on the options and return the result' );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,61 @@ private without sharing class DmlRecordTest
ortoo_Asserts.assertContains( 'Invalid', exceptionMessage, 'getChildDefiner, when given a child type that does not exist, will throw an exception' );
}

@isTest
private static void getChildSobjects_whenGivenAValidChildType_willReturnTheChildrenForThatType() // NOPMD: Test method name format
{
DmlRecord dmlRecord = new DmlRecord( new Account() );
dmlRecord.addChildContext( 'Contacts', new DmlChildContext( Contact.AccountId, IChildRecordFinder.class ) );

List<Contact> contacts = new List<Contact>{
new Contact( LastName = 'name1' ),
new Contact( LastName = 'name2' )
};

Test.startTest();
dmlRecord
.addChild( 'Contacts', new DmlRecord( contacts[0] ) )
.addChild( 'Contacts', new DmlRecord( contacts[1] ) );

List<Contact> got = dmlRecord.getChildSobjects( 'Contacts' );
Test.stopTest();

System.assertEquals( contacts, got, 'getChildSobjects, when given a valid child type, will return the sobjects registered for that type' );
}

@isTest
private static void getChildSobjects_whenGivenAValidChildTypeThatHasNoChildren_willReturnAnEmptyList() // NOPMD: Test method name format
{
DmlRecord dmlRecord = new DmlRecord( new Account() );
dmlRecord.addChildContext( 'Contacts', new DmlChildContext( Contact.AccountId, IChildRecordFinder.class ) );

Test.startTest();
List<Contact> got = dmlRecord.getChildSobjects( 'Contacts' );
Test.stopTest();

System.assertEquals( new List<Contact>(), got, 'getChildSobjects, when given a valid child type that has no children, will return an empty list' );
}

@isTest
private static void getChildSobjects_whenGivenAChildTypeThatDoesNotExist_willThrowAnException() // NOPMD: Test method name format
{
DmlRecord dmlRecord = new DmlRecord( new Account() );

Test.startTest();
String exceptionMessage;
try
{
dmlRecord.getChildSobjects( 'Invalid' );
}
catch ( Contract.AssertException e )
{
exceptionMessage = e.getMessage();
}
Test.stopTest();

ortoo_Asserts.assertContains( 'Invalid', exceptionMessage, 'getChildSobjects, when given a child type that does not exist, will throw an exception' );
}

@isTest
private static void setChildDmlOptions_whenGivenADmlDefinerOptions_willSetThatOnTheChildDefiner() // NOPMD: Test method name format
{
Expand Down
20 changes: 20 additions & 0 deletions framework/default/ortoo-core/default/classes/utils/StringUtils.cls
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,24 @@ public inherited sharing class StringUtils

return String.join( ListUtils.convertToListOfStrings( listOfObjects ), delimiter );
}

/**
* Given a String, will safely cut it to the desired length, returning the original string if it is already shorter
*
* @param String The string to cut
* @param Integer The length to cut the string to
* @return String The cut string
*/
public static String cut( String originalString, Integer length )
{
Contract.requires( originalString != null, 'cut called with a null originalString' );
Contract.requires( length != null, 'cut called with a null length' );
Contract.requires( length >= 0, 'cut called with a negative length' );

if ( originalString.length() < length )
{
return originalString;
}
return originalString.substring( 0, length );
}
}
Loading

0 comments on commit 2ccc43a

Please sign in to comment.