Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,21 @@ module.exports = [
message:
"Don't pass { history: 'push' } to nuqs useQueryState(s) — a history entry per URL write breaks the back button (useSafeBack steps through same-screen states instead of leaving). Use the default 'replace'; the URL stays shareable. If a flow genuinely needs push-per-step, add a scoped file exemption with a comment (see useNativePlugins).",
},
{
// Toast copy must come from next-intl. `react/jsx-no-literals` below
// only inspects JSX children, so toasts fired from hooks and contexts
// (authContext, useLogin, useSendMoney, QRScanner) shipped English to
// every locale unnoticed.
//
// Deliberately NOT extended to `throw new Error('…')`: those messages
// are developer/Sentry breadcrumbs that the friendly-error mapper
// collapses to `errors.genericSupport` before any user sees them, so
// translating them would only fragment Sentry issue grouping.
selector:
"CallExpression[callee.object.name='toast'][callee.property.name=/^(error|success|info|warning|loading)$/] > :matches(Literal, TemplateLiteral):first-child",
message:
"Don't pass a string literal to toast.* — copy must come from next-intl. Import the right namespace with useTranslations and pass t('…'). If the value genuinely isn't copy (an id, a URL), assign it to a named const first.",
},
],
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars, react/display-name */
import React from 'react'
import { render, screen, fireEvent, waitFor, act } from '@testing-library/react'
import { IntlWrapper } from '@/test-utils/intl'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'

