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
133
134
135
136
137
138
139
140
141
142
143"""Tests for AutoCorrection model."""
from datetime import datetime
import pytest
from src.shared.models.auto_correction import AutoCorrection
class TestAutoCorrection:
"""Tests for the AutoCorrection model."""
def test_create_auto_correction(self):
"""Test creating a basic auto correction."""
correction = AutoCorrection(
observation_id="obs-123",
search="## Introduction",
replace="## 1. Introduction",
justification="Adding section number",
confidence=0.98,
agent="structure",
)
assert correction.observation_id == "obs-123"
assert correction.search == "## Introduction"
assert correction.replace == "## 1. Introduction"
assert correction.confidence == 0.98
assert correction.agent == "structure"
assert correction.applied is False
assert correction.applied_at is None
assert correction.id # Auto-generated
def test_mark_applied(self):
"""Test marking a correction as applied."""
correction = AutoCorrection(
observation_id="obs-123",
search="old",
replace="new",
justification="test",
confidence=0.95,
agent="structure",
)
assert correction.applied is False
correction.mark_applied()
assert correction.applied is True
assert correction.applied_at is not None
assert isinstance(correction.applied_at, datetime)
def test_mark_applied_twice_raises(self):
"""Test that marking applied twice raises error."""
correction = AutoCorrection(
observation_id="obs-123",
search="old",
replace="new",
justification="test",
confidence=0.95,
agent="structure",
)
correction.mark_applied()
with pytest.raises(ValueError, match="already applied"):
correction.mark_applied()
def test_empty_replace_allowed(self):
"""Test that empty replace string is allowed (for deletions)."""
correction = AutoCorrection(
observation_id="obs-123",
search="delete me",
replace="",
justification="Removing unnecessary text",
confidence=0.99,
agent="typography",
)
assert correction.replace == ""
def test_search_must_not_be_empty(self):
"""Test that search string cannot be empty."""
with pytest.raises(ValueError):
AutoCorrection(
observation_id="obs-123",
search="",
replace="new",
justification="test",
confidence=0.95,
agent="structure",
)
def test_justification_must_not_be_empty(self):
"""Test that justification cannot be empty."""
with pytest.raises(ValueError):
AutoCorrection(
observation_id="obs-123",
search="old",
replace="new",
justification="",
confidence=0.95,
agent="structure",
)
def test_confidence_bounds(self):
"""Test that confidence must be between 0 and 1."""
with pytest.raises(ValueError):
AutoCorrection(
observation_id="obs-123",
search="old",
replace="new",
justification="test",
confidence=1.5,
agent="structure",
)
with pytest.raises(ValueError):
AutoCorrection(
observation_id="obs-123",
search="old",
replace="new",
justification="test",
confidence=-0.1,
agent="structure",
)
def test_json_serialization(self):
"""Test that AutoCorrection serializes to JSON correctly."""
correction = AutoCorrection(
observation_id="obs-123",
search="old",
replace="new",
justification="test",
confidence=0.95,
agent="structure",
page_num=3,
)
json_str = correction.model_dump_json()
assert "obs-123" in json_str
assert "structure" in json_str
# Deserialize and verify
restored = AutoCorrection.model_validate_json(json_str)
assert restored.observation_id == correction.observation_id
assert restored.confidence == correction.confidence