Skip to content

Improve validation of openedx_content to prevent creation of corrupt states#521

Merged
bradenmacdonald merged 7 commits intomainfrom
braden/corrupt-state-issues
Apr 29, 2026
Merged

Improve validation of openedx_content to prevent creation of corrupt states#521
bradenmacdonald merged 7 commits intomainfrom
braden/corrupt-state-issues

Conversation

@bradenmacdonald
Copy link
Copy Markdown
Contributor

@bradenmacdonald bradenmacdonald commented Mar 30, 2026

This PR implements tests for four of the issues identified in #463 .

  1. set_draft_version() should reject a PublishableEntityVersion that belongs to a different PublishableEntity.
  2. publish_from_drafts() should reject drafts that don't belong to the specified LearningPackage.
  3. create_publishable_entity_version() should reject dependencies that are from a different LearningPackage.
  4. publish_all_drafts() and publish_from_drafts() should not be callable from within a bulk_draft_changes_for() context.

Another issue is in a separate PR for simplicity: #569

Two issues are unaddressed as they are API design choices: create_publishable_entity_version() and create_publishable_entity() can both create either a useless or an invalid state if they are used on their own without corresponding [Component/Container/etc.] versions.

Platform: no corresponding changes are required in openedx-platform as far as I can tell.

@openedx-webhooks openedx-webhooks added open-source-contribution PR author is not from Axim or 2U core contributor PR author is a Core Contributor (who may or may not have write access to this repo). labels Mar 30, 2026
@openedx-webhooks
Copy link
Copy Markdown

openedx-webhooks commented Mar 30, 2026

Thanks for the pull request, @bradenmacdonald!

This repository is currently maintained by @axim-engineering.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

Details
Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@github-project-automation github-project-automation Bot moved this to Needs Triage in Contributions Mar 30, 2026
@bradenmacdonald bradenmacdonald force-pushed the braden/corrupt-state-issues branch from 5c69fc1 to dda0024 Compare March 30, 2026 21:07
@mphilbrick211 mphilbrick211 moved this from Needs Triage to Waiting on Author in Contributions Apr 1, 2026
@bradenmacdonald bradenmacdonald force-pushed the braden/corrupt-state-issues branch 3 times, most recently from 34a6794 to 03237af Compare April 28, 2026 17:48
@bradenmacdonald bradenmacdonald force-pushed the braden/corrupt-state-issues branch from 03237af to c689d0a Compare April 28, 2026 21:30
@bradenmacdonald bradenmacdonald requested a review from ormsbee April 28, 2026 21:31
@bradenmacdonald bradenmacdonald marked this pull request as ready for review April 28, 2026 21:31
Comment on lines -418 to -422
def test_reset_drafts_to_published_bulk(self) -> None:
"""bulk_draft_changes_for creates only one DraftChangeLog."""
with publishing_api.bulk_draft_changes_for(self.learning_package_1.id):
self.test_reset_drafts_to_published()
assert DraftChangeLog.objects.count() == 1
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since it's hard to tell from the diff what's going on here:

This test_reset_drafts_to_published_bulk just called test_reset_drafts_to_published() inside bulk_draft_changes_for but that inner test does some setup, a publish, more setup, then a revert, so this was causing an error - we don't want to allow publishes inside bulk_draft_changes_for.

The refactored test is almost exactly the same, but is parametrized and when bulk=True it wraps the pre-publish setup in a bulk transaction, and the post-publish setup+revert in a second bulk transaction.

I think this is an even better test now because we can assert that the net effect of the second bulk transaction is zero, as it reverts to the published version.

My local git client shows the diff more cleanly than GitHub:
Image

@bradenmacdonald bradenmacdonald force-pushed the braden/corrupt-state-issues branch from c689d0a to 1abbf1e Compare April 28, 2026 21:40
Copy link
Copy Markdown
Contributor

@ormsbee ormsbee left a comment

Choose a reason for hiding this comment

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

Minor request on more detail in the errors being raised.

Comment thread src/openedx_content/applets/publishing/api.py Outdated
Comment thread src/openedx_content/applets/publishing/api.py Outdated

from django.contrib.auth import get_user_model
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ObjectDoesNotExist, ValidationError
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[Comment]: I've generally used ValueError instead of ValidationError for invalid arguments, though I realize that doesn't make sense for things like checking that you're not in a bulk change context before publishing. Should I switch over, do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For these errors that are more developer-facing (you coded something wrong, not the user gave invalid input), I honestly don't think it makes much difference. I'm on the fence and happy to change to ValueError too if you'd like.

The python docs say

ValueError: Raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception

So I guess it depends if you consider ValidationError to be more precise. We could also define a custom exception that's even more specific, but I don't think it's worth it if we expect these to be pretty rare.

@bradenmacdonald
Copy link
Copy Markdown
Contributor Author

@ormsbee I added in that extra logging you requested.

@bradenmacdonald bradenmacdonald merged commit c3d876d into main Apr 29, 2026
6 checks passed
@bradenmacdonald bradenmacdonald deleted the braden/corrupt-state-issues branch April 29, 2026 16:57
@github-project-automation github-project-automation Bot moved this from Waiting on Author to Done in Contributions Apr 29, 2026
@ormsbee
Copy link
Copy Markdown
Contributor

ormsbee commented Apr 30, 2026

@bradenmacdonald, @kdmccormick: Just a heads up that something here is causing test failures in the modulestore migrator code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core contributor PR author is a Core Contributor (who may or may not have write access to this repo). open-source-contribution PR author is not from Axim or 2U

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants