Spaces:
Running
Running
| """Unit tests for per-platform list price fetching.""" | |
| from unittest.mock import AsyncMock, MagicMock | |
| import pytest | |
| from app.services.platform_pricing import ( | |
| PriceContext, | |
| extract_price_from_html, | |
| fetch_apple_books_price, | |
| fetch_google_books_price, | |
| fetch_listing_price, | |
| format_price, | |
| ) | |
| class TestFormatPrice: | |
| def test_usd(self): | |
| assert format_price(14.99, "USD") == "$14.99" | |
| def test_gbp(self): | |
| assert format_price(9.5, "GBP") == "£9.50" | |
| class TestExtractPriceFromHtml: | |
| def test_barnes_noble_json_price(self): | |
| html = '{"price": "14.99", "title": "Test"}' | |
| hit = extract_price_from_html("barnes_noble", html) | |
| assert hit is not None | |
| assert hit.formatted == "$14.99" | |
| def test_abebooks_itemprop(self): | |
| html = '<span itemprop="price" content="6.32">US$ 6.32</span>' | |
| hit = extract_price_from_html("abebooks", html) | |
| assert hit is not None | |
| assert hit.amount == 6.32 | |
| def test_amazon_us_offscreen(self): | |
| html = '<span class="a-offscreen">$15.99</span>' | |
| hit = extract_price_from_html("amazon", html) | |
| assert hit is not None | |
| assert hit.formatted == "$15.99" | |
| def test_amazon_international_currency(self): | |
| html = 'apex-pricetopay-accessibility-label"> PKR 275.24 with 94 percent' | |
| hit = extract_price_from_html("amazon", html) | |
| assert hit is not None | |
| assert "275.24" in hit.formatted | |
| def test_goodreads_no_price(self): | |
| html = "<html><body>Goodreads page</body></html>" | |
| assert extract_price_from_html("goodreads", html) is None | |
| class TestFetchApiPrices: | |
| async def test_google_books_isbn_fallback(self): | |
| client = AsyncMock() | |
| volume_resp = MagicMock(status_code=200) | |
| volume_resp.json.return_value = {"saleInfo": {"saleability": "NOT_FOR_SALE"}} | |
| isbn_resp = MagicMock(status_code=200) | |
| isbn_resp.json.return_value = { | |
| "items": [{"saleInfo": {"listPrice": {"amount": 0.99, "currencyCode": "USD"}}}], | |
| } | |
| client.get.side_effect = [volume_resp, isbn_resp] | |
| hit = await fetch_google_books_price( | |
| client, | |
| "https://books.google.com/books?id=abc123", | |
| PriceContext(isbn13="9781529374551"), | |
| ) | |
| assert hit is not None | |
| assert hit.formatted == "$0.99" | |
| async def test_apple_formatted_price(self): | |
| client = AsyncMock() | |
| response = MagicMock() | |
| response.status_code = 200 | |
| response.json.return_value = { | |
| "results": [{"formattedPrice": "$14.99", "currency": "USD"}], | |
| } | |
| client.get.return_value = response | |
| hit = await fetch_apple_books_price( | |
| client, "https://books.apple.com/us/book/x/id6475274221", | |
| ) | |
| assert hit is not None | |
| assert hit.formatted == "$14.99" | |
| async def test_open_library_free(self): | |
| client = AsyncMock() | |
| hit = await fetch_listing_price( | |
| client, "open_library", "https://openlibrary.org/isbn/9781529374551", | |
| ) | |
| assert hit is not None | |
| assert hit.formatted == "Free" | |