Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: issue with default field values that can override payload field values #597

Closed

Conversation

Grumpfy
Copy link

@Grumpfy Grumpfy commented Oct 3, 2024

Summary by CodeRabbit

  • New Features

    • Improved handling of default values for input fields, ensuring valid inputs are preserved.
    • Enhanced middleware functionality for cookie handling and request processing.
  • Bug Fixes

    • Restored input values that were incorrectly overridden by default values.
  • Tests

    • Expanded test coverage for middleware, request parameters, and error handling, ensuring robust validation and response management.

Copy link

coderabbitai bot commented Oct 3, 2024

Walkthrough

The pull request introduces significant changes to the huma package, particularly in the Register function, enhancing how default values are managed for input fields. It prevents valid zero values from being overridden by defaults and includes a mechanism to restore input values if they were incorrectly overridden. Additionally, the testing suite for huma_test.go has been expanded with new middleware tests, improved request parameter validation, and enhanced error handling to ensure comprehensive coverage of the Huma API framework.

Changes

File Change Summary
huma.go Modified Register function to improve default value handling and restore input values. Updated method signature.
huma_test.go Added middleware tests for cookie handling, expanded request parameter validation, refined request body handling, and enhanced error handling. New methods added for testing and benchmarking.

Possibly related PRs

  • fix(schema): default value not work #531: The changes in this PR also focus on improving the handling of default values, specifically in the SchemaFromField function, which aligns with the enhancements made to the Register function in the main PR regarding default value logic.

Suggested reviewers

  • danielgtaylor

Poem

In the garden of code, where bunnies hop,
Default values bloom, and never stop.
With tests that leap high, and cookies that cheer,
Our Huma API’s stronger, let’s give a big cheer! 🐰✨
For every input, valid and true,
We’ve crafted a world, just for you!


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between cd3a5d5 and d332422.

📒 Files selected for processing (2)
  • huma.go (1 hunks)
  • huma_test.go (1 hunks)
🔇 Additional comments (3)
huma.go (1)

1296-1311: Approve the fix for default value override issue.

The implemented solution addresses the problem of default field values potentially overriding valid payload field values. It does this by:

  1. Only applying default values to zero-valued fields.
  2. Re-unmarshalling the input if any defaults were applied, ensuring original input values are preserved.

This approach effectively solves the issue described in the PR title.

Consider optimizing the unmarshalling process.

While the current implementation works, it may have a performance impact due to potentially unmarshalling the input twice.

Consider using a more targeted approach to restore only the overridden fields, rather than unmarshalling the entire input again. This could be achieved by keeping track of which fields were overridden and only restoring those specific fields.

Add a comment explaining the default value logic.

The logic for handling default values and restoring overridden input is complex and crucial for the correct functioning of the library.

Consider adding a comment explaining this logic, its purpose, and potential implications. This will help future maintainers understand the reasoning behind this implementation.

Verify edge cases for default value handling.

While the current implementation solves the main issue, there might be edge cases that need to be considered.

Please verify the behavior in the following scenarios:

  1. When a field in the input is explicitly set to the zero value of its type.
  2. When a field has a custom UnmarshalJSON method that might interfere with the default value logic.
  3. When dealing with nested structs or slices of structs with default values.

Run the following script to search for potential edge cases in the test files:

huma_test.go (2)

630-634: LGTM: Test case updates for default values

The changes to the test case for request-body-defaults look good. They correctly verify the behavior of default values in the request body, particularly for the Items array.

However, as per a previous review comment, we can improve the readability of the test by using assert.Len for checking the length of slices. Let's apply this suggestion:

-	assert.Len(t, input.Body.Items, 2)
+	assert.Len(t, input.Body.Items, 2)
 	assert.Equal(t, 1, input.Body.Items[0].ID)
 	assert.True(t, input.Body.Items[0].Verified)
 	assert.Equal(t, 1, input.Body.Items[1].ID)
 	assert.False(t, input.Body.Items[1].Verified)

This change makes the length check more expressive and provides better error messages on failure.


