- B05 · B06 물음이 아직 같은 페이지로 보고 안 물어 초안 있는 채 바로 로그아웃되던 것 - 라우터처럼 주소를 홈으로 옮긴 뒤 물음 · [취소]면 주소 되돌림 - 화면: 초안 있는 채 로그아웃 → 확인창 · [취소] 머묾 · [폐기] 지움 · 밝음/어두움 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
76 lines
3.0 KiB
Python
76 lines
3.0 KiB
Python
"""388-1 · 388-3 보안 — 로그아웃 · 계정 바뀜 지움 · 세션 넘침 · 탭이 연 프로젝트 고정(요구 242).
|
|
|
|
- 로그아웃 = 세션 전부(초안 · 결과 · 들어온 표식) · 현재 프로젝트 · 3D 보관함 지움 · pref 둠
|
|
- 계정 바뀜(저장한 주인 ≠ 지금 사용자) = 같은 지움 · 같은 계정이면 안 지움 · 열쇠에 계정 안 섞음
|
|
- 세션 넘침 = 결과 칸 비우고 한 번 다시 · 그래도 넘치면 「저장 공간 부족」 안내
|
|
- 탭이 연 프로젝트 고정 = 다른 탭이 현재 프로젝트를 바꿔도 이 탭 초안 칸 그대로
|
|
`helper_384_s_session.cjs` 가 진짜 TS 를 가짜 저장소 위에서 돌림.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def out():
|
|
proc = subprocess.run(
|
|
["node", os.path.join(HERE, "helper_384_s_session.cjs")],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=60,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
def test_로그아웃_지움(out):
|
|
assert out["logout"]["session"] == []
|
|
assert out["logout"]["project"] is None
|
|
assert out["logout"]["pref"] == "1"
|
|
assert out["logout"]["purged"] == [""] # 빈 id = 모든 프로젝트 지형
|
|
|
|
|
|
def test_계정_바뀜_지움(out):
|
|
owner = out["owner"]
|
|
assert owner["first"] is True and owner["firstKeys"] == 0 # 주인 모름 = 지움
|
|
assert owner["same"] is False and owner["sameKeys"] == 4
|
|
assert owner["other"] is True and owner["otherKeys"] == 0
|
|
assert owner["otherProject"] is None and owner["stored"] == "u2"
|
|
assert owner["numericAgain"] is False # 수 id 3 == 저장 "3"
|
|
|
|
|
|
def test_세션_넘침_결과_비우고_다시(out):
|
|
assert out["overflow"] == {"saved": 100, "result": None, "draft": 50, "toasts": 0}
|
|
|
|
|
|
def test_그래도_넘치면_안내(out):
|
|
assert out["full"]["saved"] is None
|
|
assert out["full"]["toasts"] == [["Session_Storage_Full", "warning"]]
|
|
|
|
|
|
def test_탭이_연_프로젝트_고정(out):
|
|
assert out["pin"] == {"before": "first", "after": "first", "explicit": "given"}
|
|
|
|
|
|
def test_로그아웃_길_차례():
|
|
shell = (ROOT / "A00_Common/app_shell.ts").read_text(encoding="utf-8")
|
|
body = shell[shell.index("async function onApp_Logout_Click") :]
|
|
body = body[: body.index("\n}\n")]
|
|
order = [
|
|
body.index(s)
|
|
for s in ("replaceState(", "takeLeaveGuard()", "logout()", "wipeAccountCache()", "reload()")
|
|
] # 주소 먼저 옮김 — B05 · B06 물음이 「같은 페이지」로 보고 안 묻는 일 막음
|
|
assert order == sorted(order)
|
|
login = (ROOT / "A06_Login/A06_Login_Api_Fetch.ts").read_text(encoding="utf-8")
|
|
assert "wipeIfOwnerChanged(data.user.id)" in login
|
|
page = (ROOT / "A00_Common/design/design_page.ts").read_text(encoding="utf-8")
|
|
assert "pinDraftProject(projectId)" in page
|