Cell.jsx: порядок спреда стилей — base → editable/not-editable → locked →
invalid (INVALID_STYLES последним), чтобы красная рамка 2px не перетиралась
EDITABLE_STYLES у вводимых ячеек с ошибкой.
utils/wsErrorUtils.js: getWsErrorMessage(error) — строка возвращается как
есть, объект берёт message || detail, известные технические префиксы
(computed_field:, role_not_allowed:, window_closed:, org_not_assigned)
заменяются понятным текстом, прочее отдаётся без "Server error:".
RealtimeContext.js: toast.error(getWsErrorMessage(data.error)) вместо
`Server error:${data.error.message}` || '', которое всегда давало undefined
для ошибок-строк (|| не срабатывает на непустой строке).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
54 lines
3.2 KiB
JavaScript
54 lines
3.2 KiB
JavaScript
import assert from 'node:assert/strict';
|
||
import { test } from 'node:test';
|
||
import { getWsErrorMessage } from './wsErrorUtils.js';
|
||
|
||
test('строка возвращается как есть', () => {
|
||
assert.equal(getWsErrorMessage('Ячейка уже редактируется другим пользователем'), 'Ячейка уже редактируется другим пользователем');
|
||
});
|
||
|
||
test('объект с message возвращает message', () => {
|
||
assert.equal(getWsErrorMessage({ code: 400, field: 'q1.transfer_econ', message: 'Нельзя указать отрицательное значение' }), 'Нельзя указать отрицательное значение');
|
||
});
|
||
|
||
test('объект без message возвращает detail', () => {
|
||
assert.equal(getWsErrorMessage({ detail: 'Ошибка подключения к базе данных' }), 'Ошибка подключения к базе данных');
|
||
});
|
||
|
||
test('объект без message и без detail возвращает дефолтный текст, а не undefined', () => {
|
||
const result = getWsErrorMessage({ code: 500 });
|
||
assert.notEqual(result, undefined);
|
||
assert.equal(typeof result, 'string');
|
||
assert.ok(!result.includes('undefined'));
|
||
});
|
||
|
||
test('префикс computed_field: заменяется человеческим текстом', () => {
|
||
assert.equal(getWsErrorMessage('computed_field: q1.corrected_plan'), 'Это расчётная ячейка, её нельзя изменить');
|
||
assert.equal(getWsErrorMessage({ message: 'computed_field: q1.corrected_plan' }), 'Это расчётная ячейка, её нельзя изменить');
|
||
});
|
||
|
||
test('префикс role_not_allowed: заменяется человеческим текстом', () => {
|
||
assert.equal(getWsErrorMessage('role_not_allowed: data.q1.transfer_econ'), 'Нет прав на изменение этой колонки');
|
||
});
|
||
|
||
test('префикс window_closed: заменяется человеческим текстом', () => {
|
||
assert.equal(getWsErrorMessage('window_closed: data.q1.transfer_econ'), 'Окно ввода для этой колонки закрыто');
|
||
});
|
||
|
||
test('префикс org_not_assigned заменяется человеческим текстом', () => {
|
||
assert.equal(getWsErrorMessage('org_not_assigned'), 'Вы не назначены на эту форму');
|
||
assert.equal(getWsErrorMessage({ message: 'org_not_assigned: form_id=123' }), 'Вы не назначены на эту форму');
|
||
});
|
||
|
||
test('неизвестный текст возвращается без технического префикса Server error:', () => {
|
||
const result = getWsErrorMessage('Database unavailable');
|
||
assert.equal(result, 'Database unavailable');
|
||
assert.ok(!result.startsWith('Server error:'));
|
||
});
|
||
|
||
test('пустая строка и отсутствующая ошибка не превращаются в undefined', () => {
|
||
assert.notEqual(getWsErrorMessage(''), undefined);
|
||
assert.notEqual(getWsErrorMessage(null), undefined);
|
||
assert.notEqual(getWsErrorMessage(undefined), undefined);
|
||
assert.ok(!String(getWsErrorMessage(undefined)).includes('undefined'));
|
||
});
|