Skip to content

Commit 131194f

Browse files
fix: address PR #49 review (preserve dict keys, role test, parser type)
Return validated input dict instead of reconstructing four keys. Add test_missing_role_in_message and annotate build_cli_parser().
1 parent 49393b2 commit 131194f

3 files changed

Lines changed: 13 additions & 13 deletions

File tree

app.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Flask app that serves the web GUI for browsing sessions."""
22

3+
import argparse
34
import os
45
import sys
56

@@ -35,10 +36,8 @@ def index():
3536
return app
3637

3738

38-
def build_cli_parser():
39+
def build_cli_parser() -> argparse.ArgumentParser:
3940
"""CLI argument parser for ``python app.py`` (stdlib only; safe to import in tests)."""
40-
import argparse
41-
4241
parser = argparse.ArgumentParser(description="Claude Code Chat Browser")
4342
parser.add_argument("--port", type=int, default=5000)
4443
parser.add_argument("--host", default="127.0.0.1")

tests/test_jsonl_validation.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ def test_null_role_in_message(self):
4646
)
4747
assert exc_info.value.path == "messages[0].role"
4848

49+
def test_missing_role_in_message(self):
50+
with pytest.raises(SessionValidationError) as exc_info:
51+
validate_session_dict(
52+
_valid_payload(messages=[{"text": "no role key"}])
53+
)
54+
assert exc_info.value.path == "messages[0].role"
55+
4956
def test_metadata_not_dict(self):
5057
with pytest.raises(SessionValidationError) as exc_info:
5158
validate_session_dict(_valid_payload(metadata="not-a-dict"))

utils/validation.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
from typing import Any, cast
44

55
from models.errors import SessionValidationError
6-
from models.session import MessageDict, SessionDict
6+
from models.session import SessionDict
77

88
_REQUIRED_SESSION_KEYS = ("session_id", "title", "messages", "metadata")
99

1010

1111
def validate_session_dict(data: dict[str, Any]) -> SessionDict:
1212
"""Validate a plain dict matches SessionDict before returning it."""
13+
# Runtime guard for dynamic callers; mypy already types the parameter as dict.
1314
if not isinstance(data, dict):
1415
raise SessionValidationError("$", "expected dict")
1516

@@ -18,6 +19,7 @@ def validate_session_dict(data: dict[str, Any]) -> SessionDict:
1819
raise SessionValidationError(key, "missing required field")
1920

2021
session_id = data["session_id"]
22+
# Explicit null check before isinstance so errors say "must not be null".
2123
if session_id is None:
2224
raise SessionValidationError("session_id", "must not be null")
2325
if not isinstance(session_id, str):
@@ -67,12 +69,4 @@ def validate_session_dict(data: dict[str, Any]) -> SessionDict:
6769
"metadata", f"expected dict, got {type(metadata).__name__}"
6870
)
6971

70-
return cast(
71-
SessionDict,
72-
{
73-
"session_id": session_id,
74-
"title": title,
75-
"messages": cast(list[MessageDict], messages),
76-
"metadata": metadata,
77-
},
78-
)
72+
return cast(SessionDict, data)

0 commit comments

Comments
 (0)