Skip to content

Conversation

@simlegate
Copy link
Contributor

@simlegate simlegate commented Oct 10, 2025

Please see the document from Paypal https://developer.paypal.com/docs/api/orders/v2/#definition-amount_breakdown

The discount for all items within a given purchase_unit. discount.value can not be a negative number.

image

Summary by CodeRabbit

  • Bug Fixes

    • Corrected discount display in PayPal checkout to always show a non-negative amount.
    • Ensures zero is shown when no discount applies, preventing confusing negative values.
  • Tests

    • Added tests covering discount handling (positive from negative totals, zero, and nil cases).
    • Cleaned up a name truncation test to keep focus on expected behavior.

@coderabbitai
Copy link

coderabbitai bot commented Oct 10, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Changed PayPal order presenter to serialize a nil-safe, non-negative discount using (order.promo_total || 0).abs.to_s. Added tests covering negative promo_total (producing a positive discount), zero promo_total, and nil discount; cleaned an extraneous line in an existing name truncation test.

Changes

Cohort / File(s) Summary of modifications
Presenter Logic
app/presenters/spree_paypal_checkout/order_presenter.rb
Updated discount serialization from order.promo_total.to_s to `(order.promo_total
Specs
spec/presenters/spree_paypal_checkout/order_presenter_spec.rb
Added a discount context with tests for: negative promo_total yielding a positive discount string, zero promo_total yielding "0", and nil discount yielding "0". Removed an extraneous line from the 127-character name truncation test while preserving truncation assertions.

Sequence Diagram(s)

No sequence diagram necessary for this change.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I nibble through the Ruby night,
I flip the minus out of sight,
Nil turned zero, numbers bright,
Tests stand guard with soft moonlight,
A carrot-cheer for PayPal's flight 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title accurately reflects the primary change of enforcing a non-negative discount value for PayPal, directly summarizing the presenter and test updates without unnecessary detail.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 60001a0 and 61ee5f5.

📒 Files selected for processing (2)
  • app/presenters/spree_paypal_checkout/order_presenter.rb (1 hunks)
  • spec/presenters/spree_paypal_checkout/order_presenter_spec.rb (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • spec/presenters/spree_paypal_checkout/order_presenter_spec.rb
  • app/presenters/spree_paypal_checkout/order_presenter.rb
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

cursor[bot]

This comment was marked as outdated.

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)
spec/presenters/spree_paypal_checkout/order_presenter_spec.rb (1)

56-63: Good edge case coverage, but clarify the third test name.

The tests appropriately cover zero and default value scenarios. However, the third test (line 61) is named "should be zero when discount is nil" but doesn't actually test a nil promo_total—it tests the default value. Consider renaming for clarity:

-    it "should be zero when discount is nil" do
+    it "should be zero when promo_total has default value" do
       expect(subject.to_json['body'].purchase_units[0].amount.breakdown.discount.value).to eq("0.0")
     end

Note: The varying string formats ("100", "0", "0.0") reflect how Ruby's .to_s handles different numeric types and is expected behavior.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c81c65e and 60001a0.

📒 Files selected for processing (2)
  • app/presenters/spree_paypal_checkout/order_presenter.rb (1 hunks)
  • spec/presenters/spree_paypal_checkout/order_presenter_spec.rb (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
spec/presenters/spree_paypal_checkout/order_presenter_spec.rb (1)
app/presenters/spree_paypal_checkout/order_presenter.rb (1)
  • to_json (15-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (3)
spec/presenters/spree_paypal_checkout/order_presenter_spec.rb (2)

40-40: Minor test improvement, unrelated to discount fix.

The change from eq("") to be_nil.or eq("") makes the test more flexible when handling nil names. While this is a reasonable improvement, it appears unrelated to the discount fix that is the focus of this PR.


51-54: Excellent test coverage for the core fix.

This test correctly validates that negative promo_total values are converted to positive discount values, which is the primary requirement from PayPal's API documentation.

app/presenters/spree_paypal_checkout/order_presenter.rb (1)

39-39: Add explanatory comment and guard against nil promo_total

Replace

value: order.promo_total.abs.to_s

with

# PayPal requires discount.value to be non-negative
value: order.promo_total&.abs.to_s || '0'

Ensure order.promo_total can never be nil (or defaults to zero).


it "should be zero when discount is nil" do
expect(subject.to_json['body'].purchase_units[0].amount.breakdown.discount.value).to eq("0.0")
end
Copy link

Choose a reason for hiding this comment

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

Bug: Discount Test Inconsistency

The test for a nil discount expects "0.0", but the implementation produces "0" when order.promo_total is nil. This creates an inconsistency with the existing test for a zero discount, which correctly expects "0".

Fix in Cursor Fix in Web

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.

1 participant