initial openlane project
This commit is contained in:
198
tests/test_mapper.py
Normal file
198
tests/test_mapper.py
Normal file
@@ -0,0 +1,198 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from openlane_scraper.openlane.mapper import (
|
||||
map_openlane_record,
|
||||
map_openlane_records,
|
||||
_parse_mileage,
|
||||
_parse_engine_volume_cc,
|
||||
_generate_slug,
|
||||
)
|
||||
|
||||
|
||||
class TestMapOpenLaneRecord(unittest.TestCase):
|
||||
def _sample_record(self, **overrides) -> dict:
|
||||
base = {
|
||||
"id": "12345",
|
||||
"make": "Toyota",
|
||||
"model": "Camry",
|
||||
"year": 2020,
|
||||
"mileage": 45000,
|
||||
"price": 18500,
|
||||
"color": "White",
|
||||
"body_type": "sedan",
|
||||
"transmission": "automatic",
|
||||
"drivetrain": "fwd",
|
||||
"vin": "1HGBH41JXMN109186",
|
||||
"url": "https://app.openlane.com/vehicles/12345",
|
||||
"images": [
|
||||
{"full": "https://img.openlane.com/1_full.jpg", "thumbnail": "https://img.openlane.com/1_thumb.jpg"},
|
||||
{"full": "https://img.openlane.com/2_full.jpg", "thumbnail": "https://img.openlane.com/2_thumb.jpg"},
|
||||
],
|
||||
}
|
||||
base.update(overrides)
|
||||
return base
|
||||
|
||||
def test_basic_mapping(self) -> None:
|
||||
record = self._sample_record()
|
||||
result = map_openlane_record(record)
|
||||
self.assertIsNotNone(result)
|
||||
self.assertEqual(result.brand, "TOYOTA")
|
||||
self.assertEqual(result.model, "CAMRY")
|
||||
self.assertEqual(result.year, 2020)
|
||||
self.assertEqual(result.price, 18500)
|
||||
self.assertEqual(result.mileage, 45000)
|
||||
self.assertEqual(result.color, "white")
|
||||
self.assertEqual(result.body_type, "SEDAN")
|
||||
self.assertEqual(result.gearbox, "AT")
|
||||
self.assertEqual(result.drive, "FWD")
|
||||
self.assertEqual(result.origin, "OPENLANE")
|
||||
self.assertEqual(result.origin_id, "openlane:12345")
|
||||
self.assertEqual(result.origin_url, "https://app.openlane.com/vehicles/12345")
|
||||
self.assertEqual(result.evaluation, "1HGBH41JXMN109186")
|
||||
self.assertEqual(len(result.images), 2)
|
||||
self.assertEqual(result.images[0].fullres_image, "https://img.openlane.com/1_full.jpg")
|
||||
self.assertEqual(result.images[0].preview_image, "https://img.openlane.com/1_thumb.jpg")
|
||||
|
||||
def test_missing_id_returns_none(self) -> None:
|
||||
record = {"make": "Toyota", "model": "Camry"}
|
||||
self.assertIsNone(map_openlane_record(record))
|
||||
|
||||
def test_missing_brand_returns_none(self) -> None:
|
||||
record = {"id": "123", "model": "Camry"}
|
||||
self.assertIsNone(map_openlane_record(record))
|
||||
|
||||
def test_missing_model_returns_none(self) -> None:
|
||||
record = {"id": "123", "make": "Toyota"}
|
||||
self.assertIsNone(map_openlane_record(record))
|
||||
|
||||
def test_vin_as_id_fallback(self) -> None:
|
||||
record = self._sample_record()
|
||||
del record["id"]
|
||||
record["vin"] = "WBAPH5C52BA012345"
|
||||
result = map_openlane_record(record)
|
||||
self.assertIsNotNone(result)
|
||||
self.assertEqual(result.origin_id, "openlane:WBAPH5C52BA012345")
|
||||
|
||||
def test_existing_openlane_prefix_is_normalized(self) -> None:
|
||||
record = self._sample_record(id="openlane:777")
|
||||
result = map_openlane_record(record)
|
||||
self.assertIsNotNone(result)
|
||||
self.assertEqual(result.origin_id, "openlane:777")
|
||||
|
||||
def test_whitespace_id_is_normalized(self) -> None:
|
||||
record = self._sample_record(id=" 888 ")
|
||||
result = map_openlane_record(record)
|
||||
self.assertIsNotNone(result)
|
||||
self.assertEqual(result.origin_id, "openlane:888")
|
||||
|
||||
def test_image_url_strings(self) -> None:
|
||||
record = self._sample_record(images=["https://a.com/1.jpg", "https://a.com/2.jpg"])
|
||||
result = map_openlane_record(record)
|
||||
self.assertEqual(len(result.images), 2)
|
||||
self.assertEqual(result.images[0].fullres_image, "https://a.com/1.jpg")
|
||||
|
||||
def test_image_deduplication(self) -> None:
|
||||
record = self._sample_record(images=[
|
||||
{"full": "https://a.com/same.jpg"},
|
||||
{"full": "https://a.com/same.jpg"},
|
||||
{"full": "https://a.com/other.jpg"},
|
||||
])
|
||||
result = map_openlane_record(record)
|
||||
self.assertEqual(len(result.images), 2)
|
||||
|
||||
def test_vehicle_images_api_format(self) -> None:
|
||||
record = self._sample_record(images=[
|
||||
{
|
||||
"url": "https://a.com/original.jpg",
|
||||
"large_resolution_url": "https://a.com/large.jpg",
|
||||
"low_resolution_url": "https://a.com/medium.jpg",
|
||||
}
|
||||
])
|
||||
result = map_openlane_record(record)
|
||||
self.assertEqual(len(result.images), 1)
|
||||
self.assertEqual(result.images[0].fullres_image, "https://a.com/original.jpg")
|
||||
self.assertEqual(result.images[0].preview_image, "https://a.com/medium.jpg")
|
||||
|
||||
def test_default_url_generation(self) -> None:
|
||||
record = self._sample_record()
|
||||
del record["url"]
|
||||
result = map_openlane_record(record)
|
||||
self.assertEqual(result.origin_url, "https://app.openlane.com/vehicles/12345")
|
||||
|
||||
def test_nested_vehicle_fields(self) -> None:
|
||||
record = {
|
||||
"id": "999",
|
||||
"vehicle": {
|
||||
"make": "BMW",
|
||||
"model": "X5",
|
||||
"year": 2022,
|
||||
"mileage": 10000,
|
||||
},
|
||||
}
|
||||
result = map_openlane_record(record)
|
||||
self.assertIsNotNone(result)
|
||||
self.assertEqual(result.brand, "BMW")
|
||||
self.assertEqual(result.model, "X5")
|
||||
self.assertEqual(result.year, 2022)
|
||||
|
||||
def test_map_records_filters_invalid(self) -> None:
|
||||
records = [
|
||||
self._sample_record(id="1"),
|
||||
{"no_id": True},
|
||||
self._sample_record(id="2"),
|
||||
]
|
||||
results = map_openlane_records(records)
|
||||
self.assertEqual(len(results), 2)
|
||||
|
||||
def test_sale_type_mapping(self) -> None:
|
||||
record = self._sample_record(sale_type="buy_now")
|
||||
result = map_openlane_record(record)
|
||||
self.assertEqual(result.selling_type, "STOCK")
|
||||
|
||||
record2 = self._sample_record(sale_type="tender")
|
||||
result2 = map_openlane_record(record2)
|
||||
self.assertEqual(result2.selling_type, "TENDER")
|
||||
|
||||
|
||||
class TestParseMileage(unittest.TestCase):
|
||||
def test_integer(self) -> None:
|
||||
self.assertEqual(_parse_mileage(45000), 45000)
|
||||
|
||||
def test_string_with_commas(self) -> None:
|
||||
self.assertEqual(_parse_mileage("45,000 miles"), 45000)
|
||||
|
||||
def test_none_returns_zero(self) -> None:
|
||||
self.assertEqual(_parse_mileage(None), 0)
|
||||
|
||||
def test_float(self) -> None:
|
||||
self.assertEqual(_parse_mileage(45000.5), 45000)
|
||||
|
||||
|
||||
class TestParseEngineVolume(unittest.TestCase):
|
||||
def test_liters_float(self) -> None:
|
||||
self.assertEqual(_parse_engine_volume_cc(2.5), 2500)
|
||||
|
||||
def test_cc_int(self) -> None:
|
||||
self.assertEqual(_parse_engine_volume_cc(2500), 2500)
|
||||
|
||||
def test_string_liters(self) -> None:
|
||||
self.assertEqual(_parse_engine_volume_cc("2.5L"), 2500)
|
||||
|
||||
def test_none(self) -> None:
|
||||
self.assertIsNone(_parse_engine_volume_cc(None))
|
||||
|
||||
|
||||
class TestGenerateSlug(unittest.TestCase):
|
||||
def test_basic(self) -> None:
|
||||
slug = _generate_slug(2020, "TOYOTA", "CAMRY", "openlane:123")
|
||||
self.assertEqual(slug, "2020-toyota-camry-openlane-123")
|
||||
|
||||
def test_no_year(self) -> None:
|
||||
slug = _generate_slug(None, "BMW", "X5", "openlane:456")
|
||||
self.assertEqual(slug, "bmw-x5-openlane-456")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user