import test from 'node:test'; import assert from 'node:assert/strict'; import { harness, participant, props, original, nodes, text, } from './helpers/partnership-room.mjs'; test('new milestone selects named current representatives explicitly and submits the selected person', () => { const h = harness(); assert.equal( h.field('milestone:new', 'Responsável pelo marco').props.value, '', ); assert.equal( h.button('Guardar marco', h.form('milestone:new')).props.disabled, true, ); assert.match( text(h.field('milestone:new', 'Responsável pelo marco')), /SYNTHETIC authorised officer — Proponente/, ); h.change('milestone:new', 'Responsável pelo marco', '4'); assert.equal( h.button('Guardar marco', h.form('milestone:new')).props.disabled, false, ); const request = h.submit('milestone:new'); assert.equal(request.url, '/parcerias/salas/10/marcos'); assert.equal(request.data.responsible_id, '4'); }); test('a revoked original assignment stays visible and requires explicit replacement', () => { const h = harness( props({ milestones: [{ ...original, responsible_is_participant: false }], participants: [participant(4, 'SYNTHETIC current officer')], }), ); const select = h.field('milestone:7', 'Responsável pelo marco'); assert.equal(select.props.value, '1'); const historical = nodes(select).find( (node) => node.type === 'option' && node.props.value === '1', ); assert.equal(historical.props.disabled, true); assert.match( text(historical), /SYNTHETIC original author — sem representação actual/, ); assert.match( text(h.form('milestone:7')), /consultar não altera o responsável/, ); assert.equal( h.button('Guardar marco', h.form('milestone:7')).props.disabled, true, ); h.change('milestone:7', 'Responsável pelo marco', '4'); const request = h.submit('milestone:7'); assert.equal(request.method, 'put'); assert.equal(request.data.version, 3); assert.equal(request.data.responsible_id, '4'); }); test('read only, negotiation and terminal rooms keep names/history and expose no clean milestone form', () => { for (const status of ['negotiation', 'closed', 'cancelled']) { const h = harness( props({ room: { id: 10, version: 3, status, agreement: null }, milestones: [original], participants: [], }), ); assert.equal(h.form('milestone:7'), undefined); assert.equal(h.form('milestone:new'), undefined); assert.match(text(h.tree), /Responsável: SYNTHETIC original author/); assert.doesNotMatch(text(h.tree), /Responsável ID/); } const readOnly = harness( props({ canWrite: false, milestones: [original], participants: [] }), ); assert.equal(readOnly.form('milestone:7'), undefined); }); test('current assignment remains selected and person representing both parties appears once', () => { const h = harness( props({ milestones: [original], participants: [ participant(1, 'SYNTHETIC dual representative', [ 'proponent', 'candidate', ]), ], }), ); const select = h.field('milestone:7', 'Responsável pelo marco'); assert.equal(select.props.value, '1'); assert.equal( h.button('Guardar marco', h.form('milestone:7')).props.disabled, false, ); assert.equal( nodes(select).filter( (node) => node.type === 'option' && node.props.value === '1', ).length, 1, ); assert.match(text(select), /Proponente \/ Candidato/); }); test('refreshed participant choices invalidate a cached selection without silently changing it', () => { const h = harness(); h.change('milestone:new', 'Responsável pelo marco', '4'); h.render({ ...h.props, participants: [participant(2, 'SYNTHETIC candidate', ['candidate'])], }); assert.equal( h.field('milestone:new', 'Responsável pelo marco').props.value, '4', ); assert.equal( h.button('Guardar marco', h.form('milestone:new')).props.disabled, true, ); assert.match( text(h.form('milestone:new')), /participante seleccionado deixou de estar disponível/, ); h.submit('milestone:new'); assert.equal(h.sent.length, 0); }); test('missing historical name is reported without asking for an account identifier', () => { const h = harness( props({ canWrite: false, milestones: [ { ...original, responsible_name: null, responsible_is_participant: false, }, ], participants: [], }), ); assert.match(text(h.tree), /Responsável registado indisponível/); assert.match(text(h.tree), /atribuição anterior conservada/); assert.doesNotMatch(text(h.tree), /Responsável ID/); });