Skip to content

[OSDEV-1778] Fix the validation for number_of_workers field in POST, PATCH production locations API#532

Merged
Innavin369 merged 13 commits intomainfrom
OSDEV-1778-fix-validation-for-number-of-workers
Feb 27, 2025
Merged

[OSDEV-1778] Fix the validation for number_of_workers field in POST, PATCH production locations API#532
Innavin369 merged 13 commits intomainfrom
OSDEV-1778-fix-validation-for-number-of-workers

Conversation

@Innavin369
Copy link
Contributor

@Innavin369 Innavin369 commented Feb 21, 2025

OSDEV-1778 Fix the validation for number_of_workers field in POST, PATCH production locations API.

  • min can be less or equal to max
  • min and max must be integer
  • fixed API spec in the PR

@Innavin369 Innavin369 self-assigned this Feb 21, 2025
@Innavin369 Innavin369 marked this pull request as ready for review February 25, 2025 11:11
@coderabbitai
Copy link

coderabbitai bot commented Feb 25, 2025

📝 Walkthrough

Walkthrough

The pull request introduces enhancements to the validation logic in the production locations API regarding the "number of workers" field. A new release notes entry documents that the minimum value must be less than or equal to the maximum. In the serializer, a new validate method has been added to check this relationship, raising a validation error if the condition is not met. Additionally, the ProductionLocationSchemaSerializer has been modified to remove previous validation logic, potentially allowing invalid data to be accepted.

Changes

File Change Summary
doc/release/RELEASE-NOTES.md Added a release note entry (OSDEV-1778) documenting the bug fix to enforce that the minimum number of workers is less than or equal to the maximum.
src/django/api/serializers/v1/number_of_workers_serializer.py Added validate method to check that minmax; updated to_internal_value method for validation; removed validate_object method.
src/django/api/serializers/v1/production_location_schema_serializer.py Updated number_of_workers field to remove custom validators and error messages, altering validation behavior.

Possibly related PRs

Suggested reviewers

  • roman-stolar
  • mazursasha1990
  • vladsha-dev
✨ Finishing Touches
  • 📝 Generate Docstrings

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
doc/release/RELEASE-NOTES.md (1)

79-79: Fix typo in release note entry.

There's a small typo in the release note - it says "PATH" instead of "PATCH" when referring to the production locations API.

-* [OSDEV-1778](https://opensupplyhub.atlassian.net/browse/OSDEV-1778) - Fixed the validation for number of workers field in POST, PATH production locations API. The min field must be less than or equal to the max field.
+* [OSDEV-1778](https://opensupplyhub.atlassian.net/browse/OSDEV-1778) - Fixed the validation for number of workers field in POST, PATCH production locations API. The min field must be less than or equal to the max field.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 842aa4e and bd07b20.

📒 Files selected for processing (2)
  • doc/release/RELEASE-NOTES.md (1 hunks)
  • src/django/api/serializers/v1/number_of_workers_serializer.py (1 hunks)
🔇 Additional comments (3)
src/django/api/serializers/v1/number_of_workers_serializer.py (3)

9-11: LGTM! Added improved validation error message for integer requirement.

The added error message provides better clarity to API users about the expected data type.


17-19: LGTM! Added improved validation error message for integer requirement.

The added error message provides better clarity to API users about the expected data type.


22-36: LGTM! Added validation to ensure min ≤ max.

This implementation correctly validates that the minimum value is less than or equal to the maximum value, addressing the issue described in OSDEV-1778. The validation only happens when both values are present, which is appropriately handled.

The error message is clear and descriptive, helping API consumers understand the validation rule.

@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:14 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:17 — with GitHub Actions Inactive
@barecheck
Copy link

barecheck bot commented Feb 25, 2025

React App | Jest test suite - Code coverage report

Total: 31.61%

Your code coverage diff: 0.00% ▴

✅ All code changes are covered

@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:21 — with GitHub Actions Inactive
@barecheck
Copy link

barecheck bot commented Feb 25, 2025

Dedupe Hub App | Unittest test suite - Code coverage report

Total: 56.14%

Your code coverage diff: 0.00% ▴

✅ All code changes are covered

@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:22 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 25, 2025 11:22 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
@Innavin369 Innavin369 temporarily deployed to Quality Environment February 26, 2025 10:50 — with GitHub Actions Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/django/api/serializers/v1/number_of_workers_serializer.py (1)

34-71: Consider simplifying validation approach.

While the custom validation works, it creates redundancy with Django REST Framework's built-in validation. The serializer already defines both fields as required IntegerFields with min_value constraints (lines 5-12).

Instead of completely reimplementing validation:

  1. Let DRF handle the type checking and required validation
  2. Keep only the min-max relationship validation in the validate method
-    def to_internal_value(self, data):
-        min = data.get('min')
-        max = data.get('max')
-        errors = []
-
-        if not min:
-            errors.append({
-                "field": "min",
-                "detail":
-                    "The min field is required!"
-            })
-
-        if not max:
-            errors.append({
-                "field": "max",
-                "detail":
-                    "The max field is required!"
-            })
-
-        if min and not isinstance(data.get('min'), int):
-            errors.append({
-                "field": "min",
-                "detail":
-                    "The min field must be an integer."
-            })
-
-        if max and not isinstance(data.get('max'), int):
-            errors.append({
-                "field": "max",
-                "detail":
-                    "The max field must be an integer."
-            })
-
-        if len(errors) > 0:
-            raise serializers.ValidationError({"field": {self.field_name},
-                                               "errors": errors})
-
-        return super().to_internal_value(data)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5653b2 and c4e5cc7.

📒 Files selected for processing (2)
  • doc/release/RELEASE-NOTES.md (1 hunks)
  • src/django/api/serializers/v1/number_of_workers_serializer.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • doc/release/RELEASE-NOTES.md
⏰ Context from checks skipped due to timeout of 90000ms (13)
  • GitHub Check: run-eslint-linter-and-prettier-formatter
  • GitHub Check: run-integration-test-code-quality
  • GitHub Check: run-flake8-linter
  • GitHub Check: run-dd-code-quality
  • GitHub Check: run-countries-code-quality
  • GitHub Check: run-contricleaner-code-quality
  • GitHub Check: get-base-branch-fe-cov
  • GitHub Check: get-base-branch-contricleaner-cov
  • GitHub Check: get-base-branch-dd-cov
  • GitHub Check: run-fe-code-quality
  • GitHub Check: get-base-branch-countries-cov
  • GitHub Check: run-django-code-quality
  • GitHub Check: get-base-branch-django-cov
🔇 Additional comments (3)
src/django/api/serializers/v1/number_of_workers_serializer.py (3)

14-28: Good addition of min/max relationship validation.

The added validate method properly checks that min is less than or equal to max when both values are present, which aligns with the PR objectives.


53-58: Integer validation may be too strict.

Using isinstance(data.get('min'), int) might reject valid integer values that are submitted as strings (common in HTTP APIs). Django REST Framework's IntegerField would handle this conversion automatically.


71-71: Consider error handling for super().to_internal_value.

After performing custom validation, calling super().to_internal_value(data) might raise additional validation errors with different formats. Consider handling these or documenting the expected behavior.

Copy link
Contributor

@vladsha-dev vladsha-dev left a comment

Choose a reason for hiding this comment

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

  1. Left some comments/questions.
  2. Passing an array instead of a object(dictionary) results in a 500 error. However, it should trigger a 422 error with a clear message.
Screenshot 2025-02-26 at 11 20 15

Copy link
Contributor

@vladsha-dev vladsha-dev left a comment

Choose a reason for hiding this comment

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

@Innavin369
Could you please also check that the SLC form works as expected after the changes you made?

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c4e5cc7 and 20bf8a2.

📒 Files selected for processing (3)
  • doc/release/RELEASE-NOTES.md (1 hunks)
  • src/django/api/serializers/v1/number_of_workers_serializer.py (1 hunks)
  • src/django/api/serializers/v1/production_location_schema_serializer.py (0 hunks)
💤 Files with no reviewable changes (1)
  • src/django/api/serializers/v1/production_location_schema_serializer.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • doc/release/RELEASE-NOTES.md
⏰ Context from checks skipped due to timeout of 90000ms (13)
  • GitHub Check: run-integration-test-code-quality
  • GitHub Check: run-flake8-linter
  • GitHub Check: run-fe-code-quality
  • GitHub Check: run-eslint-linter-and-prettier-formatter
  • GitHub Check: run-dd-code-quality
  • GitHub Check: run-contricleaner-code-quality
  • GitHub Check: run-countries-code-quality
  • GitHub Check: get-base-branch-fe-cov
  • GitHub Check: get-base-branch-countries-cov
  • GitHub Check: get-base-branch-contricleaner-cov
  • GitHub Check: get-base-branch-dd-cov
  • GitHub Check: get-base-branch-django-cov
  • GitHub Check: run-django-code-quality
🔇 Additional comments (3)
src/django/api/serializers/v1/number_of_workers_serializer.py (3)

14-28: LGTM: The validation logic for min and max relationship is correctly implemented.

The new validate method properly ensures that the minimum value must be less than or equal to the maximum value, which aligns with the PR objective.


30-37:

Details

❓ Verification inconclusive

Consider adding validation for negative numbers or zero in min/max fields.

The API should validate that min and max values are positive integers. While the field definitions on lines 5-12 specify min_value=1, the manual validation should align with these constraints.

I notice that your IntegerField definitions include min_value=1, but your validation logic doesn't explicitly check for this. It's worth verifying if Django REST framework's validation will handle this automatically or if additional validation should be added:


🏁 Script executed:

#!/bin/bash
# Check how validation is typically handled in other serializers
grep -r "min_value" --include="*.py" --include="*.md" src/django/ | grep -v '__pycache__' | head -20

Length of output: 2109


Ensure Consistent Positive Integer Validation for min/max Fields
While the serializer’s field definitions enforce min_value=1 at the top of the file (as confirmed by the grep results), the custom to_internal_value() method does not explicitly validate that min and max are positive. In other parts of the codebase, similar serializers rely on these built-in validations, so you might consider one of the following approaches:

  • Rely on DRF’s Field Validation:
    If you’re confident that the DRF field-level validations (i.e., min_value=1) will always be executed, you could leave the manual validation out of to_internal_value(). This helps avoid duplication and keeps the code consolidated.

  • Add Explicit Manual Checks:
    If there’s any risk of bypassing the standard validation (or if you prefer a clearer error message at this stage), add explicit checks before further processing. For example:

        if min is not None and min < 1:
            errors.append("The 'min' value must be a positive integer.")
        if max is not None and max < 1:
            errors.append("The 'max' value must be a positive integer.")

Please review and decide whether to rely solely on the field definitions or to introduce these additional manual checks to ensure consistency.


67-70:

Details

❓ Verification inconclusive

Ensure field_name attribute is properly defined.

The code uses self.field_name in the error structure. Make sure this attribute is defined somewhere in the class or inherited from a parent class, as it's not defined within the code shown.


🏁 Script executed:

#!/bin/bash
# Check if field_name is defined in the serializer base class or elsewhere
grep -r "field_name" --include="*.py" src/django/api/serializers/ | grep -v 'from\|import'

Length of output: 3092


Action: Verify the Definition of self.field_name

The code at lines 67–70 in src/django/api/serializers/v1/number_of_workers_serializer.py raises a ValidationError using self.field_name, but there’s no visible definition of this attribute in the snippet. Similar serializers (e.g. in string_or_list_field.py) also use self.field_name, suggesting that it may be initialized in a common base class or elsewhere. Please confirm that:

  • self.field_name is either initialized in this serializer’s constructor or inherited from a parent class.
  • The attribute’s definition is consistent across serializers to prevent potential runtime issues.

roman-stolar
roman-stolar previously approved these changes Feb 26, 2025
Copy link
Contributor

@roman-stolar roman-stolar left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@vladsha-dev vladsha-dev left a comment

Choose a reason for hiding this comment

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

  1. Left comment.
  2. Please check the title of the PR. I see PATH there instead of PATCH

@sonarqubecloud
Copy link

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/django/api/serializers/v1/number_of_workers_serializer.py (2)

5-10: Consider adding required=True to the field definitions for clarity.

The validation logic in to_internal_value checks if these fields are present, effectively treating them as required. For better code clarity and self-documentation, it would be good to add the required=True parameter to both field definitions, which aligns with the comment from @vladsha-dev in the previous review.

-    min = serializers.IntegerField(
-        min_value=1,
-    )
-    max = serializers.IntegerField(
-        min_value=1,
-    )
+    min = serializers.IntegerField(
+        min_value=1,
+        required=True,
+    )
+    max = serializers.IntegerField(
+        min_value=1,
+        required=True,
+    )

30-31: Fix spacing in error message for better consistency.

There's an extra space in the error message between "a" and "dictionary".

-              "Invalid data. Expected a dictionary(object).")
+              "Invalid data. Expected a dictionary (object).")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4a28a4d and 35b9ce7.

