import assert from 'node:assert/strict'; import test from 'node:test'; import { createElement, isValidElement, type ReactElement, type ReactNode } from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { PledgeClaimFields, pledgeClaimInputError } from '../components/pledge-claim-fields'; type ElementProps = { children?: ReactNode; [key: string]: unknown }; type Element = ReactElement; function elements(node: ReactNode): Element[] { if (Array.isArray(node)) return node.flatMap(elements); if (!isValidElement(node)) return []; return [node, ...elements(node.props.children)]; } function input(props: Parameters[0]) { const field = elements(PledgeClaimFields(props)).find(element => element.props.id === 'truth-pledge-minimum'); assert.ok(field && typeof field.props.onChange === 'function'); return field; } function edit(props: Parameters[0], value: number) { (input(props).props.onChange as (event: { currentTarget: { valueAsNumber: number } }) => void)( { currentTarget: { valueAsNumber: value } }); } void test('ally funding question checks positive safe totals and respects disabled controls', () => { const changes: number[] = []; const props = {minimum: 2, allyName: 'House Guild', disabled: false, onChange: (value: number) => changes.push(value)}; assert.equal(pledgeClaimInputError(props.minimum), null); edit(props, 1); edit(props, Number.MAX_SAFE_INTEGER); for (const value of [0, -1, 1.5, NaN, Infinity, Number.MAX_SAFE_INTEGER + 1]) { assert.ok(pledgeClaimInputError(value)); edit(props, value); } edit({ ...props, disabled: true }, 3); assert.deepEqual(changes, [1, Number.MAX_SAFE_INTEGER]); assert.match(renderToStaticMarkup(createElement(PledgeClaimFields, { ...props, minimum: 0 })), /role="alert"/); }); void test('ally funding explanation distinguishes an update, previous pledge and payment', () => { const html = renderToStaticMarkup(createElement(PledgeClaimFields, { minimum: 3, allyName: 'House Guild', disabled: false, onChange() {}, })); assert.match(html, /Current ally: House Guild/); assert.match(html, /after the answer during this phase/); assert.match(html, /same total again counts/); assert.match(html, /earlier pledge alone does not/); assert.match(html, /not a payment/); assert.doesNotMatch(html, /current balance|available wallet/i); });