127 lines
4.8 KiB
Python
127 lines
4.8 KiB
Python
"""349 · 326-6 배수유역 [업데이트] 흐름 — 화면 파일(`B05_Profile_UI_Drainage_Live` · `_Run` · `_Suggest`)을
|
|
가짜 DOM · 시계 · fetch 로 돌림(`helper_349_drainage_live_flow.cjs`).
|
|
|
|
- 꼭짓점 옮김 = 옛 그림 그대로 · [업데이트] 단추에 낡음 점만 · 저절로 셈 없음(시계 60 s 흘려도).
|
|
- [업데이트] = 뒤에서 조용히 셈(단추만 「계산 중…」 · 구석 표시) · 묶음이 같은 입력으로 다시 돌아도 답을 받음.
|
|
- 낡지 않아도 [업데이트] = 다시 셈(326-6) · 약속은 답이 오르면 참(B06 [>] 확인 창 뒤 이동).
|
|
- 요청 중 또 옮기면 앞 요청 끊고 다시 낡음 · 낡은 동안 제안 [적용] · [자동 제안] 끔.
|
|
- 노선 [저장] 뒤 서버 답이 「낡음」 = 낡음 표시 · 저절로 셈 없음.
|
|
- 되돌리기로 초안이 없어지면 저장분 다시 받기 · 그 답의 낡음대로 · 초안용 답 끊음(349-0i).
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def r():
|
|
proc = subprocess.run(
|
|
["node", os.path.join(HERE, "helper_349_drainage_live_flow.cjs")],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=60,
|
|
encoding="utf-8",
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
STALE_TITLE = "노선이 바뀌어 제안이 낡음 — 새 계산 뒤 적용"
|
|
IDLE = "업데이트"
|
|
BUSY = "계산 중…"
|
|
|
|
|
|
def state(stale, busy, fetches):
|
|
return {
|
|
"stale": stale,
|
|
"pending": stale, # 낡음 = 단추 점(흐림 · 덮개 없음)
|
|
"off": busy, # 셈 동안 단추만 잠금
|
|
"label": BUSY if busy else IDLE,
|
|
"busy": busy,
|
|
"fetches": fetches,
|
|
"applyOff": stale,
|
|
}
|
|
|
|
|
|
def look(row, *skip):
|
|
return {k: v for k, v in row.items() if k not in ("applyTitle", *skip)}
|
|
|
|
|
|
def test_moved_keeps_old_picture_no_auto(r):
|
|
assert look(r["start"]) == {**state(False, False, 0), "applyOff": True} # 제안 없음
|
|
assert look(r["moved"]) == state(True, False, 0)
|
|
assert look(r["sameAgain"]) == state(True, False, 0) # 판 번호만 바뀜
|
|
assert look(r["noAuto"]) == state(True, False, 0) # 60 s 지나도 셈 없음
|
|
|
|
|
|
def test_update_answer_lands_after_same_rerun(r):
|
|
assert look(r["sent"], "body") == state(True, True, 1)
|
|
assert r["sent"]["body"]["route"]["rev"] == 2 # 지금 초안 노선으로
|
|
rerun = r["rerunWhileBusy"]
|
|
assert not rerun["aborted"] and rerun["busy"] # 같은 입력 다시 돎 — 요청 그대로
|
|
assert look(r["answered"], "applied") == state(False, False, 1)
|
|
assert r["answered"]["applied"] == 1
|
|
|
|
|
|
def test_suggestions_and_apply(r):
|
|
# 관 자리 후보(200)는 제안 목록에 안 올림 — [자동 제안] 목록 몫(510)
|
|
assert r["suggest"]["shown"] and r["suggest"]["title"] == "제안 1건"
|
|
assert len(r["suggest"]["rows"]) == 1
|
|
points = {p["chainage_m"]: p for p in r["applied"]["points"]}
|
|
assert points[100]["options"]["pipe_diameter_mm"] == 1200
|
|
assert 200 not in points
|
|
assert r["applied"]["remembered"] == 1
|
|
assert r["records"] == 1 # [적용] 한 번 = 사진첩 한 걸음
|
|
|
|
|
|
def test_move_while_busy_cancels(r):
|
|
moved = r["movedWhileBusy"]
|
|
assert moved["aborted"] and look(moved, "aborted") == state(True, False, 2)
|
|
assert r["promised"] is True
|
|
assert look(r["fresh"]) == state(False, False, 3)
|
|
|
|
|
|
def test_update_always_recomputes(r):
|
|
assert look(r["again"], "route") == {**state(False, True, 4), "applyOff": False}
|
|
assert look(r["againDone"]) == state(False, False, 4)
|
|
|
|
|
|
def test_stale_blocks_apply(r):
|
|
assert r["movedWhileBusy"]["applyTitle"] == STALE_TITLE
|
|
assert r["staleApply"] == 1 # 눌러도 옛 제안이 안 들어감(앞 [적용] 한 번뿐)
|
|
assert r["fresh"]["applyTitle"] != STALE_TITLE
|
|
assert r["proposeStale"] == {"off": True, "title": "B05_Drainage_Btn_Propose_Stale"}
|
|
assert r["proposeFresh"] == {"off": False, "title": "B05_Drainage_Btn_Propose_Tip"}
|
|
|
|
|
|
def test_saved_stale_marks_only(r):
|
|
assert look(r["savedStale"], "status") == state(True, False, 4)
|
|
assert r["savedStale"]["status"] == "배수유역 낡음"
|
|
assert look(r["savedStaleNoAuto"]) == state(True, False, 4)
|
|
assert look(r["savedDone"]) == state(False, False, 5)
|
|
|
|
|
|
def test_undo_back_to_saved(r):
|
|
waiting = r["undoWaiting"]
|
|
assert waiting["aborted"] and look(waiting, "aborted", "savedLoads") == state(True, False, 6)
|
|
assert look(r["undo"], "savedLoads") == state(False, False, 6)
|
|
assert r["undo"]["savedLoads"] == 2
|
|
assert look(r["undoSavedStale"], "savedLoads") == state(True, False, 6)
|
|
assert r["undoSavedStale"]["savedLoads"] == 3
|
|
|
|
|
|
def test_input_key(r):
|
|
assert r["keys"] == {
|
|
"rev": True,
|
|
"order": True,
|
|
"node": False,
|
|
"pipe": False,
|
|
"id": False,
|
|
"saved": True,
|
|
}
|