voting-app/tests/unit/test_cache.py
2026-05-15 15:16:18 -05:00

298 lines
7.9 KiB
Python

"""Test SQLite cache operations."""
from __future__ import annotations
import os
import tempfile
from datetime import date
import pytest
from src.cache import Cache
from src.models import Bill, Legislator, Summary, Vote
@pytest.fixture
def cache() -> Cache:
fd, path = tempfile.mkstemp(suffix=".db")
c = Cache(path)
yield c
c.close()
os.close(fd)
os.unlink(path)
# --- Legislators ---
def test_save_and_get_legislator(cache: Cache):
leg = Legislator(
id="L001",
first_name="John",
last_name="Doe",
full_name="John Doe",
party="Democrat",
state="CA",
chamber="Senate",
in_office=True,
start_date=date(2025, 1, 3),
end_date=None,
)
cache.save_legislator(leg)
fetched = cache.get_legislator("L001")
assert fetched is not None
assert fetched.id == "L001"
assert fetched.full_name == "John Doe"
assert fetched.party == "Democrat"
assert fetched.start_date == date(2025, 1, 3)
assert fetched.end_date is None
def test_get_missing_legislator(cache: Cache):
assert cache.get_legislator("MISSING") is None
def test_search_legislators(cache: Cache):
cache.save_legislator(
Legislator(
id="L001",
first_name="John",
last_name="Doe",
full_name="John Doe",
party="Democrat",
state="CA",
chamber="Senate",
)
)
cache.save_legislator(
Legislator(
id="L002",
first_name="Jane",
last_name="Smith",
full_name="Jane Smith",
party="Republican",
state="NY",
chamber="House",
)
)
results = cache.search_legislators("John")
assert len(results) == 1
assert results[0].full_name == "John Doe"
results = cache.search_legislators("Smith")
assert len(results) == 1
assert results[0].last_name == "Smith"
def test_legislator_retired(cache: Cache):
leg = Legislator(
id="M000355",
first_name="Mitch",
last_name="McConnell",
full_name="Mitch McConnell",
party="Republican",
state="KY",
chamber="Senate",
in_office=False,
start_date=date(1985, 1, 3),
end_date=date(2025, 12, 31),
)
cache.save_legislator(leg)
fetched = cache.get_legislator("M000355")
assert fetched is not None
assert fetched.in_office is False
assert fetched.start_date == date(1985, 1, 3)
assert fetched.end_date == date(2025, 12, 31)
def test_legislator_update(cache: Cache):
"""Updating a legislator preserves all fields."""
leg = Legislator(
id="L001",
first_name="John",
last_name="Doe",
full_name="John Doe",
party="Democrat",
state="CA",
chamber="Senate",
start_date=date(2025, 1, 3),
end_date=None,
)
cache.save_legislator(leg)
leg.party = "Independent"
leg.in_office = False
leg.end_date = date(2027, 12, 31)
cache.save_legislator(leg)
fetched = cache.get_legislator("L001")
assert fetched.party == "Independent"
assert fetched.in_office is False
assert fetched.end_date == date(2027, 12, 31)
assert fetched.start_date == date(2025, 1, 3)
# --- Bills ---
def test_save_and_get_bill(cache: Cache):
bill = Bill(bill_id="B100", title="Test Bill", subject="Education", text="Full text", enacted=True)
cache.save_bill(bill)
fetched = cache.get_bill("B100")
assert fetched is not None
assert fetched.title == "Test Bill"
assert fetched.subject == "Education"
assert fetched.enacted is True
def test_get_missing_bill(cache: Cache):
assert cache.get_bill("MISSING") is None
# --- Votes ---
def test_save_and_get_vote(cache: Cache):
cache.save_legislator(
Legislator(
id="L001",
first_name="John",
last_name="Doe",
full_name="John Doe",
party="Democrat",
state="CA",
chamber="Senate",
)
)
vote = Vote(legislator_id="L001", roll_call_id="RC001", vote_type="Yea", bill_id="B100", bill_title="Test Bill")
cache.save_vote(vote)
votes = cache.get_votes("L001")
assert len(votes) == 1
assert votes[0].vote_type == "Yea"
def test_save_multiple_votes(cache: Cache):
cache.save_legislator(
Legislator(
id="L001",
first_name="John",
last_name="Doe",
full_name="John Doe",
party="Democrat",
state="CA",
chamber="Senate",
)
)
cache.save_votes(
[
Vote(legislator_id="L001", roll_call_id="RC001", vote_type="Yea", bill_id="B100", bill_title="Bill A"),
Vote(legislator_id="L001", roll_call_id="RC002", vote_type="Nay", bill_id="B101", bill_title="Bill B"),
]
)
votes = cache.get_votes("L001")
assert len(votes) == 2
def test_vote_duplicate_ignored(cache: Cache):
"""INSERT OR IGNORE prevents duplicate votes."""
cache.save_legislator(
Legislator(
id="L001",
first_name="John",
last_name="Doe",
full_name="John Doe",
party="Democrat",
state="CA",
chamber="Senate",
)
)
vote = Vote(legislator_id="L001", roll_call_id="RC001", vote_type="Yea", bill_id="B100", bill_title="Test Bill")
cache.save_vote(vote)
cache.save_vote(vote)
votes = cache.get_votes("L001")
assert len(votes) == 1
# --- Summaries ---
def test_save_and_get_summary(cache: Cache):
cache.save_bill(Bill(bill_id="B100", title="Test Bill", subject="Education"))
summary = Summary(
bill_id="B100",
summary_text="This bill does X.",
key_measures=["Measure A", "Measure B"],
model_name="gpt-oss",
)
cache.save_summary(summary)
fetched = cache.get_summary("B100")
assert fetched is not None
assert fetched.summary_text == "This bill does X."
assert fetched.key_measures == ["Measure A", "Measure B"]
assert fetched.model_name == "gpt-oss"
def test_get_missing_summary(cache: Cache):
assert cache.get_summary("MISSING") is None
# --- Voting Record ---
def test_voting_record(cache: Cache):
cache.save_legislator(
Legislator(
id="L001",
first_name="John",
last_name="Doe",
full_name="John Doe",
party="Democrat",
state="CA",
chamber="Senate",
)
)
cache.save_bill(Bill(bill_id="B100", title="Test Bill", subject="Education"))
cache.save_vote(
Vote(legislator_id="L001", roll_call_id="RC001", vote_type="Yea", bill_id="B100", bill_title="Test Bill")
)
records, total = cache.get_voting_record("L001")
assert len(records) == 1
assert total == 1
assert records[0]["vote_type"] == "Yea"
assert records[0]["bill_title"] == "Test Bill"
def test_voting_record_empty(cache: Cache):
records, total = cache.get_voting_record("MISSING")
assert records == []
assert total == 0
def test_voting_record_pagination(cache: Cache):
cache.save_legislator(
Legislator(
id="L001",
first_name="John",
last_name="Doe",
full_name="John Doe",
party="Democrat",
state="CA",
chamber="Senate",
)
)
cache.save_votes(
[
Vote(legislator_id="L001", roll_call_id=f"RC{i}", vote_type="Yea", bill_id=f"B{i}", bill_title=f"Bill {i}")
for i in range(10)
]
)
records, total = cache.get_voting_record("L001", limit=3, offset=0)
assert len(records) == 3
assert total == 10
records, total = cache.get_voting_record("L001", limit=3, offset=3)
assert len(records) == 3
records, total = cache.get_voting_record("L001", limit=3, offset=9)
assert len(records) == 1