Skip to content

bugfix for Issue 221 #449

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions sfdx-source/apex-common/main/classes/fflib_SObjectUnitOfWork.cls
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ public virtual class fflib_SObjectUnitOfWork
{
for (Schema.SObjectType sObjectType : m_sObjectTypes)
{
m_relationships.get(sObjectType.getDescribe().getName()).resolve();
m_dml.dmlUpdate(m_dirtyMapByType.get(sObjectType.getDescribe().getName()).values());
}
}
Expand Down Expand Up @@ -809,12 +810,11 @@ public virtual class fflib_SObjectUnitOfWork
public void resolve()
{
// Resolve relationships
for (IRelationship relationship : m_relationships)
{
//relationship.Record.put(relationship.RelatedToField, relationship.RelatedTo.Id);
relationship.resolve();
}

for (Integer i = (m_relationships.size() - 1); i >= 0; i--) {
if (m_relationships.get(i).resolve()) {
m_relationships.remove(i);
}
}
}

public void add(SObject record, Schema.SObjectField relatedToField, Schema.SObjectField externalIdField, Object externalId)
Expand Down Expand Up @@ -874,7 +874,7 @@ public virtual class fflib_SObjectUnitOfWork

private interface IRelationship
{
void resolve();
Boolean resolve();
}

private class RelationshipByExternalId implements IRelationship
Expand All @@ -886,11 +886,16 @@ public virtual class fflib_SObjectUnitOfWork
public Schema.SObjectField ExternalIdField;
public Object ExternalId;

public void resolve()
public Boolean resolve()
{
if (ExternalId == null) {
return false;
}

SObject relationshipObject = this.RelatedTo.newSObject();
relationshipObject.put( ExternalIdField.getDescribe().getName(), this.ExternalId );
this.Record.putSObject( this.RelationshipName, relationshipObject );
return true;
}
}

Expand All @@ -900,9 +905,14 @@ public virtual class fflib_SObjectUnitOfWork
public Schema.SObjectField RelatedToField;
public SObject RelatedTo;

public void resolve()
public Boolean resolve()
{
if (String.isBlank(this.relatedTo.Id)) {
return false;
}

this.Record.put( this.RelatedToField, this.RelatedTo.Id);
return true;
}
}

Expand All @@ -911,9 +921,14 @@ public virtual class fflib_SObjectUnitOfWork
public Messaging.SingleEmailMessage email;
public SObject relatedTo;

public void resolve()
public Boolean resolve()
{
if (String.isBlank(this.relatedTo.Id)) {
return false;
}

this.email.setWhatId( this.relatedTo.Id );
return true;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,63 @@ private with sharing class fflib_SObjectUnitOfWorkTest
);
}

@IsTest
private static void testRegisterDirtyWithRelationship() {
// GIVEN an existing opportunity
Opportunity existingOpp = new Opportunity(
Id = fflib_IDGenerator.generate(Schema.Opportunity.SObjectType),
Name = 'Existing Opportunity',
StageName = 'Closed',
CloseDate = System.today()
);
// AND an existing Account to which the existing opportunity will be related to
Account newAccount = new Account(
Name = 'New Account'
);

// WHEN
Test.startTest();
MockDML mockDML = new MockDML();
List<Schema.SObjectType> mySobjects = new List<Schema.SObjectType>{
Opportunity.SObjectType,
Account.SObjectType
};
fflib_SObjectUnitOfWork uow = new fflib_SObjectUnitOfWork(mySobjects, mockDML);
uow.registerNew(newAccount);
uow.registerDirty(existingOpp, Opportunity.AccountId, newAccount);
uow.commitWork();
Test.stopTest();

// THEN
System.Assert.isTrue(
new fflib_MatcherDefinitions.SObjectsWith(
new List<Map<SObjectField, Object>>{
new Map<SObjectField, Object>
{
Account.Id => newAccount.Id,
Account.Name => 'New Account'
}
}
).matches(mockDML.recordsForInsert),
'The new account record does not match'
);

// AND
System.Assert.isTrue(
new fflib_MatcherDefinitions.SObjectsWith(
new List<Map<SObjectField, Object>>{
new Map<SObjectField, Object>
{
Opportunity.Id => existingOpp.Id,
Opportunity.Name => 'Existing Opportunity',
Opportunity.StageName => 'Closed',
Opportunity.AccountId => newAccount.Id
}
}
).matches(mockDML.recordsForUpdate),
'The opportunity record should be related to the new Account'
);
}
@IsTest
private static void testRegisterUpsert() {
Opportunity existingOpp = new Opportunity(
Expand Down Expand Up @@ -824,6 +881,12 @@ private with sharing class fflib_SObjectUnitOfWorkTest

public void dmlInsert(List<SObject> objList)
{
for (SObject obj : objList) {
if (obj == null) {
continue;
}
obj.Id = fflib_IDGenerator.generate(obj.getSObjectType());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ClayChipps and @jprichter -- Please add a null check on obj before trying to generate the mock Id.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}
this.recordsForInsert.addAll(objList);
}

Expand Down
Loading