Skip to content

feat: multi-currency support and E2E tests for Kotlin sample#306

Merged
pengying merged 5 commits intomainfrom
feat/sample-multi-currency-e2e-tests
Apr 10, 2026
Merged

feat: multi-currency support and E2E tests for Kotlin sample#306
pengying merged 5 commits intomainfrom
feat/sample-multi-currency-e2e-tests

Conversation

@pengying
Copy link
Copy Markdown
Contributor

Summary

  • Fix SDK type mismatches so the Kotlin sample compiles and runs against SDK v1.1.0
  • Add multi-currency external account support (MXN, BRL, INR, GBP, PHP, EUR) with country selector dropdown
  • Add source currency dropdown (USD/USDC) on the quote step
  • Add "Start New Payment" button to restart the flow from the external account step
  • Extract shared optText/requireText to JsonUtils.kt, deduplicate BeneficiaryFields parsing
  • Add 7 Ktor server E2E tests hitting the Grid sandbox API
  • Add 8 Playwright browser E2E tests driving the full React UI

Test plan

  • cd samples/kotlin && ./gradlew test — 7 backend E2E tests pass
  • cd samples/frontend && npm run test:e2e — 8 Playwright browser tests pass (requires backend running)
  • Manual testing of all country destinations (IN, MX, BR, PH, GB, EU)
  • Manual testing of USD and USDC source currencies
  • Manual testing of "Start New Payment" reset flow

🤖 Generated with Claude Code

- Fix SDK type mismatches (Config field names, QuoteSourceOneOf, AccountType enums)
- Add multi-currency external account support (MXN, BRL, INR, GBP, PHP, EUR)
- Add country selector dropdown and source currency dropdown (USD/USDC)
- Add "Start New Payment" button to restart from external account step
- Extract shared optText/requireText to JsonUtils, deduplicate across route files
- Extract BeneficiaryFields to reduce copy-paste across beneficiary builders
- Add Ktor server E2E tests (7 tests hitting Grid sandbox API)
- Add Playwright browser E2E tests (8 tests driving the full React UI)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
grid-flow-builder Ready Ready Preview, Comment Apr 10, 2026 6:39pm

Request Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 27, 2026

Greptile Summary

This PR adds multi-currency support (MXN, BRL, INR, GBP, PHP, EUR) to the Kotlin sample with a country selector dropdown, a source currency (USD/USDC) selector, and a "Start New Payment" reset button. It also fixes SDK v1.1.0 type mismatches, deduplicates optText/requireText helpers, and adds 7 backend Ktor E2E tests plus 8 Playwright browser tests covering the full payout flow.

Confidence Score: 5/5

Safe to merge — both P2 findings are minor style/UX issues that do not block correctness.

All remaining findings are P2: the 'Start New Payment' button appearing one step early is a no-op (harmless), and the misleading Playwright comment doesn't affect test correctness. The SDK type fixes, multi-currency routing, and test coverage are solid.

samples/frontend/src/App.tsx (Start New Payment button condition) and samples/frontend/e2e/payout-flow.spec.ts (stale comment)

Important Files Changed

