test(sheet): ничья ключа сортировки по-настоящему, F1-AHR-plan, комментарий 0051 (AURORA-1850)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4a5e15e970
commit
655a69cf34
@ -1,7 +1,5 @@
|
||||
-- AURORA-1850 (change: openspec/changes/aurora-1850-upd-form-cells-subtree): правка ячейки пересчитывает только затронутое поддерево.
|
||||
-- Параметр фокуса p_focus_lines (D1) и колонка _sort_rank (D2) в построителях FORM_2 AHR/CAP/OPER.
|
||||
-- Тела — буквальные, сняты с БД после 0050 (D8, before-0051.sql); порядок операторов — D9.
|
||||
-- FORM_1 (Task 5): те же правки, v_form1_view, v_form_view. Остальные функции добавляются следующими задачами плана.
|
||||
-- AURORA-1850: фокусные сборщики FORM_1/FORM_2, скелет с _sort_rank, _form_affected_rows и дельта AHR на фокусном пути, jit=off.
|
||||
|
||||
DROP FUNCTION v3.v_form2_view(integer, character varying, text[]);
|
||||
DROP FUNCTION v3.v_form2_sheet_jsonb(integer, character varying, text[]);
|
||||
|
||||
@ -45,6 +45,7 @@ CASES = {
|
||||
"F2-AHR_LIMIT": ("FORM_2", "AHR_LIMIT", None, None, 0),
|
||||
"F2-OTCH9F": ("FORM_2", "OTCH9F", None, None, 0),
|
||||
"F2-AHR-plan": ("FORM_2", "AHR", None, ["plan"], 2048),
|
||||
"F1-AHR-plan": ("FORM_1", "AHR", "Support", ["plan"], 2049),
|
||||
}
|
||||
SAT_FORM = 4
|
||||
|
||||
@ -201,7 +202,6 @@ def test_affected_rows_match_reference(client, headers, db_exec, path, case):
|
||||
form_type, sheet, direction, sections, _ = CASES[case]
|
||||
form_id, units, batches = _prepare(client, headers, db_exec, case)
|
||||
assert units, "в листе нет строк"
|
||||
is_tree = sheet in ("AHR", "CAP", "OPER")
|
||||
for i in units:
|
||||
_check(db_exec, path, form_type, form_id, sheet, [i], direction, sections, f"{case} id={i}",
|
||||
must_have_input=sheet != "AHR_LIMIT" and sheet != "OTCH9F")
|
||||
@ -209,7 +209,6 @@ def test_affected_rows_match_reference(client, headers, db_exec, path, case):
|
||||
dev = batches[0][-1]
|
||||
rows = affected_rows(db_exec, form_id, sheet, [dev], direction, sections)
|
||||
assert not any(_has_input(r, dev) for r in rows), "Development INPUT попал в результат Support"
|
||||
del is_tree
|
||||
for n, batch in enumerate(batches):
|
||||
_check(db_exec, path, form_type, form_id, sheet, batch, direction, sections, f"{case} batch#{n}")
|
||||
|
||||
@ -373,17 +372,22 @@ def _sort_key_candidate(db_exec):
|
||||
ORDER BY b.id LIMIT 1
|
||||
"""
|
||||
)
|
||||
return rows[0][0] if rows else None
|
||||
return (rows[0][0], rows[0][1]) if rows else None
|
||||
|
||||
|
||||
def test_sort_key_tie_node_before_line(client, headers, db_exec):
|
||||
child = _sort_key_candidate(db_exec)
|
||||
if child is None:
|
||||
cand = _sort_key_candidate(db_exec)
|
||||
if cand is None:
|
||||
pytest.skip("нет статьи AHR глубины 3 с дочерней глубины 4 и свободным id в budget_line")
|
||||
child, parent = cand
|
||||
assert child != parent
|
||||
form_id = _new_form(client, headers, "FORM_2", 2058)
|
||||
# строка висит на родительской статье, а её id равен id дочерней статьи:
|
||||
# ключ сортировки INPUT совпадает с ключом узла дочерней статьи (ничья)
|
||||
db_exec(
|
||||
"INSERT INTO v3.budget_line (id, budget_form_id, expense_item_id, name) "
|
||||
"VALUES (:i, :f, :i, 'tie')", i=child, f=form_id)
|
||||
"VALUES (:i, :f, :p, 'tie')", i=child, f=form_id, p=parent)
|
||||
assert db_exec("SELECT expense_item_id FROM v3.budget_line WHERE id = :i", i=child)[0][0] == parent
|
||||
g1 = _get_sheet(client, headers, form_id, "AHR")
|
||||
g2 = _get_sheet(client, headers, form_id, "AHR")
|
||||
assert [row_key(r) for r in g1] == [row_key(r) for r in g2]
|
||||
@ -391,13 +395,16 @@ def test_sort_key_tie_node_before_line(client, headers, db_exec):
|
||||
assert idx > 0
|
||||
prev = g1[idx - 1]
|
||||
assert prev["row_type"] in TREE_TYPES and prev["data"]["header"]["expense_item_id"] == child, prev
|
||||
assert prev["sort_order"] == g1[idx]["sort_order"] - 1
|
||||
patch = _patch_cell(client, headers, form_id, "AHR", child, "plan.q1", 8)
|
||||
node = next((r for r in patch if r["row_type"] in TREE_TYPES
|
||||
and r["data"]["header"]["expense_item_id"] == child), None)
|
||||
assert node is not None, "узел дочерней статьи отсутствует в ответе"
|
||||
line_row = next(r for r in patch if r["row_type"] == "INPUT" and r["data"]["line_id"] == child)
|
||||
assert node["sort_order"] < line_row["sort_order"]
|
||||
assert_patch_rows_match_sheet(patch, _get_sheet(client, headers, form_id, "AHR"))
|
||||
get_rows = _get_sheet(client, headers, form_id, "AHR")
|
||||
line_patch = next(r for r in patch if r["row_type"] == "INPUT" and r["data"]["line_id"] == child)
|
||||
line_get = next(r for r in get_rows if r["row_type"] == "INPUT" and r["data"]["line_id"] == child)
|
||||
assert line_patch["sort_order"] == line_get["sort_order"]
|
||||
node_get = next(r for r in get_rows if r["row_type"] in TREE_TYPES
|
||||
and r["data"]["header"]["expense_item_id"] == child)
|
||||
assert node_get["sort_order"] == line_get["sort_order"] - 1
|
||||
assert_patch_rows_match_sheet(patch, get_rows)
|
||||
|
||||
|
||||
def _delta_equals_get(db_exec, sheet, row_id):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user