Files
Jyotisha/tests/test_flexible_birth_time_profile.py
T
2026-09-04 02:11:57 +08:00

87 lines
3.1 KiB
Python

#!/usr/bin/env python3
"""Focused contracts for unresolved birth-time candidate profiles."""
from __future__ import annotations
import json
import os
import sys
import pytest
SCRIPTS = os.path.join(os.path.dirname(__file__), "..", "scripts")
if SCRIPTS not in sys.path:
sys.path.insert(0, SCRIPTS)
from flexible_birth_time_profile import ( # noqa: E402
FlexibleBirthTimeProfileError,
build_flexible_birth_time_profile,
)
def _candidate(index: int, count: int) -> dict:
candidate_time = f"08:{index:02d}"
return {
"candidate_id": f"fictional-{index}",
"candidate_time": candidate_time,
"evidence": {
"D1.ascendant": "Aries",
"D10.ascendant": "Capricorn" if index < count - 1 else "Aquarius",
},
"trace": [{"kind": "fictional_candidate", "reference": f"fixture://{candidate_time}"}],
}
@pytest.mark.parametrize("count", [2, 15])
def test_profile_supports_two_to_fifteen_candidates_with_real_minute_variation(count: int) -> None:
candidates = [_candidate(index, count) for index in range(count)]
profile = build_flexible_birth_time_profile(
candidates,
source_reference={"review_id": "fictional-review"},
)
reversed_profile = build_flexible_birth_time_profile(
list(reversed(candidates)),
source_reference={"review_id": "fictional-review"},
)
assert profile == reversed_profile
assert profile["birth_time_window"]["candidate_count"] == count
assert profile["stable_evidence"] == {"D1.ascendant": "Aries"}
assert set(profile["sensitive_evidence"]) == {"D10.ascendant"}
for minute_values in profile["sensitive_evidence"].values():
assert len({json.dumps(value, sort_keys=True) for value in minute_values.values()}) > 1
@pytest.mark.parametrize("count", [1, 16])
def test_profile_rejects_candidate_counts_outside_two_to_fifteen(count: int) -> None:
with pytest.raises(FlexibleBirthTimeProfileError, match="candidate_count_must_be_two_to_fifteen"):
build_flexible_birth_time_profile(
[_candidate(index, max(count, 2)) for index in range(count)],
source_reference={"review_id": "fictional-review"},
)
@pytest.mark.parametrize("status", ["approved", "confirmed"])
def test_profile_rejects_approved_or_confirmed_source_reference(status: str) -> None:
with pytest.raises(FlexibleBirthTimeProfileError, match="approved_or_confirmed_source_reference_forbidden"):
build_flexible_birth_time_profile(
[_candidate(0, 2), _candidate(1, 2)],
source_reference={"review_id": "fictional-review", "status": status},
)
@pytest.mark.parametrize(
"field",
["approved_birth_time", "final_birth_time", "winner", "approval", "approval_authority"],
)
def test_profile_rejects_birth_minute_authority_fields(field: str) -> None:
candidates = [_candidate(0, 2), _candidate(1, 2)]
candidates[0]["evidence"][field] = "08:00"
with pytest.raises(FlexibleBirthTimeProfileError, match="candidate_window_authority_forbidden"):
build_flexible_birth_time_profile(
candidates,
source_reference={"review_id": "fictional-review"},
)