Overview

Surfaced in #3534561: Integrate with core's default content exporter.

Calculating dependencies is not calculating properly the intermediate dependencies. It only includes "both ends".

E.g. if a component instance depends on a media which depends on a file, we are not getting the right dependencies: "media" dependencies are missing.

See attached failing functional test.

This is a bug that landed in #3457504: XB field type: calculate all dependencies, store them, surface in new Component "Audit" operation and went unnoticed.

Proposed resolution

Expand test expectations in kernel tests, but keep the new functional test.

User interface changes

None. (Other than the implicit consequence: more complete config dependencies means there's more modules/themes whose uninstallation and config whose deletion will be prevented. 👍 That's why this is tagged data integrity.)

Issue fork canvas-3544604

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

penyaskito created an issue. See original summary.

penyaskito’s picture

Issue summary: View changes
wim leers’s picture

Priority: Normal » Major
Issue tags: +data integrity, +Missing dependency

Fantastic find!

wim leers’s picture

wim leers’s picture

Status: Active » Needs work
effulgentsia’s picture

Issue tags: -stable blocker +RC blocker

Not every stable blocker needs to block an RC, but this one does.

wim leers’s picture

Assigned: Unassigned » wim leers
Status: Needs work » Needs review
wim leers’s picture

Status: Needs review » Needs work
Issue tags: +Needs followup

Per https://git.drupalcode.org/project/canvas/-/merge_requests/23/diffs#note....

I think I've got all the necessary remaining pieces ready locally. Too tired to finish this today though. Will finish tomorrow AM.

wim leers’s picture

Title: Calculating dependencies not including the intermediate dependencies » Calculating dependencies of `ReferenceField(Type)PropExpression` is missing intermediate dependencies
Priority: Major » Critical
Issue summary: View changes
Issue tags: -Needs followup
Related issues: +#3457504: XB field type: calculate all dependencies, store them, surface in new Component "Audit" operation

Follow-up created: #3547579: Introduce a new cache tags aware prop shape repository, so changes affecting prop shape calculation can force the re-invoke of hook_canvas_storable_shape_prop_alter. Really, it's not a follow-up for this issue, but just a completely separate bug that was surfaced by this issue's new functional test coverage 😅

wim leers’s picture

Assigned: wim leers » penyaskito
Status: Needs work » Reviewed & tested by the community

All done and fixed. Sprinkled ℹ️ remarks for @penyaskito to review and do the final sign-off. He found this, he reported it, he wrote the test coverage to first prove this was broken.

So I think he's the perfect person to confirm that what I did is correct 😊

penyaskito’s picture

penyaskito’s picture

Confirmed this fixes the dependencies also for the export as expected (see issue/canvas-3534561@616bb298). Now 100% sure to merge this.

wim leers’s picture

Assigned: penyaskito » Unassigned

Thanks for all the due diligence you did at #3534561-37: Integrate with core's default content exporter, @penyaskito! 👏🙏

This indeed allows us to merge this with confidence 😊

  • wim leers committed 65bd155e on 1.x authored by penyaskito
    [#3544604] fix(Data model): Calculating dependencies of `ReferenceField(...
wim leers’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.

wim leers’s picture

wim leers’s picture

Status: Fixed » Active
Issue tags: +Needs update path

Actually, this needs update path tests. Similar to the update path + test coverage at https://www.drupal.org/node/3539207.

(We got rid of that update path test coverage in the XB → Canvas rename.)

That'll be a good baseline to establish 👍

penyaskito’s picture

Assigned: Unassigned » penyaskito

nagwani’s picture

Issue tags: -RC blocker
penyaskito’s picture

Assigned: penyaskito » wim leers
Status: Active » Needs review
Issue tags: -Needs update path

This is ready for review. Assigning to Wim, but I think this needs @larowlan's input too.

wim leers’s picture

Assigned: wim leers » penyaskito
Status: Needs review » Needs work
  1. This looks fantastic! 🤩
  2. AFAICT no update path is necessary for JavaScriptComponent config entities 😇
  3. I'm a bit worried about recalculating all dependencies to check whether an update is necessary; why not rely on the presence of ReferenceField(Type)PropExpression instead? Described how I think that can work.
  4. I think the various add-* files to construct a config entity with a component instance whose dependencies would've been incorrectly calculated prior to !23 are fine, but unnecessarily complex. I think we could instead be using the exact same component tree with a ReferenceFieldTypePropExpression in a StaticPropSource in all of them. Special case for ContentTemplate, where I'd want to see a <code>ReferenceFieldPropExpression in a DynamicPropSource in addition.
    That would then mean that UpdateIntermediateDependenciesUpdateTest could become 10x simpler: it'd just check for the same component instance UUID in a Pattern, a PageRegion, a ContentTemplate and a FieldConfig, and verify that additional dependencies appeared after the update. For ContentTemplate, you'd do an additional check.
    IOW: the same before vs after expectations could be applied to all of the config-entities-under-test. It'd make the update path test coverage much easier to review and maintain. (And would be an even better reference for future update paths!)
  5. Last but not least: shouldn't we also be updating all content entities; at minimum the default revision, preferably all revisions?

    https://www.drupal.org/node/3539207 didn't need to do that because it was an optimization, but here it is a fix that impacts data integrity: without such dependencies, in theory it's possible that e.g. the intermediary Media entity gets deleted because the content entity's component tree depended only on the File entity that the Media pointed to.

    However: A) I remember us discussing this and @effulgentsia convincing us we don't need that?, B) deleting content entities doesn't actually check the impact on things depending on it, see \Drupal\Core\Entity\ContentEntityDeleteForm and \Drupal\Core\Entity\EntityDeleteForm::buildForm(), so even if we did update all revisions' inputs' dependencies in the DB, it would have zero effect. The only effect it would have, is to make Canvas' Audit functionality more precise.

    Conclusion: I'm fine with proceeding without this, especially given this is not yet a stable module.

wim leers’s picture

#24.4 has not yet been addressed yet. 🙏 That'd make these tests much easier to understand and much more maintainable.

penyaskito’s picture

A snippet that I used for generating + inspecting the dump:

https://git.drupalcode.org/-/snippets/248


#24.4: Added dynamic prop to content template → bd5cb038

+ Simplified tests in multiple commits. It's definitely more compact, not sure if more maintainable tho, I see pros and cons.

penyaskito’s picture

Assigned: penyaskito » wim leers
Status: Needs work » Needs review

IMHO this is ready for reviews now.

wim leers’s picture

Assigned: wim leers » Unassigned
Status: Needs review » Reviewed & tested by the community

After spending more hours than either of us really wanted pairing on this (and the blocking https://git.drupalcode.org/project/canvas/-/merge_requests/219 MR), we both think this is finally ready to go!

🌇

wim leers’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.