This commit is contained in:
Ole
2026-05-16 16:14:01 +00:00
parent 1399f61c1a
commit 71cc9c86a0
18 changed files with 1797 additions and 15 deletions
+172
View File
@@ -0,0 +1,172 @@
"""Tests for formatting module."""
import pytest
from finn_eiendom import formatting
def test_render_ad_json():
"""Test rendering ad as JSON."""
ad = {
"finnkode": "123456",
"title": "Nice apartment",
"address": "Hovedstreet 1",
"asking_price": 5000000,
"area_m2": 80,
}
result = formatting.render_ad(ad, "json")
assert "123456" in result
assert "Nice apartment" in result
assert isinstance(result, str)
def test_render_ad_markdown():
"""Test rendering ad as Markdown."""
ad = {
"finnkode": "123456",
"title": "Nice apartment",
"address": "Hovedstreet 1",
"asking_price": 5000000,
"area_m2": 80,
}
result = formatting.render_ad(ad, "markdown")
assert "Nice apartment" in result
assert "Hovedstreet 1" in result
assert "#" in result # Markdown headers
def test_render_shortlist_json():
"""Test rendering shortlist as JSON."""
data = {
"shortlist": [
{
"finnkode": "1",
"title": "Ad 1",
"address": "Street 1",
"asking_price": 5000000,
"area_m2": 80,
},
{
"finnkode": "2",
"title": "Ad 2",
"address": "Street 2",
"asking_price": 4500000,
"area_m2": 75,
},
]
}
result = formatting.render_shortlist(data, "json")
assert "Ad 1" in result
assert "Ad 2" in result
def test_render_shortlist_markdown():
"""Test rendering shortlist as Markdown."""
data = {
"shortlist": [
{
"finnkode": "1",
"title": "Ad 1",
"address": "Street 1",
"asking_price": 5000000,
"area_m2": 80,
},
]
}
result = formatting.render_shortlist(data, "markdown")
assert "Ad 1" in result
assert "Street 1" in result
def test_render_shortlist_table():
"""Test rendering shortlist as table."""
data = {
"shortlist": [
{
"finnkode": "1",
"title": "Ad 1",
"address": "Street 1",
"asking_price": 5000000,
"area_m2": 80,
},
]
}
result = formatting.render_shortlist(data, "table")
assert "|" in result # Table format
def test_render_comparison():
"""Test rendering comparison."""
data = {
"listings": [
{
"finnkode": "1",
"title": "Ad 1",
"address": "Street 1",
"asking_price": 5000000,
"area_m2": 80,
},
{
"finnkode": "2",
"title": "Ad 2",
"address": "Street 2",
"asking_price": 4500000,
"area_m2": 75,
},
]
}
result = formatting.render_comparison(data, "markdown")
assert "Comparison" in result
assert "Ad 1" in result
assert "Ad 2" in result
def test_render_diff():
"""Test rendering diff."""
data = {
"new_ads": [
{
"title": "New Ad",
"address": "New Street",
"asking_price": 5000000,
},
],
"removed_ads": [],
"changed_ads": [],
}
result = formatting.render_diff(data, "markdown")
assert "New" in result
assert "New Ad" in result
def test_render_cache_stats():
"""Test rendering cache stats."""
data = {
"total_finn_ads": 100,
"total_eiendom_units": 50,
"total_search_runs": 10,
"cache_size_mb": 25.5,
"last_updated": "2024-01-01",
}
result = formatting.render_cache_stats(data, "json")
assert "100" in result
assert "50" in result
def test_format_validation():
"""Test that invalid formats raise ValueError."""
with pytest.raises(ValueError):
formatting.render_ad({}, "invalid")
def test_render_unit():
"""Test rendering Eiendom unit."""
unit = {
"unit_code": "code123",
"address": "Hovedstreet 1",
"rooms": 3,
"estimated_selling_price": 5000000,
}
result = formatting.render_unit(unit, "markdown")
assert "Hovedstreet 1" in result
assert "3" in result
+265
View File
@@ -0,0 +1,265 @@
"""Tests for Pydantic models in finn_eiendom.models."""
import json
from datetime import UTC, datetime
from finn_eiendom.models import (
EiendomUnit,
FinnAd,
FinnSearchCard,
SimilarUnit,
UnitVector,
)
def test_finn_search_card_json_roundtrip():
"""Test JSON roundtrip for FinnSearchCard model."""
data = {
"finnkode": "123456789",
"url": "https://www.finn.no/realestate/homes/ad.html?finnkode=123456789",
"title": "Beautiful apartment in Oslo",
"address": "Karl Johans gate 1",
"area_m2": 80,
"asking_price": 5000000,
"total_price": 5200000,
"common_costs": 2000,
"property_type": "APARTMENT",
"ownership_type": "FREEHOLD",
"bedrooms": 2,
"floor": "3/5",
"broker_company": "Estate AS",
}
# Create model instance
model = FinnSearchCard(**data)
# Convert to JSON
json_str = model.model_dump_json()
# Parse JSON back to dict
parsed_data = json.loads(json_str)
# Create new instance from parsed data
model_from_json = FinnSearchCard(**parsed_data)
# Assert they're equal
assert model == model_from_json
def test_finn_ad_json_roundtrip():
"""Test JSON roundtrip for FinnAd model."""
now = datetime.now(UTC)
data = {
"finnkode": "123456789",
"url": "https://www.finn.no/realestate/homes/ad.html?finnkode=123456789",
"title": "Beautiful apartment in Oslo",
"address": "Karl Johans gate 1",
"postal_area": "0150",
"district": "Sentrum",
"property_type": "APARTMENT",
"ownership_type": "FREEHOLD",
"asking_price": 5000000,
"total_price": 5200000,
"shared_debt": 100000,
"common_costs": 2000,
"municipal_fee": 500,
"other_fees": 300,
"area_m2": 80,
"rooms": 3,
"bedrooms": 2,
"floor": "3/5",
"construction_year": 2000,
"energy_rating": "C",
"heating": "FJERNVARME",
"has_balcony": True,
"has_terrace": False,
"has_elevator": True,
"has_parking": False,
"has_garage": False,
"listing_description": "A lovely apartment with great views",
"broker_name": "John Doe",
"broker_company": "Estate AS",
"first_seen_at": now,
"last_seen_at": now,
"detail_fetched_at": now,
"eiendom_unit_code": "EI-987654321",
}
# Create model instance
model = FinnAd(**data)
# Convert to JSON
json_str = model.model_dump_json()
# Parse JSON back to dict
parsed_data = json.loads(json_str)
# Create new instance from parsed data
model_from_json = FinnAd(**parsed_data)
# Assert they're equal
assert model == model_from_json
def test_eiendom_unit_json_roundtrip():
"""Test JSON roundtrip for EiendomUnit model."""
now = datetime.now(UTC)
data = {
"unit_code": "EI-987654321",
"address": "Karl Johans gate 1",
"lat": 59.9139,
"lng": 10.7522,
"property_type": "APARTMENT",
"floor": 3,
"rooms": 3,
"construction_year": 2000,
"usable_area": 80,
"estimated_selling_price": 5500000,
"estimated_selling_price_lower": 5200000,
"estimated_selling_price_upper": 5800000,
"listing_price": 5000000,
"listing_sqm_price": 62500,
"common_costs": 2000,
"days_on_market": 45,
"sale_status": "FOR_SALE",
"market_placement_score": "GOOD",
"unit_vector": "base64encodedvector===",
"fetched_at": now,
}
# Create model instance
model = EiendomUnit(**data)
# Convert to JSON
json_str = model.model_dump_json()
# Parse JSON back to dict
parsed_data = json.loads(json_str)
# Create new instance from parsed data
model_from_json = EiendomUnit(**parsed_data)
# Assert they're equal
assert model == model_from_json
def test_similar_unit_json_roundtrip():
"""Test JSON roundtrip for SimilarUnit model."""
data = {
"unit_code": "EI-123456789",
"address": "Karl Johans gate 2",
"lat": 59.9140,
"lng": 10.7523,
"property_type": "APARTMENT",
"floor": 4,
"rooms": 3,
"construction_year": 2005,
"usable_area": 90,
"listing_price": 5800000,
"selling_price": 5700000,
"shared_debt": 120000,
"common_costs": 2200,
"sqm_price": 63333,
"days_on_market": 30,
"sale_status": "SOLD",
"finalized_at": datetime.now(UTC),
"listing_status": "RECENTLY_SOLD",
}
# Create model instance
model = SimilarUnit(**data)
# Convert to JSON
json_str = model.model_dump_json()
# Parse JSON back to dict
parsed_data = json.loads(json_str)
# Create new instance from parsed data
model_from_json = SimilarUnit(**parsed_data)
# Assert they're equal
assert model == model_from_json
def test_unit_vector_json_roundtrip():
"""Test JSON roundtrip for UnitVector model."""
data = {
"lon": 10.7522,
"lat": 59.9139,
"ptype": "APARTMENT",
"floor": 3,
"rooms": 3,
"built": 2000,
"area": 80,
"price": 5000000,
}
# Create model instance
model = UnitVector(**data)
# Convert to JSON
json_str = model.model_dump_json()
# Parse JSON back to dict
parsed_data = json.loads(json_str)
# Create new instance from parsed data
model_from_json = UnitVector(**parsed_data)
# Assert they're equal
assert model == model_from_json
def test_finn_ad_serializer_datetime():
"""Test that FinnAd datetime serialization works correctly."""
now = datetime.now(UTC)
data = {
"finnkode": "123456789",
"url": "https://www.finn.no/realestate/homes/ad.html?finnkode=123456789",
"first_seen_at": now,
"last_seen_at": now,
}
model = FinnAd(**data)
json_str = model.model_dump_json()
parsed_data = json.loads(json_str)
# Check that datetimes are serialized as ISO strings
assert isinstance(parsed_data["first_seen_at"], str)
assert isinstance(parsed_data["last_seen_at"], str)
assert "T" in parsed_data["first_seen_at"] # ISO format contains T
assert "Z" in parsed_data["first_seen_at"] or "+" in parsed_data["first_seen_at"] # TZ info
def test_eiendom_unit_serializer_datetime():
"""Test that EiendomUnit datetime serialization works correctly."""
now = datetime.now(UTC)
data = {
"unit_code": "EI-987654321",
"fetched_at": now,
}
model = EiendomUnit(**data)
json_str = model.model_dump_json()
parsed_data = json.loads(json_str)
# Check that datetimes are serialized as ISO strings
assert isinstance(parsed_data["fetched_at"], str)
assert "T" in parsed_data["fetched_at"] # ISO format contains T
assert "Z" in parsed_data["fetched_at"] or "+" in parsed_data["fetched_at"] # Timezone info
def test_similar_unit_serializer_datetime():
"""Test that SimilarUnit datetime serialization works correctly (handles None)."""
data = {
"unit_code": "EI-123456789",
"finalized_at": None, # This should serialize to null
}
model = SimilarUnit(**data)
json_str = model.model_dump_json()
parsed_data = json.loads(json_str)
# Check that None datetimes serialize to null
assert parsed_data["finalized_at"] is None