Skip to content

Commit

Permalink
Merge pull request #247 from wimvelzeboer/feature/MockingDomaingetCha…
Browse files Browse the repository at this point in the history
…ngesRecords

feature/mocking domain getChangedRecords
  • Loading branch information
ImJohnMDaniel committed Dec 30, 2019
2 parents df5c61d + c3b1bca commit b69f211
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 14 deletions.
68 changes: 55 additions & 13 deletions fflib/src/classes/fflib_SObjectDomain.cls
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,34 @@ public virtual with sharing class fflib_SObjectDomain
* Provides access to the data represented by this domain class
**/
public List<SObject> Records { get; private set;}



/**
* Provides access to Trigger.oldMap and allowing it to be mocked in unit-tests
**/
@TestVisible
protected Map<Id, SObject> ExistingRecords
{
get
{
if (ExistingRecords == null)
{
if (System.Test.isRunningTest() & Test.Database.hasRecords())
{
// If in test context and records are in the mock database use those instead of Trigger.oldMap
ExistingRecords = Test.Database.oldRecords;
}
else
{
ExistingRecords = Trigger.oldMap;
}
}
return ExistingRecords;

}
private set;
}

/**
* Derived from the records provided during construction, provides the native describe for the standard or custom object
**/
Expand Down Expand Up @@ -279,14 +306,22 @@ public virtual with sharing class fflib_SObjectDomain
public List<SObject> getChangedRecords(Set<String> fieldNames)
{
List<SObject> changedRecords = new List<SObject>();
for(SObject newRecord : Records)
for (SObject newRecord : Records)
{
Id recordId = (Id)newRecord.get('Id');
if(Trigger.oldMap == null || !Trigger.oldMap.containsKey(recordId)) continue;
SObject oldRecord = Trigger.oldMap.get(recordId);
for(String fieldName : fieldNames)
Id recordId = (Id) newRecord.get('Id');
if (this.ExistingRecords == null || !this.ExistingRecords.containsKey(recordId))
{
if(oldRecord.get(fieldName) != newRecord.get(fieldName)) changedRecords.add(newRecord);
continue;
}

SObject oldRecord = this.ExistingRecords.get(recordId);
for (String fieldName : fieldNames)
{
if (oldRecord.get(fieldName) != newRecord.get(fieldName))
{
changedRecords.add(newRecord);
break; // prevents the records from being added multiple times
}
}
}
return changedRecords;
Expand All @@ -299,14 +334,21 @@ public virtual with sharing class fflib_SObjectDomain
public List<SObject> getChangedRecords(Set<Schema.SObjectField> fieldTokens)
{
List<SObject> changedRecords = new List<SObject>();
for(SObject newRecord : Records)
for (SObject newRecord : Records)
{
Id recordId = (Id)newRecord.get('Id');
if(Trigger.oldMap == null || !Trigger.oldMap.containsKey(recordId)) continue;
SObject oldRecord = Trigger.oldMap.get(recordId);
for(Schema.SObjectField fieldToken : fieldTokens)
Id recordId = (Id) newRecord.get('Id');
if (this.ExistingRecords == null || !this.ExistingRecords.containsKey(recordId))
{
continue;
}
SObject oldRecord = this.ExistingRecords.get(recordId);
for (Schema.SObjectField fieldToken : fieldTokens)
{
if(oldRecord.get(fieldToken) != newRecord.get(fieldToken)) changedRecords.add(newRecord);
if (oldRecord.get(fieldToken) != newRecord.get(fieldToken))
{
changedRecords.add(newRecord);
break; // prevents the records from being added multiple times
}
}
}
return changedRecords;
Expand Down
90 changes: 89 additions & 1 deletion fflib/src/classes/fflib_SObjectDomainTest.cls
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,85 @@ private with sharing class fflib_SObjectDomainTest
}
);
}



@IsTest
private static void itShouldReturnTheChangedRecordsBySObjectFields()
{
// GIVEN a domain with old and changed records

Id idLuke = fflib_IDGenerator.generate(Account.SObjectType);
Id idHan = fflib_IDGenerator.generate(Account.SObjectType);
Id idLeia = fflib_IDGenerator.generate(Account.SObjectType);
List<Account> oldRecords = new List<Account>
{
new Account(Id = idLuke, Name = 'Luke', Description = 'Jedi'),
new Account(Id = idHan, Name = 'Han', Description = 'Pilot'),
new Account(Id = idLeia, Name = 'Leia')
};

List<Account> newRecords = oldRecords.deepClone(true, true, true);
newRecords.get(0).Name = 'Luke SkyWalker';
newRecords.get(0).Description = 'Jedi Master';
newRecords.get(1).Name = 'Han Solo';
Accounts accounts = new Accounts(newRecords);
accounts.ExistingRecords = new Map<Id, SObject>(oldRecords);

// WHEN we create a domain with ExistingRecords and request the changed records
List<SObject> result = accounts.getChangedRecords(
new Set<Schema.SObjectField>
{
Account.Name,
Account.Description
}
);

// THEN it should only return the changed records
Map<Id, SObject> resultMap = new Map<Id, SObject>(result);
System.assertEquals(2, result.size());
System.assert(resultMap.containsKey(idLuke));
System.assert(resultMap.containsKey(idHan));
}

@IsTest
private static void itShouldReturnTheChangedRecordsByStringFields()
{
// GIVEN a domain with old and changed records

Id idLuke = fflib_IDGenerator.generate(Account.SObjectType);
Id idHan = fflib_IDGenerator.generate(Account.SObjectType);
Id idLeia = fflib_IDGenerator.generate(Account.SObjectType);
List<Account> oldRecords = new List<Account>
{
new Account(Id = idLuke, Name = 'Luke', Description = 'Jedi'),
new Account(Id = idHan, Name = 'Han', Description = 'Pilot'),
new Account(Id = idLeia, Name = 'Leia')
};

List<Account> newRecords = oldRecords.deepClone(true, true, true);
newRecords.get(0).Name = 'Luke SkyWalker';
newRecords.get(0).Description = 'Jedi Master';
newRecords.get(1).Name = 'Han Solo';
Accounts accounts = new Accounts(newRecords);
fflib_SObjectDomain.Test.Database.onUpdate(newRecords, new Map<Id, SObject>(oldRecords));

// WHEN we create a domain with ExistingRecords and request the changed records
List<SObject> result = accounts.getChangedRecords(
new Set<String>
{
'Name',
'Description'
}
);

// THEN it should only return the changed records
Map<Id, SObject> resultMap = new Map<Id, SObject>(result);
System.assertEquals(2, result.size());
System.assert(resultMap.containsKey(idLuke));
System.assert(resultMap.containsKey(idHan));
}


/**
* Create test user
**/
Expand Down Expand Up @@ -413,4 +491,14 @@ private with sharing class fflib_SObjectDomainTest
}
*/
}



private class Accounts extends fflib_SObjectDomain
{
public Accounts(List<SObject> records)
{
super(records);
}
}
}

0 comments on commit b69f211

Please sign in to comment.