Filename Overview
samples/frontend/e2e/payout-flow.spec.ts Adds 8 Playwright browser E2E tests covering the full payout flow; comment on line 44 incorrectly states the default country is IN when it is actually MX.
samples/frontend/playwright.config.ts New Playwright config targeting port 8080 (Kotlin backend that serves pre-built React static files); previously flagged baseURL concern is a known trade-off documented in the spec file.
samples/frontend/src/App.tsx Adds selectedCountry state, restartFromExternalAccount function, and "Start New Payment" button; button condition activeStep >= 1 shows it one step too early (no-op at the External Account step).
samples/frontend/src/steps/CreateExternalAccount.tsx Adds COUNTRY_CONFIGS map with 6 currencies and a country selector dropdown; Math.random() in useEffect was already flagged in a prior review thread.
samples/frontend/src/steps/CreateQuote.tsx Adds source currency dropdown (USD/USDC) and reads destination currency from COUNTRY_CONFIGS; clean implementation.
samples/kotlin/src/main/kotlin/com/grid/sample/JsonUtils.kt Extracts optText/requireText extension functions to a shared location; behaviorally equivalent to the per-file implementations they replace.
samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt Adds PHP and EUR account types, fixes SDK type references (e.g. UsdAccountInfo vs UsdExternalAccountInfo), deduplicates beneficiary parsing via parseBeneficiaryFields; EUR SWIFT workaround is documented inline.
samples/kotlin/src/main/kotlin/com/grid/sample/routes/Quotes.kt Updates return type of buildQuoteSource to QuoteSourceOneOf and aligns factory method names to SDK v1.1.0; straightforward SDK migration.
samples/kotlin/src/test/kotlin/com/grid/sample/EndToEndTest.kt Adds 7 backend E2E tests covering customer creation, external accounts (MXN, INR), validation rejections, quote creation, and a full payout flow; env var names in the docstring match Config.kt.
samples/kotlin/src/main/kotlin/com/grid/sample/GridClientBuilder.kt Updates credential property references from gridClientId/gridClientSecret to apiTokenId/apiClientSecret to match renamed Config properties.
samples/kotlin/src/main/kotlin/com/grid/sample/routes/Customers.kt Switches from local requiredText to shared requireText from JsonUtils; clean deduplication.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[POST /api/customers/:id/external-accounts] --> B{accountInfo present?}
    B -- No --> ERR1[400 accountInfo is required]
    B -- Yes --> C{accountType present?}
    C -- No --> ERR2[400 accountType is required]
    C -- Yes --> D{accountType value}

    D -- USD_ACCOUNT --> USD[buildUsdBeneficiary\n→ UsdExternalAccountInfo]
    D -- INR_ACCOUNT --> INR[buildInrBeneficiary\n→ InrExternalAccountInfo]
    D -- BRL_ACCOUNT --> BRL[buildBrlBeneficiary\n→ BrlExternalAccountInfo]
    D -- MXN_ACCOUNT --> MXN[buildMxnBeneficiary\n→ MxnExternalAccountInfo]
    D -- GBP_ACCOUNT --> GBP[buildGbpBeneficiary\n→ GbpExternalAccountInfo]
    D -- PHP_ACCOUNT --> PHP[buildPhpBeneficiary\n→ PhpExternalAccountInfo]
    D -- EUR_ACCOUNT --> EUR[buildEurBeneficiary\n→ EurAccount + optional swiftBic workaround]
    D -- other --> ERR3[throw IllegalArgumentException]

    USD & INR & BRL & MXN & GBP & PHP & EUR --> EA[ExternalAccountCreate\nvia GridClient]
    EA --> RES[201 Created — external account JSON]
Loading

Fix All in Claude Code

Prompt To Fix All With AI
This is a comment left during a code review.
Path: samples/frontend/src/App.tsx
Line: 92-99

Comment:
**"Start New Payment" button is a no-op at the External Account step**

When `activeStep === 1` (the user is already on the Create External Account step), clicking this button calls `setActiveStep(1)` and clears `externalAccountId`/`quoteId`, both of which are already `null` — so nothing actually changes. The button is most useful after an external account has been created (i.e., from step 2 onwards).

```suggestion
          {activeStep >= 2 && (
            <button
              onClick={restartFromExternalAccount}
              className="mt-6 px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded text-sm font-medium text-gray-300"
            >
              Start New Payment
            </button>
          )}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: samples/frontend/e2e/payout-flow.spec.ts
Line: 44-46

Comment:
**Stale comment: default country is MX, not IN**

The comment says the default country is `IN`, but `App.tsx` initialises `selectedCountry` to `'MX'`. The actual test assertions are correct (they explicitly select countries before checking), but the comment is misleading.

```suggestion
    // Default country is MX; switch to each and verify the textarea updates.

    // Switch to India
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (5): Last reviewed commit: "Merge branch 'main' into feat/sample-mul..." | Re-trigger Greptile

Comment thread samples/frontend/playwright.config.ts
Comment thread samples/frontend/src/steps/CreateExternalAccount.tsx
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- India: name, UPI, countryOfResidence
- Mexico: name, CLABE, countryOfResidence
- Brazil: name, taxId, pixKeyType, pixKey, countryOfResidence
- Philippines: name, bankCode, accountNumber, countryOfResidence
- EU: name, IBAN, full address, countryOfResidence
- UK: name, sortCode, accountNumber, countryOfResidence

Removes extra fields (birthDate, email, phone, swiftCode) that are not
required per the spec. Makes swiftCode optional in the EUR backend handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The API field is countryOfResidence, not nationality. Updated frontend
configs, backend parser (with fallback to nationality), and E2E tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@pengying pengying merged commit 80ac181 into main Apr 10, 2026
8 checks passed
@pengying pengying deleted the feat/sample-multi-currency-e2e-tests branch April 10, 2026 19:11
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.

2 participants