Skip to content

Conversation

@mrbazzan
Copy link
Contributor

@mrbazzan mrbazzan commented Jul 20, 2025

Summary by Sourcery

Fix saving of per-row column settings by correcting entangled_fields metadata and form naming in grid forms, and add unit tests for device choice fields and grid container/row/column forms

Bug Fixes:

  • Use _meta instead of Meta to register extra config fields on GridRowForm and GridColumnForm
  • Rename generated grid row form type to "GridRowForm" for consistency
  • Persist extra_fields_column keys so column-per-row settings are saved correctly

Tests:

  • Add tests for DeviceChoiceField and OptionalDeviceChoiceField behavior
  • Add tests for GridContainerForm, GridRowForm, and GridColumnForm to verify config persistence and validation

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jul 20, 2025

Reviewer's Guide

This PR corrects the entangled_fields configuration in grid form definitions to ensure column-per-row settings are persisted and expands test coverage by adding and refining tests for DeviceChoiceField/OptionalDeviceChoiceField as well as comprehensive grid form behavior validations.

Class diagram for updated grid form definitions

classDiagram
    class GridRowBaseForm {
        +Meta
        +_meta
    }
    class GridRowForm {
    }
    GridRowForm --|> GridRowBaseForm
    GridRowBaseForm : entangled_fields["config"] += extra_fields_column.keys()

    class GridColumnBaseForm {
        +Meta
        +_meta
    }
    class GridColumnForm {
    }
    GridColumnForm --|> GridColumnBaseForm
    GridColumnBaseForm : entangled_fields["config"] += extra_fields_column.keys()
Loading

File-Level Changes

Change Details Files
Refactored entanglement of 'config' fields to use the correct metadata attribute
  • Replace GridRowBaseForm.Meta.entangled_fields with GridRowBaseForm._meta.entangled_fields
  • Relocate and deduplicate entangled_fields assignment for GridColumnBaseForm
djangocms_frontend/contrib/grid/forms.py
Enhanced test_fields imports to include device choice settings and fields
  • Import DEVICE_CHOICES constant
  • Add DeviceChoiceField and OptionalDeviceChoiceField to imports
tests/test_fields.py
Added tests for DeviceChoiceField and OptionalDeviceChoiceField
  • Verify valid and default behavior of OptionalDeviceChoiceField
  • Check required validation and error messages for DeviceChoiceField
tests/test_fields.py
Added comprehensive grid form tests
  • Test GridContainerForm for required config keys and container_type assignment
  • Test GridRowForm for column settings and dynamic config inclusion
  • Test GridColumnForm for offset, column width, and margin/padding device settings
tests/grid/test_forms.py

Assessment against linked issues

Issue Objective Addressed Explanation
#289 Ensure that the 'Columns per Row' (responsive settings) values in the Grid Row plugin are saved correctly when editing and saving the plugin.
#289 Ensure that the saved 'Columns per Row' values are correctly loaded and displayed when re-editing the Grid Row plugin (i.e., values are not empty after saving and reopening).
#289 Apply the proper CSS classes based on the saved 'Columns per Row' values in the Grid Row plugin.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @mrbazzan - I've reviewed your changes - here's some feedback:

  • The two test methods named test_grid_container_form collide—rename the second to something like test_grid_column_form so both actually run.
  • Rather than mutating _meta.entangled_fields in scattered spots, consider centralizing that in your form definitions to avoid potential inconsistencies down the line.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The two test methods named test_grid_container_form collide—rename the second to something like test_grid_column_form so both actually run.
- Rather than mutating _meta.entangled_fields in scattered spots, consider centralizing that in your form definitions to avoid potential inconsistencies down the line.

## Individual Comments

### Comment 1
<location> `tests/test_fields.py:37` </location>
<code_context>
             ],
         )
+
+    def test_optional_device_choice_field(self):
+        class Form(forms.Form):
+            odc = OptionalDeviceChoiceField()
</code_context>

<issue_to_address>
Missing test for invalid input in OptionalDeviceChoiceField.

Add a test to verify that OptionalDeviceChoiceField rejects values not present in DEVICE_CHOICES.
</issue_to_address>

### Comment 2
<location> `tests/test_fields.py:61` </location>
<code_context>
+        self.assertTrue(form.is_valid(), form.errors)
+        self.assertEqual(form.cleaned_data["dc"], ["xs"])
+
+        form_1 = Form2(data={})
+        self.assertFalse(form_1.is_valid())
+        self.assertFormError(form_1, "dc_not_required",
+                             ["Please select at least one device size"])
</code_context>

<issue_to_address>
Test for DeviceChoiceField with multiple valid and invalid values is missing.

Please add tests for DeviceChoiceField with multiple valid values and with a mix of valid and invalid values to better verify validation logic.
</issue_to_address>

### Comment 3
<location> `tests/grid/test_forms.py:10` </location>
<code_context>
+
+
+class GridFormTestCase(TestCase):
+    def test_grid_container_form(self):
+        form = GridContainerForm(data={
+            "container_type": "container",
</code_context>

<issue_to_address>
Duplicate test method name 'test_grid_container_form'.

Only the second method will run. Please rename one to reflect its purpose, such as 'test_grid_column_form'.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@codecov
Copy link

codecov bot commented Jul 20, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.01%. Comparing base (cd3923d) to head (f61eac1).
⚠️ Report is 28 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #291      +/-   ##
==========================================
+ Coverage   88.89%   89.01%   +0.11%     
==========================================
  Files         124      124              
  Lines        3385     3385              
  Branches      288      288              
==========================================
+ Hits         3009     3013       +4     
+ Misses        259      254       -5     
- Partials      117      118       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mrbazzan mrbazzan force-pushed the fix/grid_row branch 2 times, most recently from a85e288 to 3393f6b Compare July 20, 2025 12:18
Copy link
Member

@fsbraun fsbraun left a comment

Choose a reason for hiding this comment

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

Nice! Thank you, @mrbazzan !

@fsbraun
Copy link
Member

fsbraun commented Jul 20, 2025

@mrbazzan Let's get this released! 🚢

@fsbraun fsbraun merged commit 2cb0fb5 into django-cms:main Jul 20, 2025
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GridRowPlugin: Columns per Row are not saved

2 participants