160 lines
6.2 KiB
Python
Executable File
160 lines
6.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Tests fixtures réelles pour le store Backmarket."""
|
|
|
|
import pytest
|
|
from pathlib import Path
|
|
|
|
from pricewatch.app.stores.backmarket.store import BackmarketStore
|
|
|
|
|
|
class TestBackmarketFixtures:
|
|
"""Tests avec fixtures HTML réelles de Backmarket."""
|
|
|
|
@pytest.fixture
|
|
def store(self):
|
|
"""Fixture du store Backmarket."""
|
|
return BackmarketStore()
|
|
|
|
@pytest.fixture
|
|
def fixture_iphone15pro(self):
|
|
"""Fixture HTML iPhone 15 Pro."""
|
|
fixture_path = (
|
|
Path(__file__).parent.parent.parent
|
|
/ "pricewatch/app/stores/backmarket/fixtures/backmarket_iphone15pro.html"
|
|
)
|
|
with open(fixture_path, "r", encoding="utf-8") as f:
|
|
return f.read()
|
|
|
|
# ========== Tests de parsing complet ==========
|
|
|
|
def test_parse_iphone15pro_complete(self, store, fixture_iphone15pro):
|
|
"""Parse fixture iPhone 15 Pro - doit extraire toutes les données essentielles."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
|
|
# Identité
|
|
assert snapshot.source == "backmarket"
|
|
assert snapshot.url == "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
assert snapshot.reference == "iphone-15-pro"
|
|
|
|
# Contenu essentiel
|
|
assert snapshot.title == "iPhone 15 Pro"
|
|
assert snapshot.price is not None
|
|
assert snapshot.price > 0
|
|
assert snapshot.currency == "EUR"
|
|
|
|
# Complet
|
|
assert snapshot.is_complete()
|
|
|
|
def test_parse_iphone15pro_title(self, store, fixture_iphone15pro):
|
|
"""Parse fixture - vérifier le titre exact."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
|
|
assert snapshot.title == "iPhone 15 Pro"
|
|
assert len(snapshot.title) > 0
|
|
|
|
def test_parse_iphone15pro_price(self, store, fixture_iphone15pro):
|
|
"""Parse fixture - vérifier le prix."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
|
|
# Prix extrait du JSON-LD
|
|
assert snapshot.price == 571.0
|
|
assert snapshot.currency == "EUR"
|
|
|
|
def test_parse_iphone15pro_reference(self, store, fixture_iphone15pro):
|
|
"""Parse fixture - vérifier la référence (SKU)."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
|
|
assert snapshot.reference == "iphone-15-pro"
|
|
|
|
def test_parse_iphone15pro_images(self, store, fixture_iphone15pro):
|
|
"""Parse fixture - vérifier les images."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
|
|
assert len(snapshot.images) >= 1
|
|
# Vérifier que les URLs sont valides
|
|
for img_url in snapshot.images:
|
|
assert img_url.startswith("http")
|
|
assert "cloudfront" in img_url or "backmarket" in img_url
|
|
|
|
def test_parse_iphone15pro_debug_success(self, store, fixture_iphone15pro):
|
|
"""Parse fixture - vérifier les infos de debug."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
|
|
assert snapshot.debug.status == "success"
|
|
assert snapshot.debug.method == "http" # Sera mis à jour par l'appelant
|
|
|
|
# ========== Tests de robustesse ==========
|
|
|
|
def test_parse_with_different_urls(self, store, fixture_iphone15pro):
|
|
"""Parse fixture fonctionne avec différentes formes d'URL."""
|
|
urls = [
|
|
"https://www.backmarket.fr/fr-fr/p/iphone-15-pro",
|
|
"https://www.backmarket.fr/fr-fr/p/iphone-15-pro?color=black",
|
|
"https://www.backmarket.fr/fr-fr/p/iphone-15-pro#specs",
|
|
]
|
|
|
|
for url in urls:
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
assert snapshot.title == "iPhone 15 Pro"
|
|
assert snapshot.price == 571.0
|
|
# URL canonicalisée (sans query params ni fragment)
|
|
assert snapshot.url == "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
|
|
def test_parse_extracts_data_from_json_ld(self, store, fixture_iphone15pro):
|
|
"""Parse fixture utilise le JSON-LD schema.org (source prioritaire)."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
|
|
# Les données doivent venir du JSON-LD
|
|
assert snapshot.title == "iPhone 15 Pro"
|
|
assert snapshot.price == 571.0
|
|
assert snapshot.currency == "EUR"
|
|
|
|
# Pas d'erreur dans le debug
|
|
assert len(snapshot.debug.errors) == 0
|
|
|
|
def test_parse_no_errors(self, store, fixture_iphone15pro):
|
|
"""Parse fixture ne génère pas d'erreurs."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
|
|
assert len(snapshot.debug.errors) == 0
|
|
|
|
# ========== Tests comparatifs ==========
|
|
|
|
def test_parse_consistent_results(self, store, fixture_iphone15pro):
|
|
"""Parse multiple fois donne les mêmes résultats."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
|
|
snapshot1 = store.parse(fixture_iphone15pro, url)
|
|
snapshot2 = store.parse(fixture_iphone15pro, url)
|
|
|
|
# Les résultats doivent être identiques (sauf fetched_at)
|
|
assert snapshot1.title == snapshot2.title
|
|
assert snapshot1.price == snapshot2.price
|
|
assert snapshot1.currency == snapshot2.currency
|
|
assert snapshot1.reference == snapshot2.reference
|
|
assert snapshot1.images == snapshot2.images
|
|
assert snapshot1.is_complete() == snapshot2.is_complete()
|
|
|
|
def test_parse_json_export(self, store, fixture_iphone15pro):
|
|
"""Parse et export JSON fonctionne sans erreur."""
|
|
url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
|
|
snapshot = store.parse(fixture_iphone15pro, url)
|
|
|
|
# Export vers dict
|
|
data = snapshot.to_dict()
|
|
|
|
assert data["source"] == "backmarket"
|
|
assert data["title"] == "iPhone 15 Pro"
|
|
assert data["price"] == 571.0
|
|
assert data["currency"] == "EUR"
|
|
assert data["reference"] == "iphone-15-pro"
|
|
assert "debug" in data
|