All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m11s
- Run tests for all 10 services via per-service pytest subprocesses - Group results by service with section headers - Clickable summary cards filter by outcome (passed/failed/errors/skipped) - Service filter nav using ~nav-link buttons in menu bar - Full menu integration: ~header-row + ~header-child + ~menu-row - Show logo image via cart-mini rendering - Mount full service directories in docker-compose for test access - Add 24 unit test files across 9 services Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
"""Unit tests for listings parsing utilities."""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from market.scrape.listings import (
|
|
parse_total_pages_from_text,
|
|
_first_from_srcset,
|
|
_dedupe_preserve_order_by,
|
|
_filename_key,
|
|
)
|
|
|
|
|
|
class TestParseTotalPages:
|
|
def test_standard(self):
|
|
assert parse_total_pages_from_text("Showing 36 of 120") == 4
|
|
|
|
def test_exact_fit(self):
|
|
assert parse_total_pages_from_text("Showing 36 of 36") == 1
|
|
|
|
def test_partial_page(self):
|
|
assert parse_total_pages_from_text("Showing 36 of 37") == 2
|
|
|
|
def test_no_match(self):
|
|
assert parse_total_pages_from_text("no data") is None
|
|
|
|
def test_case_insensitive(self):
|
|
# shown=12 is in {12,24,36} so per_page=36, ceil(60/36)=2
|
|
assert parse_total_pages_from_text("showing 12 of 60") == 2
|
|
|
|
def test_small_shown(self):
|
|
# shown=10, not in {12,24,36}, so per_page=10
|
|
assert parse_total_pages_from_text("Showing 10 of 100") == 10
|
|
|
|
|
|
class TestFirstFromSrcset:
|
|
def test_single_entry(self):
|
|
assert _first_from_srcset("img.jpg 1x") == "img.jpg"
|
|
|
|
def test_multiple_entries(self):
|
|
assert _first_from_srcset("a.jpg 1x, b.jpg 2x") == "a.jpg"
|
|
|
|
def test_empty(self):
|
|
assert _first_from_srcset("") is None
|
|
|
|
def test_none(self):
|
|
assert _first_from_srcset(None) is None
|
|
|
|
|
|
class TestDedupePreserveOrder:
|
|
def test_no_dupes(self):
|
|
result = _dedupe_preserve_order_by(["a", "b", "c"], key=str)
|
|
assert result == ["a", "b", "c"]
|
|
|
|
def test_removes_dupes(self):
|
|
result = _dedupe_preserve_order_by(["a", "b", "a"], key=str)
|
|
assert result == ["a", "b"]
|
|
|
|
def test_empty_strings_skipped(self):
|
|
result = _dedupe_preserve_order_by(["a", "", "b"], key=str)
|
|
assert result == ["a", "b"]
|
|
|
|
def test_preserves_order(self):
|
|
result = _dedupe_preserve_order_by(["c", "b", "a", "b"], key=str)
|
|
assert result == ["c", "b", "a"]
|
|
|
|
|
|
class TestFilenameKey:
|
|
def test_basic(self):
|
|
assert _filename_key("https://img.com/photos/pic.jpg") == "img.com:pic.jpg"
|
|
|
|
def test_trailing_slash(self):
|
|
k = _filename_key("https://img.com/photos/")
|
|
assert k == "img.com:photos"
|
|
|
|
def test_case_insensitive(self):
|
|
k = _filename_key("https://IMG.COM/PIC.JPG")
|
|
assert k == "img.com:pic.jpg"
|