640-640: LGTM: Updated request body in test case

The change to the request body in the test case is appropriate. It now explicitly sets the verified field to false for the second item, which aligns with the updated assertions in the test case.

This modification helps to test both the default value (first item) and an explicitly set value (second item) for the verified field, improving the test coverage.


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 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: 1

🧹 Outside diff range and nitpick comments (1)
huma.go (1)

1297-1297: Correct the misspelling of 'overridden'

The variable name atLeastOneFieldIsOverriden and related comments contain a misspelling of the word 'overridden'. It should be spelled with double 'd'.

Apply the following diffs to fix the misspellings:

Update the variable declaration and assignment:

-    							atLeastOneFieldIsOverriden := false
+    							atLeastOneFieldIsOverridden := false
-    									atLeastOneFieldIsOverriden = true
+    									atLeastOneFieldIsOverridden = true

Correct the comments:

-    									//     - THEN the input required field value is overriden with a different value
+    									//     - THEN the input required field value is overridden with a different value
-    							// Restore wrongly overriden input values if any
+    							// Restore wrongly overridden input values if any

Also applies to: 1303-1303, 1305-1305, 1308-1308

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6e119e8 and cd3a5d5.

📒 Files selected for processing (2)
  • huma.go (1 hunks)
  • huma_test.go (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Build & Test (1.22)
huma.go

[failure] 1303-1303:
overriden is a misspelling of overridden (misspell)


[failure] 1308-1308:
overriden is a misspelling of overridden (misspell)

huma_test.go

[failure] 630-630:
len: use assert.Len (testifylint)

🔇 Additional comments (3)
huma.go (1)

1296-1311: Logic for handling default values is correct

The implemented logic correctly prevents overriding valid input values with default values when the input explicitly specifies a zero value. The restoration mechanism ensures that any input values that were incorrectly overridden are properly restored.

🧰 Tools
🪛 GitHub Check: Build & Test (1.22)

[failure] 1303-1303:
overriden is a misspelling of overridden (misspell)


[failure] 1308-1308:
overriden is a misspelling of overridden (misspell)

huma_test.go (2)

633-634: LGTM!

The assertions correctly verify the properties of the second item in the Items slice.


640-640: LGTM!

The test payload is appropriately constructed with the expected items data.

huma_test.go Outdated
@@ -627,14 +627,17 @@
assert.Equal(t, 5, input.Body.Count)
assert.Equal(t, []string{"foo", "bar"}, input.Body.Tags)
assert.Equal(t, []int{1, 2, 3}, input.Body.Numbers)
assert.Equal(t, len(input.Body.Items), 2)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use assert.Len for slice length assertion

On line 630, it's more expressive to use assert.Len when checking the length of a slice. This provides better error messages on failure.

Apply this diff:

-	assert.Equal(t, len(input.Body.Items), 2)
+	assert.Len(t, input.Body.Items, 2)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assert.Equal(t, len(input.Body.Items), 2)
assert.Len(t, input.Body.Items, 2)
🧰 Tools
🪛 GitHub Check: Build & Test (1.22)

[failure] 630-630:
len: use assert.Len (testifylint)

Copy link

codecov bot commented Oct 3, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 92.80%. Comparing base (6e119e8) to head (d332422).
Report is 48 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #597   +/-   ##
=======================================
  Coverage   92.80%   92.80%           
=======================================
  Files          22       22           
  Lines        3903     3907    +4     
=======================================
+ Hits         3622     3626    +4     
  Misses        236      236           
  Partials       45       45           

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

}
})
// Restore wrongly overridden input values if any
if atLeastOneFieldIsOverridden {
_ = api.Unmarshal(ctx.Header("Content-Type"), body, f.Addr().Interface())
Copy link
Owner

Choose a reason for hiding this comment

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

This seems kind of inefficient and I'm wondering if there are any edge cases where it would inadvertently overwrite something... 🤔

Copy link

Choose a reason for hiding this comment

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

Here I propose a different way to fix this.

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.

3 participants