apex-enterprise-patterns / fflib-apex-common

Common Apex Library supporting Apex Enterprise Patterns and much more!
BSD 3-Clause "New" or "Revised" License
899 stars 514 forks source link

Selected tests in fflib_SObjectSelectorTest fail in an org with encryption enabled on Account.Name #451

Closed nicholas-sullivan closed 1 year ago

nicholas-sullivan commented 1 year ago

Describe the bug The following tests in fflib_SObjectSelectorTest fail in orgs with Shield Encryption enabled on Account/Opportunity Name.

Both of these tests make assertions that the query will contain.

FROM Account ORDER BY Name

However getOrderBy() in fflib_SObjectSelector contains the following logic.

Schema.SObjectField nameField = describeWrapper.getNameField();
if (nameField != null && !nameField.getDescribe().isEncrypted()) {
  m_orderBy = nameField.getDescribe().getName();
} else {
  m_orderBy = DEFAULT_SORT_FIELD;

Where DEFAULT_SORT_FIELD is set to 'CreatedDate'

This means for orgs without the Name field encrypted the generated SOQL will order by Name otherwise ordering by CreatedDate.

As the tests themselves are hardcoded to use Name in the assertion.

To Reproduce

Run the following tests from fflib_SObjectSelectorTest.

Expected behavior

Expected that both tests pass, instead both fail, instead. Disabling encryption on Account.Name will cause the tests to pass.

System.AssertException: Assertion Failed:

Expected:

SELECT name, id, annualrevenue, accountnumber,(.*)\(SELECT name, id, amount, closedate FROM Opportunities ORDER BY Name ASC NULLS FIRST \) FROM Account WITH SYSTEM_MODE ORDER BY Name ASC NULLS FIRST

Actual:

SELECT name, id, annualrevenue, accountnumber, (SELECT name, id, amount, closedate FROM Opportunities ORDER BY Name ASC NULLS FIRST ) FROM Account WITH SYSTEM_MODE ORDER BY CreatedDate ASC NULLS FIRST

Version Latest Release

daveespo commented 1 year ago

@nicholas-sullivan thanks for the fix!

michael-weglinski-afs commented 9 months ago

It looks like the fix to address the order by field in toSOQL_When_SystemModeAndChildRelationship_Expect_WellFormedSOQL is leveraging the order by field for the main query and the subselect, but the subselect order by field could be different.

String expected = String.format('SELECT name, id, annualrevenue, accountnumber, (currencyisocode, )?\\(SELECT name, id, amount, closedate(, currencyisocode)? FROM Opportunities ORDER BY {0} ASC NULLS FIRST \\) FROM Account WITH SYSTEM_MODE ORDER BY {0} ASC NULLS FIRST ', new List<String>{sel.getOrderBy()});

In our case, the Account Name field is encrypted but the Opportunity Name field is not encrypted. So the expected result replaces with CreatedDate in both the main query and the subselect, but our actual result uses CreatedDate for the main query and Name for the subselect.

Apologies if this should be reported differently.