fix(billing): add missing ThreeDSecurePopup to PaymentPopup#3028
fix(billing): add missing ThreeDSecurePopup to PaymentPopup#3028
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughPaymentPopup now integrates a 3D Secure flow: it renders a ThreeDSecurePopup when threeDSecure.threeDSData exists, hides the main popup while 3DS is open, wires 3DS success/error handlers, and updates tests/mocks to cover the new UI states. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant Popup as PaymentPopup
participant Hook as use3DSecure
participant ThreeDS as ThreeDSecurePopup
User->>Popup: open payment popup
Popup->>Hook: start or query 3DS state
Hook-->>Popup: { isOpen, threeDSData (clientSecret...), handle3DSSuccess, handle3DSError }
alt threeDSecure is open with data
Popup->>Popup: set main popup open = open && !isOpen
Popup->>ThreeDS: render with clientSecret, paymentIntentId, paymentMethodId, handlers
ThreeDS->>Hook: call onSuccess()/onError()
Hook-->>Popup: invoke handle3DSSuccess / handle3DSError
else not open
Popup->>User: show main payment UI
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3028 +/- ##
==========================================
- Coverage 59.69% 58.90% -0.80%
==========================================
Files 1032 994 -38
Lines 24231 23337 -894
Branches 6009 5876 -133
==========================================
- Hits 14465 13746 -719
+ Misses 8518 8355 -163
+ Partials 1248 1236 -12
*This pull request uses carry forward flags. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx`:
- Around line 616-621: The test "does not render ThreeDSecurePopup when 3DS data
is null" currently passes threeDSecureIsOpen: false which allows the popup to be
absent for the wrong reason; update the setup call in that spec to pass
threeDSecureIsOpen: true while keeping threeDSData: null so the test isolates
the null-data branch and ensures ThreeDSecurePopup is not rendered when
threeDSData is null (look for the it(...) block and the setup({ open:,
threeDSecureIsOpen:, threeDSData: }) invocation).
- Around line 120-123: The MockThreeDSecurePopup component currently types its
props as any; replace that with an explicit props shape (e.g., an interface or
type) that declares isOpen: boolean and clientSecret: string and use it for the
component signature (MockThreeDSecurePopup) so the TSX test file no longer uses
any for props and correctly types the mock's inputs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3361572d-e6e9-4b18-bfdf-ada5f02c7d97
📒 Files selected for processing (2)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
The ThreeDSecurePopup component was not carried over when the /payment page was removed in favor of /billing. The use3DSecure hook was wired up but the popup never rendered, causing silent payment failures for cards requiring 3D Secure verification. Fixes CON-162
8f1a426 to
a1cac9a
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (2)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx (2)
616-624:⚠️ Potential issue | 🟡 MinorIsolate the null-data branch in the negative render test.
Line 619 sets
threeDSecureIsOpen: false, so the popup can be absent even if data exists. Set it totrueso this test specifically validates thethreeDSData: nullpath.Suggested fix
it("does not render ThreeDSecurePopup when 3DS data is null", () => { setup({ open: true, - threeDSecureIsOpen: false, + threeDSecureIsOpen: true, threeDSData: null }); expect(screen.queryByTestId("three-d-secure-popup")).not.toBeInTheDocument(); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx` around lines 616 - 624, The test "does not render ThreeDSecurePopup when 3DS data is null" currently sets threeDSecureIsOpen: false which lets the popup be absent for the wrong reason; update the call to setup in PaymentPopup.spec.tsx so threeDSecureIsOpen is true while threeDSData is null (i.e., call setup({ open: true, threeDSecureIsOpen: true, threeDSData: null })) to isolate and assert the null-data branch for the ThreeDSecurePopup render behavior.
120-123:⚠️ Potential issue | 🟠 MajorReplace
anyprops onMockThreeDSecurePopupwith explicit types.Line 120 still uses
anyfor props in a TSX file; please typeisOpenandclientSecretexplicitly.Suggested fix
+type MockThreeDSecurePopupProps = { + isOpen: boolean; + clientSecret: string; +}; + -const MockThreeDSecurePopup = ({ isOpen, clientSecret }: any) => { +const MockThreeDSecurePopup = ({ isOpen, clientSecret }: MockThreeDSecurePopupProps) => { if (!isOpen) return null; return <div data-testid="three-d-secure-popup" data-client-secret={clientSecret} />; };As per coding guidelines:
**/*.{ts,tsx,js}: Never use typeanyor cast to typeany. Always define the proper TypeScript types.#!/bin/bash # Verify explicit any usage remains in this spec file rg -nP --type=tsx '\b:\s*any\b|\bas\s+any\b' apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx` around lines 120 - 123, MockThreeDSecurePopup currently types its props as any; replace that with explicit types by defining the props shape (e.g., interface or inline type) and using it on the component: type the isOpen prop as boolean and clientSecret as string | undefined (or string | null if tests pass null), then update the function signature for MockThreeDSecurePopup to use that type instead of any (e.g., MockThreeDSecurePopup = ({ isOpen, clientSecret }: { isOpen: boolean; clientSecret?: string }) => ...). Ensure the typed names match the existing identifiers so tests using data-testid="three-d-secure-popup" and data-client-secret continue to work.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In
`@apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx`:
- Around line 616-624: The test "does not render ThreeDSecurePopup when 3DS data
is null" currently sets threeDSecureIsOpen: false which lets the popup be absent
for the wrong reason; update the call to setup in PaymentPopup.spec.tsx so
threeDSecureIsOpen is true while threeDSData is null (i.e., call setup({ open:
true, threeDSecureIsOpen: true, threeDSData: null })) to isolate and assert the
null-data branch for the ThreeDSecurePopup render behavior.
- Around line 120-123: MockThreeDSecurePopup currently types its props as any;
replace that with explicit types by defining the props shape (e.g., interface or
inline type) and using it on the component: type the isOpen prop as boolean and
clientSecret as string | undefined (or string | null if tests pass null), then
update the function signature for MockThreeDSecurePopup to use that type instead
of any (e.g., MockThreeDSecurePopup = ({ isOpen, clientSecret }: { isOpen:
boolean; clientSecret?: string }) => ...). Ensure the typed names match the
existing identifiers so tests using data-testid="three-d-secure-popup" and
data-client-secret continue to work.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bc02fd60-f9fa-4078-a3ba-f6e3cf450727
📒 Files selected for processing (2)
apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
- Type MockThreeDSecurePopup props explicitly instead of `any` - Move MockThreeDSecurePopup to bottom of file as non-essential detail - Set threeDSecureIsOpen: true in null-data test to isolate the correct branch
Replace automatic_payment_methods with payment_method_types: ["card", "link"] to match createSetupIntent and createTestCharge. The automatic_payment_methods option with allow_redirects: "never" rejected link-type payment methods.
Replace confirmCardPayment with confirmPayment in ThreeDSecureModal so both card and link payment methods can complete 3DS authentication. The card-specific Stripe.js method rejected link-type PMs with "does not match the expected type card". Also restore payment_method_types: ["card", "link"] in createPaymentIntent to match createSetupIntent and createTestCharge.
Why
Fixes CON-162
When the
/paymentpage was removed in favor of/billing(#2846), theThreeDSecurePopupcomponent was not carried over to the newPaymentPopup. Theuse3DSecurehook was wired up andstart3DSecure()is called correctly, but the popup that performs the Stripe 3D Secure authentication never rendered — causing silent payment failures for cards requiring 3DS verification (e.g., certain EU cards).What
ThreeDSecurePopupinPaymentPopupcomponentDEPENDENCIESfor testabilityuse3DSecuremock in tests to return the full hook interfaceSummary by CodeRabbit
New Features
Behavioral Change
Tests