Skip to content

Commit e128ccc

Browse files
committed
test(app-shell): a fixed-to-record switch writes no defaultCurrency (#27188)
#27268 now refuses `defaultCurrency` under `currencyMode: 'record'`. The Studio currency section already drops it on a mode switch; this pins the whole path through the inspector (fixed EUR, switch to record, pick the pointer) and parses the saved object against the spec. Claude-Session: https://claude.ai/code/session_01Utp6CXtadYa5QXb2PbXPev Co-authored-by: Claude <noreply@anthropic.com>
1 parent 26913b3 commit e128ccc

1 file changed

Lines changed: 47 additions & 1 deletion

File tree

‎ui/packages/app-shell/src/views/metadata-admin/inspectors/CurrencyConfigField.recordMode-27188.test.tsx‎

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import * as React from 'react';
1010
import { describe, it, expect, vi, afterEach, beforeAll } from 'vitest';
11-
import { render, screen, cleanup } from '@testing-library/react';
11+
import { render, screen, cleanup, fireEvent, waitFor } from '@testing-library/react';
1212
import userEvent from '@testing-library/user-event';
1313
import { ObjectSchema } from '@objectstack/spec/data';
1414
import {
@@ -61,8 +61,41 @@ function renderAmount(fields: Record<string, Record<string, unknown>>) {
6161
return { onPatch, saved };
6262
}
6363

64+
/** {@link renderAmount}, with each patch applied to the draft, so a second edit sees the first. */
65+
function renderAmountLive(initial: Record<string, Record<string, unknown>>) {
66+
const onPatch = vi.fn();
67+
function Live() {
68+
const [fields, setFields] = React.useState(initial);
69+
return (
70+
<ObjectFieldInspector
71+
type="object"
72+
name="invoice"
73+
draft={{ name: 'invoice', fields }}
74+
selection={{ kind: 'field', id: 'amount' }}
75+
onPatch={(patch) => {
76+
onPatch(patch);
77+
setFields(patch.fields as Record<string, Record<string, unknown>>);
78+
}}
79+
onClearSelection={vi.fn()}
80+
onSelectionChange={vi.fn()}
81+
readOnly={false}
82+
locale="en-US"
83+
/>
84+
);
85+
}
86+
render(<Live />);
87+
const saved = () => onPatch.mock.calls.at(-1)![0].fields as Record<string, Record<string, unknown>>;
88+
return { onPatch, saved };
89+
}
90+
6491
const CODE = { type: 'text', label: 'Currency', valueDomain: 'iso_4217_currency' };
6592

93+
async function pick(label: RegExp | string, option: string) {
94+
fireEvent.keyDown(screen.getByRole('combobox', { name: label }), { key: 'ArrowDown' });
95+
await waitFor(() => expect(screen.queryAllByRole('option').length).toBeGreaterThan(0));
96+
fireEvent.click(screen.getByRole('option', { name: option }));
97+
}
98+
6699
describe('Studio currency section (ADR-0144 D2)', () => {
67100
it('a mode switch keeps only the keys that mode reads', () => {
68101
expect(switchCurrencyMode({ currencyMode: 'record', currencyField: 'currency_code' }, 'dynamic')).toEqual({ currencyMode: 'dynamic' });
@@ -88,6 +121,19 @@ describe('Studio currency section (ADR-0144 D2)', () => {
88121
expect(screen.getByRole('combobox', { name: /Currency field/ })).toHaveTextContent('currency_code');
89122
});
90123

124+
it('switching a fixed amount to record writes no defaultCurrency, and the object parses (#27268 refuses one)', async () => {
125+
const { saved } = renderAmountLive({
126+
amount: { type: 'currency', label: 'Amount', currencyConfig: { currencyMode: 'fixed', defaultCurrency: 'EUR' } },
127+
currency_code: CODE,
128+
});
129+
await pick('Currency mode', 'Record — each record names its currency');
130+
expect(saved().amount.currencyConfig).toEqual({ currencyMode: 'record' });
131+
await pick(/Currency field/, 'currency_code');
132+
const fields = saved();
133+
expect(fields.amount.currencyConfig).toEqual({ currencyMode: 'record', currencyField: 'currency_code' });
134+
expect(ObjectSchema.safeParse({ name: 'invoice', label: 'Invoice', fields }).success).toBe(true);
135+
});
136+
91137
it('"Create currency field" writes an explicit code field and the pointer, and the object parses', async () => {
92138
const { saved } = renderAmount({ amount: { type: 'currency', label: 'Amount', currencyConfig: { currencyMode: 'record' } } });
93139
await userEvent.click(screen.getByTestId('currency-config-create-code-field'));

0 commit comments

Comments
 (0)