Prevent syncing from incomplete source node#5761
Prevent syncing from incomplete source node#5761bjester wants to merge 1 commit intolearningequality:hotfixesfrom
Conversation
rtibblesbot
left a comment
There was a problem hiding this comment.
Clean, focused fix that prevents syncing from an incomplete source node, directly addressing the P0 bug.
CI passing. PR targets hotfixes (not the default unstable branch), which is appropriate for a P0 regression fix. No new user-facing strings added.
- suggestion: The warning log could be more informative (see inline comment)
- suggestion: Test could add an explicit
refresh_from_dbto strengthen the assertion (see inline comment) - praise: Good test structure and necessary fix to
_create_video_nodeto ensure the completeness guard works correctly across all existing tests
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Reviewed the pull request diff checking for:
- Correctness: bugs, edge cases, undocumented behavior, resource leaks, hardcoded values
- Design: unnecessary complexity, naming, readability, comment accuracy, redundant state
- Architecture: duplicated concerns, minimal interfaces, composition over inheritance
- Testing: behavior-based assertions, mocks only at hard boundaries, accurate coverage
- Completeness: missing dependencies, unupdated usages, i18n, accessibility, security
- Principles: DRY (same reason to change), SRP, Rule of Three (no premature abstraction)
- Checked CI status and linked issue acceptance criteria
- For UI changes: inspected screenshots for layout, visual completeness, and consistency
| ): | ||
| original_node = node.get_original_node() | ||
| if not original_node.complete: | ||
| logging.warning(f"Refusing to sync from incomplete node: {node.pk}") |
There was a problem hiding this comment.
suggestion: The warning logs node.pk (the cloned node's PK), but the reason for refusal is the original node being incomplete. Consider logging original_node.pk (or both) so it's easier to track down which source node is the problem:
logging.warning(f"Refusing to sync node {node.pk} from incomplete source node: {original_node.pk}")| sync_assessment_items=True, | ||
| ) | ||
|
|
||
| self.assertIsNotNone(cloned_video.license_id) |
There was a problem hiding this comment.
suggestion: Since sync_node operates on the in-memory object, these assertions confirm the in-memory state wasn't mutated — which is correct. For extra confidence that nothing was persisted either, you could add cloned_video.refresh_from_db() before the assertions. Minor point though — the current assertions are sufficient for the guard's purpose.
| video_node.copyright_holder = "LE" | ||
| # ensure the node is complete according to our logic | ||
| video_node.mark_complete() | ||
| self.assertTrue(video_node.complete) |
There was a problem hiding this comment.
praise: Good call making _create_video_node produce complete nodes by default. This is necessary for the new complete guard in sync_node and ensures all existing sync tests exercise the intended code path rather than silently hitting the early return.
Summary
Adds check to our
sync_nodelogic, which synchronizes metadata and content of imported nodes with their sources, to ensure the source is complete. Otherwise, it logs a warning.References
fixes #5683
related: #5760
Reviewer guidance
Follow the reproduce steps in the issue
AI usage
None