Files
Investidor-V2/tests/frontend/investment-profile-editor.test.mjs
T

235 lines
8.7 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
harness,
props,
text,
nodes,
companyId,
} from './helpers/investment-profile-editor.mjs';
const account = 'Perfil de investimento',
company = 'Declaração de empresa',
fresh = 'Nova declaração de empresa',
residence = 'País de residência do investidor';
test('the actual profile preserves the ISO selection and repeats the exact command after a lost response', async () => {
const h = harness();
h.change(residence, 'ZA', account);
const first = h.submit(account);
assert.equal(first.data.payload.residence_country_code, 'ZA');
await h.fail();
assert.equal(h.value(residence, account), 'ZA');
assert.equal(h.field(residence, account).props.disabled, true);
assert.match(text(h.tree), /preparação foi conservada/);
assert.equal(h.sent.length, 1);
h.submit(account);
assert.deepEqual(h.sent[1].data, first.data);
await h.reply({ version: 2 });
assert.equal(h.reloads.length, 1);
assert.match(text(h.tree), /Gravação confirmada/);
assert.equal(h.leave(), false);
});
test('a new company retry uses the original creation key and clears only its confirmed preparation', async () => {
const h = harness();
h.change('Nome da empresa', 'SYNTHETIC new', fresh);
h.change('País de constituição da entidade', 'MZ', fresh);
h.change('Função ou relação com a empresa', 'SYNTHETIC role', fresh);
h.change('Telefone', 'SYNTHETIC unsaved phone', account);
const first = h.submit(fresh);
await h.fail(503);
const second = h.submit(fresh);
assert.deepEqual(second.data, first.data);
await h.reply({ id: '10000000-0000-4000-8000-000000000002', version: 1 });
assert.equal(h.value('Nome da empresa', fresh), '');
assert.equal(h.value('Telefone', account), 'SYNTHETIC unsaved phone');
assert.equal(h.leave(), true);
});
test('a refreshed newer version preserves local edits until explicit comparison and adoption', async () => {
const h = harness();
h.change(residence, 'ZA', account);
h.render(
props({
account: {
version: 2,
payload: {
residence_country_code: 'MZ',
country: 'SYNTHETIC historical',
},
},
}),
);
assert.equal(h.value(residence, account), 'ZA');
assert.equal(
h.button('Guardar perfil de investimento', account).props.disabled,
true,
);
const read = h.click('Consultar registo guardado', account);
assert.equal(read.method, 'GET');
await h.reply(
props({
account: { version: 2, payload: { residence_country_code: 'MZ' } },
}),
);
assert.match(text(h.form(account)), /Compar|Preparação nesta página/);
h.click('Usar versão actual e manter a preparação', account);
assert.equal(h.value(residence, account), 'ZA');
const command = h.submit(account);
assert.equal(command.data.version, 2);
assert.equal(command.data.payload.residence_country_code, 'ZA');
});
test('conflict recovery reads current data without applying a write automatically', async () => {
const h = harness();
h.change('Nome da empresa', 'SYNTHETIC local name', company);
h.submit(company);
await h.fail(409);
assert.equal(h.value('Nome da empresa', company), 'SYNTHETIC local name');
const read = h.click('Consultar registo guardado', company);
await h.reply(
props({
companies: [
{
id: companyId,
version: 3,
payload: {
name: 'SYNTHETIC server name',
incorporation_country_code: 'MZ',
role: 'SYNTHETIC role',
},
},
],
}),
);
assert.equal(h.sent.length, 2);
assert.equal(read.method, 'GET');
h.click('Usar versão actual e manter a preparação', company);
const command = h.submit(company);
assert.equal(command.data.version, 3);
assert.equal(command.data.payload.name, 'SYNTHETIC local name');
});
test('validation shows each field message once and preserves its value', async () => {
const h = harness();
h.change(residence, 'ZZ', account);
const sent = h.submit(account);
await h.fail(422, sent, {
'payload.residence_country_code': ['SYNTHETIC invalid country'],
});
assert.equal(
text(h.form(account)).split('SYNTHETIC invalid country').length - 1,
1,
);
assert.equal(h.value(residence, account), 'ZZ');
assert.equal(h.field(residence, account).props['aria-invalid'], true);
});
test('one page leave guard covers multiple dirty profile declarations', () => {
const h = harness();
h.change(residence, 'ZA', account);
h.change('Nome da empresa', 'SYNTHETIC edit', company);
assert.equal(h.leave(), true);
assert.equal(h.confirmCalls, 1);
assert.equal(h.leave(true), false);
});
test('a response from the prior actor cannot confirm or reload another account', async () => {
const h = harness();
h.change(residence, 'ZA', account);
const old = h.submit(account);
h.render(
props({
actorId: 2,
account: { version: 0, payload: {} },
companies: [],
}),
);
await h.reply({ version: 2 }, old);
assert.equal(h.reloads.length, 0);
assert.equal(h.value(residence, account), '');
assert.doesNotMatch(text(h.tree), /Gravação confirmada/);
});
test('an invalid creation acknowledgement keeps the new company and command unresolved', async () => {
const h = harness();
h.change('Nome da empresa', 'SYNTHETIC retained', fresh);
h.submit(fresh);
await h.reply({ version: 1, id: 'invalid-id' });
assert.equal(h.value('Nome da empresa', fresh), 'SYNTHETIC retained');
assert.equal(h.reloads.length, 0);
assert.match(text(h.tree), /Não foi possível confirmar/);
});
test('long answers use multiline controls and text limits match the server', () => {
const h = harness();
assert.equal(h.field('Experiência relevante', account).type, 'textarea');
assert.equal(h.field('Telefone', account).props.maxLength, 30);
assert.equal(
h.field('Referência de registo / NUIT', company).props.maxLength,
100,
);
assert.equal(
nodes(h.form(account)).filter(
(node) => node.type === 'input' && node.props.required,
).length,
0,
);
});
test('consulting after an uncertain creation never unlocks editing or replaces its original command', async () => {
const h = harness();
h.change('Nome da empresa', 'SYNTHETIC original attempt', fresh);
const first = h.submit(fresh);
await h.fail();
h.click('Consultar registo guardado', fresh);
await h.reply(props());
assert.equal(
h.value('Nome da empresa', fresh),
'SYNTHETIC original attempt',
);
assert.equal(h.field('Nome da empresa', fresh).props.disabled, true);
assert.equal(
h.button('Usar versão actual e manter a preparação', fresh),
undefined,
);
const retry = h.submit(fresh);
assert.deepEqual(retry.data, first.data);
});
test('company country validation is attached once to the selectable country field', async () => {
const h = harness();
const request = h.submit(fresh);
await h.fail(422, request, {
'payload.country': ['SYNTHETIC company country required'],
});
assert.equal(
h.field('País de constituição da entidade', fresh).props[
'aria-invalid'
],
true,
);
assert.equal(
text(h.form(fresh)).split('SYNTHETIC company country required').length -
1,
1,
);
});
test('preparing a manifestation cannot discard unsaved profile data without the existing leave confirmation', () => {
const h = harness();
h.change(residence, 'ZA', account);
h.click('Preparar manifestação desta empresa');
assert.equal(h.confirmCalls, 1);
assert.equal(h.value(residence, account), 'ZA');
assert.equal(h.sent.length, 0);
});
test('a newer value read from the server requires explicit adoption before another write', async () => {
const h = harness();
h.change(residence, 'ZA', account);
h.click('Consultar registo guardado', account);
await h.reply(
props({
account: { version: 4, payload: { residence_country_code: 'MZ' } },
}),
);
const count = h.sent.length;
h.submit(account);
assert.equal(h.sent.length, count);
assert.equal(
h.button('Guardar perfil de investimento', account).props.disabled,
true,
);
h.click('Usar versão actual e manter a preparação', account);
assert.equal(h.submit(account).data.version, 4);
});