fix(realtime): getDataRowId возвращает null вместо undefined, тесты M-8/M-9
После jsonb_strip_nulls у групп/позиций нет ключа line_id, getDataRowId
возвращал undefined, и row_id в сообщении удаления сериализовался в {}
(KeyError на сервере). Возвращаем null, как до фазы B.
Добавлены тесты updateCells (глубокое отсутствие блока, два обновления в батче)
и сверка jsonb_strip_nulls с _strip_nulls.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
07f129e934
commit
c859ca1c59
@ -61,6 +61,19 @@ def _strip_nulls(value):
|
||||
return value
|
||||
|
||||
|
||||
def test_pg_jsonb_strip_nulls_matches_strip_nulls(client, db_session):
|
||||
literal = '{"a":{"b":null},"c":[null,{"d":null,"e":1},[{"f":null}]],"g":null,"h":{}}'
|
||||
|
||||
async def _go():
|
||||
res = await db_session.execute(text("SELECT jsonb_strip_nulls(CAST(:v AS jsonb))"), {"v": literal})
|
||||
return res.scalar_one()
|
||||
pg = client.portal.call(_go)
|
||||
if isinstance(pg, str):
|
||||
pg = json.loads(pg)
|
||||
assert pg == _strip_nulls(json.loads(literal))
|
||||
assert pg == {"a": {}, "c": [None, {"e": 1}, [{}]], "h": {}}
|
||||
|
||||
|
||||
def _has_null_field(value) -> bool:
|
||||
if isinstance(value, dict):
|
||||
return any(v is None or _has_null_field(v) for v in value.values())
|
||||
|
||||
@ -229,3 +229,19 @@ test('AURORA-1848: отсутствующий скалярный ключ вер
|
||||
const out = updateCells(data, [['INPUT', 3, 1, { line_id: 9 }]]);
|
||||
assert.equal(out[0].data.line_id, 9);
|
||||
});
|
||||
|
||||
test('AURORA-1848: блок отсутствует на двух уровнях вглубь — создаётся цепочка, вход не меняется', () => {
|
||||
const data = deepFreeze([row({ line_id: 7 })]);
|
||||
const out = updateCells(data, [['INPUT', 3, 1, { plan: { support: { q1: 5 } } }]]);
|
||||
assert.equal(out[0].data.plan.support.q1, 5);
|
||||
assert.deepEqual(data[0].data, { line_id: 7 });
|
||||
});
|
||||
|
||||
test('AURORA-1848: два обновления одной строки в одном батче складываются', () => {
|
||||
const data = deepFreeze([row({ line_id: 7 })]);
|
||||
const out = updateCells(data, [
|
||||
['INPUT', 3, 1, { q1: { m1: 5 } }],
|
||||
['INPUT', 3, 1, { q1: { m2: 3 } }],
|
||||
]);
|
||||
assert.deepEqual(out[0].data.q1, { m1: 5, m2: 3 });
|
||||
});
|
||||
|
||||
@ -30,7 +30,7 @@ export function buildRowHierarchy(items, mapItem = (item) => item) {
|
||||
}
|
||||
|
||||
export function getDataRowId(data) {
|
||||
return data?.id || data?.line_id;
|
||||
return data?.id || data?.line_id || null;
|
||||
}
|
||||
|
||||
export function getRowId(row) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { buildRowHierarchy } from './rowUtils.js';
|
||||
import { buildRowHierarchy, getDataRowId } from './rowUtils.js';
|
||||
|
||||
test('row hierarchy uses row types when depth skips a level and keeps INPUT rows as siblings', () => {
|
||||
const rows = [
|
||||
@ -19,3 +19,10 @@ test('row hierarchy uses row types when depth skips a level and keeps INPUT rows
|
||||
assert.deepEqual(tree[0].subRows[0].subRows.map(({ id }) => id), ['input-1', 'input-2']);
|
||||
assert.deepEqual(tree[0].subRows[0].subRows[0].subRows, []);
|
||||
});
|
||||
|
||||
test('AURORA-1848: getDataRowId без id и line_id возвращает null и сериализуется в row_id:null', () => {
|
||||
assert.equal(getDataRowId({ header: {} }), null);
|
||||
assert.equal(getDataRowId({ id: 5 }), 5);
|
||||
assert.equal(getDataRowId({ line_id: 7 }), 7);
|
||||
assert.ok(JSON.stringify({ row_id: getDataRowId({ header: {} }) }).includes('"row_id":null'));
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user