forked from ChelseaKR/perimeter
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_artifacts_and_pages.py
More file actions
216 lines (167 loc) · 7.31 KB
/
Copy pathtest_artifacts_and_pages.py
File metadata and controls
216 lines (167 loc) · 7.31 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
"""Determinism, the fixture flag, and what the pages are allowed to print."""
from __future__ import annotations
import json
import re
from pathlib import Path
import pytest
from perimeter.cli import build_site, main
from perimeter.coverage import (
DinsReport,
PerimeterReport,
dins_report,
perimeter_report,
)
from perimeter.dins import load_inspections
from perimeter.perimeters import load_perimeters
from perimeter.render import dins_page, index_page, perimeters_page
ROOT = Path(__file__).resolve().parents[1]
FIXTURES = ROOT / "fixtures"
FRAP_FIXTURE = FIXTURES / "frap_perimeters.sample.json"
DINS_FIXTURE = FIXTURES / "dins_postfire.sample.json"
@pytest.fixture(scope="module")
def frap() -> PerimeterReport:
return perimeter_report(load_perimeters(FRAP_FIXTURE))
@pytest.fixture(scope="module")
def dins() -> DinsReport:
return dins_report(load_inspections(DINS_FIXTURE))
@pytest.fixture(scope="module")
def built(tmp_path_factory: pytest.TempPathFactory) -> Path:
out = tmp_path_factory.mktemp("site")
build_site(
perimeters_source=FRAP_FIXTURE,
dins_source=DINS_FIXTURE,
out_dir=out,
is_fixture=True,
)
return out
def test_the_same_inputs_produce_byte_identical_output(tmp_path: Path) -> None:
def build_into(name: str) -> dict[str, bytes]:
out = tmp_path / name
written = build_site(
perimeters_source=FRAP_FIXTURE,
dins_source=DINS_FIXTURE,
out_dir=out,
is_fixture=True,
)
return {path.name: path.read_bytes() for path in written}
assert build_into("first") == build_into("second")
def test_a_fixture_build_publishes_no_acquisition_facts(built: Path) -> None:
"""Fixture output must never pass itself off as CAL FIRE's real files."""
for name in ("perimeters-coverage.json", "dins-coverage.json"):
payload = json.loads((built / "data" / name).read_text(encoding="utf-8"))
assert payload["is_fixture"] is True
source = payload["source"]
for key in (
"retrieved",
"version",
"acquired_record_count",
"acquired_bytes",
"acquired_sha256",
):
assert source[key] is None, f"{name}.{key}"
def test_a_real_build_publishes_the_reviewed_acquisition_facts(tmp_path: Path) -> None:
build_site(
perimeters_source=FRAP_FIXTURE,
dins_source=DINS_FIXTURE,
out_dir=tmp_path,
is_fixture=False,
)
payload = json.loads(
(tmp_path / "data" / "perimeters-coverage.json").read_text(encoding="utf-8")
)
assert payload["is_fixture"] is False
assert payload["source"]["retrieved"] == "2026-08-07"
assert len(payload["source"]["acquired_sha256"]) == 64
def test_no_wall_clock_leaks_into_an_artifact(built: Path) -> None:
"""Any date in the payload must be a reviewed constant, not today."""
text = (built / "data" / "perimeters-coverage.json").read_text(encoding="utf-8")
payload = json.loads(text)
assert payload["source"]["retrieved"] is None
for match in re.findall(r"\d{4}-\d{2}-\d{2}", text):
pytest.fail(f"unexpected date in a fixture artifact: {match}")
def test_every_field_publishes_all_three_counts(built: Path) -> None:
payload = json.loads((built / "data" / "dins-coverage.json").read_text("utf-8"))
assert payload["fields"]
for field in payload["fields"]:
for key in ("present", "explicit_unknown", "not_recorded", "total"):
assert key in field, f"{field['name']} is missing {key}"
assert (
field["present"] + field["explicit_unknown"] + field["not_recorded"]
== field["total"]
)
def test_the_incident_matrix_documents_its_own_ordering(built: Path) -> None:
payload = json.loads((built / "data" / "dins-coverage.json").read_text("utf-8"))
assert payload["field_state_order"] == [
"present",
"explicit_unknown",
"not_recorded",
]
incident = payload["incidents_detail"][0]
assert len(incident["fields"]["DAMAGE"]) == 3
def test_pages_are_written(built: Path) -> None:
for name in ("index.html", "perimeters.html", "dins.html"):
assert (built / name).read_text(encoding="utf-8").startswith("<!doctype html>")
@pytest.mark.parametrize("name", ["index.html", "perimeters.html", "dins.html"])
def test_every_page_says_it_is_unofficial(built: Path, name: str) -> None:
text = built / name
assert "Not affiliated with or endorsed by CAL FIRE" in text.read_text("utf-8")
@pytest.mark.parametrize("name", ["index.html", "perimeters.html", "dins.html"])
def test_a_fixture_page_says_so_on_its_face(built: Path, name: str) -> None:
assert "Fixture build" in (built / name).read_text(encoding="utf-8")
def test_a_page_quotes_the_publisher_rather_than_paraphrasing(
frap: PerimeterReport, dins: DinsReport
) -> None:
perimeters_html = perimeters_page(frap, is_fixture=True)
dins_html = dins_page(dins, is_fixture=True)
assert "it is still incomplete" in perimeters_html
assert "Attributes with null values could not be determined" in dins_html
def test_a_share_over_nothing_is_printed_as_words_not_as_a_number() -> None:
"""An empty report must not render 0% anywhere a rate does not exist."""
html = perimeters_page(perimeter_report([]), is_fixture=True)
assert "no records" in html
assert "0.0%" not in html
def test_the_pages_carry_no_em_dashes(built: Path) -> None:
for path in sorted(built.glob("*.html")):
assert "—" not in path.read_text(encoding="utf-8"), path.name
def test_the_index_names_all_three_states(
frap: PerimeterReport, dins: DinsReport
) -> None:
html = index_page(frap, dins, is_fixture=True)
for label in ("Recorded value", "Recorded as unknown", "Empty cell"):
assert label in html
def test_the_cli_builds_a_site(tmp_path: Path) -> None:
code = main(
[
"--perimeters",
str(FRAP_FIXTURE),
"--dins",
str(DINS_FIXTURE),
"--out",
str(tmp_path / "site"),
"--fixture",
]
)
assert code == 0
assert (tmp_path / "site" / "index.html").exists()
assert (tmp_path / "site" / "data" / "dins-coverage.json").exists()
def test_a_bar_over_nothing_is_words_rather_than_an_empty_bar() -> None:
from perimeter.render import state_bar
assert "no records" in state_bar(0, 0, 0)
assert '<i class="b-present"' in state_bar(1, 0, 0)
def test_the_damage_table_labels_the_two_non_value_states() -> None:
"""Neither state occurs in the published file today; the page must still name
them correctly rather than printing a raw key if one ever appears."""
from dataclasses import replace
report = dins_report(load_inspections(DINS_FIXTURE))
with_gaps = replace(
report, damage={**report.damage, "not_recorded": 3, "explicit_unknown": 2}
)
html = dins_page(with_gaps, is_fixture=True)
assert "Empty cell" in html
assert "A marker was recorded in place of a damage value." in html
assert "not_recorded<" not in html
def test_a_bar_segment_over_nothing_is_zero_width_not_a_division_error() -> None:
"""Defensive: state_bar already guards this, so the guard needs its own test."""
from perimeter.render import _width
assert _width(0, 0) == "0"
assert _width(1, 2) == "50.00"