You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
mirosociety/backend/tests/test_census.py

116 lines
4.3 KiB

"""Tests for CensusService FIPS resolution and DemographicProfile model."""
from __future__ import annotations
import pytest
from app.models.demographics import (
AgeDistribution,
DemographicProfile,
EthnicityDistribution,
IncomeDistribution,
OccupationDistribution,
)
from app.services.census import CensusService
@pytest.fixture
def service():
return CensusService(llm=None)
# ── FIPS resolution ──────────────────────────────────────────────────────────
class TestResolveFips:
def test_known_city_san_francisco(self, service):
result = service._resolve_fips("san francisco", "ca")
assert result == ("06", "67000")
def test_known_city_new_york(self, service):
result = service._resolve_fips("new york", "ny")
assert result == ("36", "51000")
def test_known_city_chicago(self, service):
result = service._resolve_fips("chicago", "il")
assert result == ("17", "14000")
def test_unknown_city_returns_none(self, service):
result = service._resolve_fips("nonexistent city", "zz")
assert result is None
def test_unknown_city_no_state_returns_none(self, service):
result = service._resolve_fips("timbuktu")
assert result is None
def test_case_insensitive_upper(self, service):
result = service._resolve_fips("San Francisco", "CA")
assert result == ("06", "67000")
def test_case_insensitive_mixed(self, service):
result = service._resolve_fips("NEW YORK", "NY")
assert result == ("36", "51000")
def test_case_insensitive_no_state(self, service):
result = service._resolve_fips("Seattle")
assert result == ("53", "63000")
def test_portland_disambiguated_oregon(self, service):
result = service._resolve_fips("portland", "or")
assert result == ("41", "59000")
def test_portland_disambiguated_maine(self, service):
result = service._resolve_fips("portland", "me")
assert result == ("23", "60545")
def test_whitespace_stripped(self, service):
result = service._resolve_fips(" boston ", " ma ")
assert result == ("25", "07000")
# ── DemographicProfile model ────────────────────────────────────────────────
class TestDemographicProfile:
def test_full_construction(self):
profile = DemographicProfile(
city_name="Test City",
state="TX",
population=500000,
age=[AgeDistribution(bracket="18_24", percentage=12.5)],
income=[IncomeDistribution(bracket="50k_75k", percentage=22.0)],
occupations=[OccupationDistribution(category="service", percentage=18.3)],
ethnicity=[EthnicityDistribution(group="white", percentage=55.0)],
median_household_income=65000,
poverty_rate=14.2,
unemployment_rate=5.1,
homeownership_rate=58.0,
median_rent=1200,
rent_burden_rate=42.0,
college_education_rate=33.5,
median_age=34.7,
city_character="A vibrant test city",
)
assert profile.city_name == "Test City"
assert profile.population == 500000
assert len(profile.age) == 1
assert profile.age[0].bracket == "18_24"
assert profile.median_household_income == 65000
assert profile.city_character == "A vibrant test city"
def test_defaults(self):
profile = DemographicProfile(
city_name="Minimal",
state="CA",
population=1000,
)
assert profile.age == []
assert profile.income == []
assert profile.occupations == []
assert profile.ethnicity == []
assert profile.median_household_income == 0
assert profile.poverty_rate == 0.0
assert profile.unemployment_rate == 0.0
assert profile.homeownership_rate == 0.0
assert profile.median_rent == 0
assert profile.rent_burden_rate == 0.0
assert profile.college_education_rate == 0.0
assert profile.median_age == 0.0
assert profile.city_character == ""