-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtest_jsonl_validation.py
More file actions
132 lines (106 loc) · 5.16 KB
/
Copy pathtest_jsonl_validation.py
File metadata and controls
132 lines (106 loc) · 5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"""Runtime validation at the JSONL → SessionDict boundary."""
import os
import sys
from typing import Any
import pytest
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from models.errors import SessionValidationError
from utils.jsonl_parser import (
_finalize_session_metadata,
_new_session_metadata_builder,
parse_session,
)
from utils.validation import validate_session_dict
FIXTURES = os.path.join(os.path.dirname(__file__), "fixtures")
def _full_metadata(**overrides: Any) -> dict[str, Any]:
raw = _new_session_metadata_builder("abc123")
raw.update(overrides)
return dict(_finalize_session_metadata(raw))
def _valid_payload(**overrides: Any) -> dict[str, Any]:
base: dict[str, Any] = {
"session_id": "abc123",
"title": "Test Session",
"messages": [{"role": "user", "text": "hello"}],
"metadata": _full_metadata(),
}
base.update(overrides)
return base
class TestValidateSessionDict:
def test_missing_session_id(self):
payload = _valid_payload()
del payload["session_id"]
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(payload)
assert exc_info.value.path == "session_id"
def test_wrong_type_session_id(self):
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(session_id=123))
assert exc_info.value.path == "session_id"
def test_null_session_id(self):
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(session_id=None))
assert exc_info.value.path == "session_id"
assert exc_info.value.detail == "must not be null"
def test_null_role_in_message(self):
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(messages=[{"role": None, "text": "x"}]))
assert exc_info.value.path == "messages[0].role"
def test_missing_role_in_message(self):
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(messages=[{"text": "no role key"}]))
assert exc_info.value.path == "messages[0].role"
def test_metadata_not_dict(self):
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(metadata="not-a-dict"))
assert exc_info.value.path == "metadata"
def test_metadata_missing_session_id(self):
metadata = _full_metadata()
del metadata["session_id"]
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(metadata=metadata))
assert exc_info.value.path == "metadata.session_id"
def test_metadata_missing_models_used(self):
metadata = _full_metadata()
del metadata["models_used"]
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(metadata=metadata))
assert exc_info.value.path == "metadata.models_used"
def test_metadata_missing_first_timestamp(self):
metadata = _full_metadata()
del metadata["first_timestamp"]
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(metadata=metadata))
assert exc_info.value.path == "metadata.first_timestamp"
def test_metadata_first_timestamp_null_allowed(self):
result = validate_session_dict(
_valid_payload(metadata=_full_metadata(first_timestamp=None))
)
assert result["metadata"]["first_timestamp"] is None
def test_metadata_models_used_requires_string_elements(self):
metadata = _full_metadata()
metadata["models_used"] = ["claude-sonnet", 42]
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(metadata=metadata))
assert exc_info.value.path == "metadata.models_used[1]"
def test_message_not_dict(self):
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(messages=["not-a-dict"]))
assert exc_info.value.path == "messages[0]"
def test_valid_payload_returns_session_dict(self):
result = validate_session_dict(_valid_payload())
assert result["session_id"] == "abc123"
assert result["messages"][0]["role"] == "user"
def test_invalid_role_in_message(self):
with pytest.raises(SessionValidationError) as exc_info:
validate_session_dict(_valid_payload(messages=[{"role": "custom", "text": "x"}]))
assert exc_info.value.path == "messages[0].role"
assert "custom" in exc_info.value.detail
class TestParseSessionValidationRegression:
def test_session_minimal_fixture_unchanged(self):
path = os.path.join(FIXTURES, "session_minimal.jsonl")
session = parse_session(path)
assert session["session_id"] == "session_minimal"
assert session["title"] == "Hello from integration fixture"
assert len(session["messages"]) == 2
assert session["messages"][0]["role"] == "user"
assert session["messages"][1]["role"] == "assistant"