// ---------- module-level mocks (must be before imports that depend on them) ----------
Expand Down Expand Up @@ -897,9 +897,9 @@ function createQueryClient() {
function renderWithProviders(component: React.ReactElement) {
const queryClient = createQueryClient()
return render(
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
<IntlWrapper>
<QueryClientProvider client={queryClient}>{component}</QueryClientProvider>
</NextIntlClientProvider>
</IntlWrapper>
)
}

Expand Down
7 changes: 3 additions & 4 deletions src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
import React from 'react'
import posthog from 'posthog-js'
import { render, screen, fireEvent, waitFor, act } from '@testing-library/react'
import { IntlWrapper } from '@/test-utils/intl'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'
import { parseUnits } from 'viem'
import type { RailCapability } from '@/types/capabilities'

Expand Down Expand Up @@ -536,13 +535,13 @@ function renderQrPay(params: Record<string, string> = {}) {
}

return render(
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
<IntlWrapper>
<QueryClientProvider client={queryClient}>
<LoadingProvider>
<QRPayPage />
</LoadingProvider>
</QueryClientProvider>
</NextIntlClientProvider>
</IntlWrapper>
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/app/(mobile-ui)/receipt/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default function NativeReceiptPage() {
return (
<PageContainer className="flex min-h-[100dvh] flex-col items-center justify-center p-6">
<div className="md:hidden">
<NavHeader title="Receipt" />
<NavHeader titleKey="receipt" />
</div>
<div className="flex flex-1 flex-col items-center justify-center">
{isLoading || !entry ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
*/
import React from 'react'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { IntlWrapper } from '@/test-utils/intl'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'
import { parseUnits } from 'viem'

// ---------- module-level mocks (must be before imports that depend on them) ----------
Expand Down Expand Up @@ -226,11 +225,11 @@ function renderWithdraw(params: Record<string, string> = {}) {
setSearchParams(params)
const queryClient = createQueryClient()
return render(
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
<IntlWrapper>
<QueryClientProvider client={queryClient}>
<WithdrawPage />
</QueryClientProvider>
</NextIntlClientProvider>
</IntlWrapper>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
*/
import React from 'react'
import { render as rtlRender, screen, fireEvent, waitFor } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import enMessages from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'

// ---------- module-level mocks ----------

Expand Down Expand Up @@ -252,12 +251,6 @@ jest.mock('@/features/payments/shared/hooks/usePaymentRecorder', () => ({

import WithdrawCryptoPage from '../page'

const IntlWrapper = ({ children }: { children: React.ReactNode }) => (
<NextIntlClientProvider locale="en" messages={enMessages} timeZone="UTC">
{children}
</NextIntlClientProvider>
)

const render = (ui: React.ReactElement, options?: Omit<Parameters<typeof rtlRender>[1], 'wrapper'>) =>
rtlRender(ui, { wrapper: IntlWrapper, ...options })

Expand Down
2 changes: 1 addition & 1 deletion src/app/receipt/[entryId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ export default async function ReceiptPage({
return (
<PageContainer className="flex min-h-[100dvh] flex-col items-center justify-center p-6">
<div className="md:hidden">
<NavHeader title="Receipt" />
<NavHeader titleKey="receipt" />
</div>
<div className="flex flex-1 flex-col items-center justify-center">
<TransactionDetailsReceipt className="w-full" transaction={transactionDetails!} isPublic />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,10 @@
*/
import React from 'react'
import { render as rtlRender, screen } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import enMessages from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'
// jest.mock calls are hoisted above this import, so the mocks below apply to it
import MantecaAddMoney from '../MantecaAddMoney'

const IntlWrapper = ({ children }: { children: React.ReactNode }) => (
<NextIntlClientProvider locale="en" messages={enMessages} timeZone="UTC">
{children}
</NextIntlClientProvider>
)

const render = (ui: React.ReactElement, options?: Omit<Parameters<typeof rtlRender>[1], 'wrapper'>) =>
rtlRender(ui, { wrapper: IntlWrapper, ...options })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,9 @@
*/
import React from 'react'
import { render as rtlRender, screen } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'

const render = (ui: React.ReactElement) =>
rtlRender(
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
{ui}
</NextIntlClientProvider>
)
const render = (ui: React.ReactElement) => rtlRender(<IntlWrapper>{ui}</IntlWrapper>)

const mockUseMantecaDepositPolling = jest.fn()
jest.mock('@/components/AddMoney/hooks/useMantecaDepositPolling', () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,11 @@
*/
import React from 'react'
import { render as rtlRender, screen, fireEvent, within } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'
import AddWithdrawCountriesList from '../AddWithdrawCountriesList'
import underMaintenanceConfig from '@/config/underMaintenance.config'

const render = (ui: React.ReactElement) =>
rtlRender(
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
{ui}
</NextIntlClientProvider>
)
const render = (ui: React.ReactElement) => rtlRender(<IntlWrapper>{ui}</IntlWrapper>)

// ---- routing ----
const mockPush = jest.fn()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
*/
import React, { useEffect } from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'

const mockRouterPush = jest.fn()
jest.mock('next/navigation', () => ({
Expand Down Expand Up @@ -137,12 +136,12 @@ function SelectedMethodProbe() {
function Harness({ user }: { user: MockUser }) {
mockUser = user
return (
<NextIntlClientProvider locale="en" messages={en}>
<IntlWrapper>
<WithdrawFlowContextProvider>
<AddWithdrawRouterView flow="withdraw" pageTitle="Withdraw" mainHeading="How?" />
<SelectedMethodProbe />
</WithdrawFlowContextProvider>
</NextIntlClientProvider>
</IntlWrapper>
)
}

Expand Down
10 changes: 2 additions & 8 deletions src/components/Badges/__tests__/BadgeEarnToast.test.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { render as rtlRender, screen, act } from '@testing-library/react'
import type { ComponentProps, ReactNode } from 'react'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'
import type { ComponentProps } from 'react'
import BadgeEarnToast from '@/components/Badges/BadgeEarnToast'

const IntlWrapper = ({ children }: { children: ReactNode }) => (
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
{children}
</NextIntlClientProvider>
)
const render = (ui: Parameters<typeof rtlRender>[0]) => rtlRender(ui, { wrapper: IntlWrapper })

// next/navigation — mutable pathname so we can exercise the /home gate; stable
Expand Down
9 changes: 1 addition & 8 deletions src/components/Badges/__tests__/BadgesRow.test.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import { render as rtlRender } from '@testing-library/react'
import { IntlWrapper } from '@/test-utils/intl'
import React from 'react'
import { NextIntlClientProvider } from 'next-intl'
import enMessages from '@/i18n/app/messages/en.json'
import type { ComponentProps } from 'react'
import BadgesRow from '@/components/Badges/BadgesRow'

const IntlWrapper = ({ children }: { children: React.ReactNode }) => (
<NextIntlClientProvider locale="en" messages={enMessages} timeZone="UTC">
{children}
</NextIntlClientProvider>
)

const render = (ui: React.ReactElement, options?: Omit<Parameters<typeof rtlRender>[1], 'wrapper'>) =>
rtlRender(ui, { wrapper: IntlWrapper, ...options })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,10 @@
*/
import React from 'react'
import { render as rtlRender, screen, fireEvent } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import { IntlWrapper } from '@/test-utils/intl'
import en from '@/i18n/app/messages/en.json'
import ApplicationStatusScreen from '@/components/Card/ApplicationStatusScreen'

const IntlWrapper = ({ children }: { children: React.ReactNode }) => (
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
{children}
</NextIntlClientProvider>
)
const render = (ui: React.ReactElement) => rtlRender(ui, { wrapper: IntlWrapper })

// NavHeader reads useAuth; stub it so the presentational screen renders alone.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,9 @@
*/
import React from 'react'
import { render as rtlRender, screen, fireEvent, waitFor } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'
import CardCountryConfirmScreen from '@/components/Card/CardCountryConfirmScreen'

const IntlWrapper = ({ children }: { children: React.ReactNode }) => (
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
{children}
</NextIntlClientProvider>
)
const render = (ui: React.ReactElement) => rtlRender(ui, { wrapper: IntlWrapper })

// NavHeader reads useAuth; stub it so the presentational screen renders alone.
Expand Down
8 changes: 1 addition & 7 deletions src/components/Card/__tests__/CardFace.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,9 @@
*/
import React from 'react'
import { render as rtlRender, screen } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'
import CardFace, { type RevealedCardDetails } from '@/components/Card/CardFace'

const IntlWrapper = ({ children }: { children: React.ReactNode }) => (
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
{children}
</NextIntlClientProvider>
)
const render = (ui: React.ReactElement) => rtlRender(ui, { wrapper: IntlWrapper })

const revealed: RevealedCardDetails = {
Expand Down
9 changes: 1 addition & 8 deletions src/components/Card/__tests__/PhysicalCardScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,11 @@
*/
import React from 'react'
import { render as rtlRender, screen } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import enMessages from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import PhysicalCardScreen from '@/components/Card/PhysicalCardScreen'
import { rainApi } from '@/services/rain'

const IntlWrapper = ({ children }: { children: React.ReactNode }) => (
<NextIntlClientProvider locale="en" messages={enMessages} timeZone="UTC">
{children}
</NextIntlClientProvider>
)

const render = (ui: React.ReactElement, options?: Omit<Parameters<typeof rtlRender>[1], 'wrapper'>) =>
rtlRender(ui, { wrapper: IntlWrapper, ...options })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
*/
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'
import { IntlWrapper } from '@/test-utils/intl'

// ---------- module-level mocks (before importing the component) ----------

Expand Down Expand Up @@ -129,9 +128,9 @@ const claimLinkData = {

function renderList() {
return render(
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
<IntlWrapper>
<SendLinkActionList claimLinkData={claimLinkData} isLoggedIn isInviteLink={false} />
</NextIntlClientProvider>
</IntlWrapper>
)
}

Expand Down
7 changes: 3 additions & 4 deletions src/components/Claim/__tests__/claim-states.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
*/
import React from 'react'
import { render, screen, waitFor } from '@testing-library/react'
import { IntlWrapper } from '@/test-utils/intl'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { NextIntlClientProvider } from 'next-intl'
import en from '@/i18n/app/messages/en.json'

// ---------- module-level mocks (must be before imports that depend on them) ----------

Expand Down Expand Up @@ -241,11 +240,11 @@ function createQueryClient() {
function renderClaim() {
const queryClient = createQueryClient()
return render(
<NextIntlClientProvider locale="en" messages={en} timeZone="UTC">
<IntlWrapper>
<QueryClientProvider client={queryClient}>
<Claim />
</QueryClientProvider>
</NextIntlClientProvider>
</IntlWrapper>
)
}

Expand Down
Loading
Loading