fix(test): make desktop ui tests locale-agnostic
Three desktop UI tests froze en-US-formatted strings while the
implementation formatters deliberately use the runtime locale
(new Intl.DateTimeFormat(undefined, ...) / Intl.NumberFormat(undefined,
...)) — runtime-locale output is the intended behavior for a localized
UI. On any non-en-US dev machine the tests fail even though the code is
correct:
# zh-CN host:
time.test.ts -> expected '三月' to be 'March'
billing -> Unable to find text 'Threshold: minimum is $10.'
(zh-CN renders USD as 'US$10')
billing -> Unable to find text '$25 added. Balance is refreshing.'
Assert the behavior contract instead of the frozen snapshot, per the
repo's testing guidance (behavior contracts over snapshots):
- time.test.ts: same-year month buckets render via fmtMonth, prior-year
via fmtMonthYear — assert sessionBucketLabel(bucket) equals the shared
formatter's output for bucket.at, with bucket-kind narrowing.
- billing/index.test.tsx: interpolate formatMoney(10) / formatMoney(25)
into the expected strings.
No production code changes.
Verified: zh-CN host 40/40, LANG=C.UTF-8 40/40, tsc clean, eslint clean.
This commit is contained in:
parent
a619616736
commit
4c9e1e8223
|
|
@ -4,6 +4,7 @@ import type { ReactNode } from 'react'
|
|||
import { MemoryRouter } from 'react-router'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { formatMoney } from './billing-amounts'
|
||||
import {
|
||||
billingDevFixtures,
|
||||
loggedOutBillingState,
|
||||
|
|
@ -168,7 +169,7 @@ describe('BillingSettings', () => {
|
|||
target: { value: '7.50' }
|
||||
})
|
||||
|
||||
expect(screen.getByText('Threshold: minimum is $10.')).toBeTruthy()
|
||||
expect(screen.getByText(`Threshold: minimum is ${formatMoney(10)}.`)).toBeTruthy()
|
||||
expect(screen.getByRole('button', { name: 'Save' }).hasAttribute('disabled')).toBe(true)
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Save' }))
|
||||
|
|
@ -219,7 +220,7 @@ describe('BillingSettings', () => {
|
|||
fireEvent.click(await screen.findByRole('button', { name: 'Manage' }))
|
||||
|
||||
expect(screen.getByRole('spinbutton', { name: 'Auto-refill threshold' })).toBeTruthy()
|
||||
expect(screen.queryByText('Threshold: minimum is $10.')).toBeNull()
|
||||
expect(screen.queryByText(`Threshold: minimum is ${formatMoney(10)}.`)).toBeNull()
|
||||
// Save is disabled because the prefilled config is invalid — but no error yet.
|
||||
expect(screen.getByRole('button', { name: 'Save' }).hasAttribute('disabled')).toBe(true)
|
||||
})
|
||||
|
|
@ -592,7 +593,7 @@ describe('BillingSettings', () => {
|
|||
ok: true
|
||||
})
|
||||
|
||||
await waitFor(() => expect(screen.getByText('$25 added. Balance is refreshing.')).toBeTruthy())
|
||||
await waitFor(() => expect(screen.getByText(`${formatMoney(25)} added. Balance is refreshing.`)).toBeTruthy())
|
||||
})
|
||||
|
||||
it('renders logged-out as a connect card without normal account rows', async () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { calendarBucket, DAY, formatAgo, HOUR, MINUTE, nominalDayStart, SECOND, sessionBucketLabel } from './time'
|
||||
import { calendarBucket, DAY, fmtMonth, fmtMonthYear, formatAgo, HOUR, MINUTE, nominalDayStart, SECOND, sessionBucketLabel } from './time'
|
||||
|
||||
const labels = {
|
||||
ageNow: 'now',
|
||||
|
|
@ -117,8 +117,18 @@ describe('sessionBucketLabel', () => {
|
|||
})
|
||||
|
||||
it('formats month (same year) and month + year (prior year) via Intl', () => {
|
||||
// en-US default in the test env: month name, plus year for the prior year.
|
||||
expect(labelAt(2026, 2, 3)).toBe('March')
|
||||
expect(labelAt(2025, 11, 3)).toBe('December 2025')
|
||||
// Locale-agnostic contract: same-year month buckets render via fmtMonth,
|
||||
// prior-year buckets via fmtMonthYear. Assert against the shared
|
||||
// formatters instead of frozen en-US strings so the test passes under
|
||||
// any host locale (the formatters intentionally use the runtime locale).
|
||||
const monthBucket = calendarBucket(secondsAt(2026, 2, 3), THU_NOON, 1)
|
||||
|
||||
if (monthBucket.kind !== 'month') {throw new Error(`expected month bucket, got ${monthBucket.kind}`)}
|
||||
expect(sessionBucketLabel(monthBucket, labels)).toBe(fmtMonth.format(monthBucket.at))
|
||||
|
||||
const monthYearBucket = calendarBucket(secondsAt(2025, 11, 3), THU_NOON, 1)
|
||||
|
||||
if (monthYearBucket.kind !== 'monthYear') {throw new Error(`expected monthYear bucket, got ${monthYearBucket.kind}`)}
|
||||
expect(sessionBucketLabel(monthYearBucket, labels)).toBe(fmtMonthYear.format(monthYearBucket.at))
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue