Andrey Epifancev 83cb364a9e fix(realtime): красная рамка у ошибки ячейки, тост без Server error:undefined (AURORA-1894)
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>
2026-11-01 12:10:16 +04:00

54 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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'));
});