|
| 1 | +/** |
| 2 | + * objectstack#27188 — a dashboard `table` over a grouped `record`-mode answer |
| 3 | + * shows each row's amount in that row's own currency (ADR-0144 D9). The |
| 4 | + * measure column names the result column holding the code (`currencyField`, |
| 5 | + * objectstack#27338); the grand-total cell, which may add several currencies, |
| 6 | + * gets no symbol. |
| 7 | + */ |
| 8 | +import { describe, it, expect, vi, afterEach } from 'vitest'; |
| 9 | +import { render, screen, cleanup, waitFor } from '@testing-library/react'; |
| 10 | +import { DatasetWidget } from '../DatasetWidget'; |
| 11 | + |
| 12 | +vi.mock('../DrillDownDrawer', () => ({ DrillDownDrawer: () => null })); |
| 13 | + |
| 14 | +/** Plain TEXT dimension field, no `options` — nothing here relabels. */ |
| 15 | +const OPPORTUNITY = { name: 'opportunity', fields: { currency_code: { type: 'text' } } }; |
| 16 | + |
| 17 | +afterEach(() => { |
| 18 | + cleanup(); |
| 19 | + vi.unstubAllGlobals(); |
| 20 | + vi.restoreAllMocks(); |
| 21 | +}); |
| 22 | + |
| 23 | +const source = () => ({ |
| 24 | + queryDataset: vi.fn(async () => ({ |
| 25 | + rows: [ |
| 26 | + { currency_code: 'USD', amount_sum: 1234.5 }, |
| 27 | + { currency_code: 'EUR', amount_sum: 99 }, |
| 28 | + { currency_code: null, amount_sum: 7 }, |
| 29 | + ], |
| 30 | + fields: [ |
| 31 | + { name: 'currency_code', type: 'text', label: 'Currency' }, |
| 32 | + { name: 'amount_sum', type: 'number', label: 'Amount', format: '0.00', currencyField: 'currency_code' }, |
| 33 | + ], |
| 34 | + totals: [{ dimensions: [] as string[], rows: [{ amount_sum: 1340.5 }] }], |
| 35 | + })), |
| 36 | +}); |
| 37 | + |
| 38 | +const TABLE_WIDGET = { type: 'table', dataset: 'amount_by_currency', dimensions: ['currency_code'], values: ['amount_sum'] }; |
| 39 | + |
| 40 | +const amountColumn = () => |
| 41 | + Array.from(document.querySelectorAll('tbody tr')).map((r) => r.querySelectorAll('td')[1]?.textContent?.trim() ?? ''); |
| 42 | + |
| 43 | +describe('DatasetWidget table — record-mode amounts (ADR-0144 D9)', () => { |
| 44 | + it('formats each row in its own currency, and a row without a code as a plain number', async () => { |
| 45 | + vi.stubGlobal('fetch', vi.fn(async () => ({ ok: true, json: async () => ({ item: OPPORTUNITY }) }))); |
| 46 | + render(<DatasetWidget widget={TABLE_WIDGET} dataSource={source()} />); |
| 47 | + await screen.findByText('Amount'); |
| 48 | + await waitFor(() => expect(amountColumn()).toEqual(['$1,234.50', '€99.00', '7.00'])); |
| 49 | + }); |
| 50 | + |
| 51 | + it('gives the grand total no symbol', async () => { |
| 52 | + vi.stubGlobal('fetch', vi.fn(async () => ({ ok: true, json: async () => ({ item: OPPORTUNITY }) }))); |
| 53 | + render(<DatasetWidget widget={TABLE_WIDGET} dataSource={source()} />); |
| 54 | + const foot = await screen.findByTestId('dataset-table-total-row'); |
| 55 | + expect(foot.querySelectorAll('td')[1]?.textContent?.trim()).toBe('1,340.50'); |
| 56 | + }); |
| 57 | +}); |
0 commit comments