📒 Files selected for processing (1)
  • src/django/api/serializers/v1/number_of_workers_serializer.py (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (13)
  • GitHub Check: run-integration-test-code-quality
  • GitHub Check: run-flake8-linter
  • GitHub Check: run-fe-code-quality
  • GitHub Check: run-django-code-quality
  • GitHub Check: run-eslint-linter-and-prettier-formatter
  • GitHub Check: run-dd-code-quality
  • GitHub Check: run-countries-code-quality
  • GitHub Check: run-contricleaner-code-quality
  • GitHub Check: get-base-branch-fe-cov
  • GitHub Check: get-base-branch-contricleaner-cov
  • GitHub Check: get-base-branch-dd-cov
  • GitHub Check: get-base-branch-django-cov
  • GitHub Check: get-base-branch-countries-cov
🔇 Additional comments (3)
src/django/api/serializers/v1/number_of_workers_serializer.py (3)

12-26: LGTM! The validation logic is clear and matches the requirements.

This implementation correctly validates that the minimum value is less than or equal to the maximum value, which aligns with the PR objective. The error message is clear and helpful for API users.


28-69: The validation implementation looks solid with proper error handling.

The to_internal_value method now correctly validates input data format, presence of required fields, and type checking with appropriate error messages. The changes properly handle edge cases like when values are zero, as addressed in the previous review comments.


66-67:

Details

❓ Verification inconclusive

Verify that self.field_name will always be available in this context.

A previous review comment mentioned an issue with self.field_name. Make sure this attribute is always available when this serializer is used. If this serializer is used directly without being nested in another serializer that sets the field name, this could potentially cause an error.


🏁 Script executed:

#!/bin/bash
# Check how NumberOfWorkersSerializer is used in the codebase
echo "Checking uses of NumberOfWorkersSerializer:"
grep -r "NumberOfWorkersSerializer" --include="*.py" src/django/

echo -e "\nChecking if field_name is set somewhere in the serializer hierarchy:"
grep -r "field_name" --include="*.py" src/django/api/serializers/

Length of output: 3846


Double-check that self.field_name is reliably set on NumberOfWorkersSerializer instances.

  • Our investigation shows that this serializer is used as a nested serializer (e.g., in production_location_schema_serializer.py), which likely binds field_name automatically. However, there’s no explicit assignment or default value for self.field_name within NumberOfWorkersSerializer itself.
  • Please verify that all usages of this serializer rely on the parent serializer to call bind() (or otherwise set this attribute) so that a direct (standalone) usage won’t result in an AttributeError.
  • If there’s any chance the serializer could be instantiated without being nested, consider adding an explicit initialization or fallback to ensure self.field_name is always available.

Copy link
Contributor

@vladsha-dev vladsha-dev left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@mazursasha1990 mazursasha1990 left a comment

Choose a reason for hiding this comment

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

LGTM

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.

4 participants