#!/usr/bin/env python3 """Tests fixtures réelles pour le store AliExpress.""" import pytest from pathlib import Path from pricewatch.app.stores.aliexpress.store import AliexpressStore class TestAliexpressFixtures: """Tests avec fixtures HTML réelles d'AliExpress.""" @pytest.fixture def store(self): """Fixture du store AliExpress.""" return AliexpressStore() @pytest.fixture def fixture_samsung_ram(self): """Fixture HTML Samsung DDR4 RAM.""" fixture_path = ( Path(__file__).parent.parent.parent / "pricewatch/app/stores/aliexpress/fixtures/aliexpress_1005007187023722.html" ) with open(fixture_path, "r", encoding="utf-8") as f: return f.read() # ========== Tests de parsing complet ========== def test_parse_samsung_ram_complete(self, store, fixture_samsung_ram): """Parse fixture Samsung RAM - doit extraire toutes les données essentielles.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) # Identité assert snapshot.source == "aliexpress" assert snapshot.url == "https://fr.aliexpress.com/item/1005007187023722.html" assert snapshot.reference == "1005007187023722" # Contenu essentiel assert snapshot.title is not None assert "Samsung" in snapshot.title assert "DDR4" in snapshot.title assert snapshot.price is not None assert snapshot.price > 0 assert snapshot.currency == "EUR" # Complet assert snapshot.is_complete() def test_parse_samsung_ram_title(self, store, fixture_samsung_ram): """Parse fixture - vérifier le titre exact.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) assert snapshot.title.startswith("Samsung serveur DDR4") assert "RAM" in snapshot.title assert len(snapshot.title) > 20 def test_parse_samsung_ram_price(self, store, fixture_samsung_ram): """Parse fixture - vérifier le prix.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) # Prix extrait par regex assert snapshot.price == 136.69 assert snapshot.currency == "EUR" def test_parse_samsung_ram_reference(self, store, fixture_samsung_ram): """Parse fixture - vérifier la référence (SKU).""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) assert snapshot.reference == "1005007187023722" assert len(snapshot.reference) == 16 # ID long (13 chiffres) def test_parse_samsung_ram_images(self, store, fixture_samsung_ram): """Parse fixture - vérifier les images.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) assert len(snapshot.images) >= 6 # Vérifier que les URLs sont valides for img_url in snapshot.images: assert img_url.startswith("http") assert "alicdn.com" in img_url def test_parse_samsung_ram_stock(self, store, fixture_samsung_ram): """Parse fixture - vérifier le stock.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) # Devrait être in_stock (bouton "add to cart" présent) assert snapshot.stock_status == "in_stock" def test_parse_samsung_ram_debug_success(self, store, fixture_samsung_ram): """Parse fixture - vérifier les infos de debug.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) assert snapshot.debug.status == "success" assert len(snapshot.debug.errors) == 0 # Devrait avoir une note sur les images DCData assert any("DCData" in note for note in snapshot.debug.notes) # ========== Tests de robustesse ========== def test_parse_with_different_urls(self, store, fixture_samsung_ram): """Parse fixture fonctionne avec différentes formes d'URL.""" urls = [ "https://fr.aliexpress.com/item/1005007187023722.html", "https://fr.aliexpress.com/item/1005007187023722.html?spm=a2g0o.detail", "https://fr.aliexpress.com/item/1005007187023722.html#reviews", ] for url in urls: snapshot = store.parse(fixture_samsung_ram, url) assert "Samsung" in snapshot.title assert snapshot.price == 136.69 # URL canonicalisée (sans query params ni fragment) assert ( snapshot.url == "https://fr.aliexpress.com/item/1005007187023722.html" ) def test_parse_extracts_images_from_dcdata(self, store, fixture_samsung_ram): """Parse fixture extrait les images depuis DCData JSON.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) # Les images doivent venir de DCData assert len(snapshot.images) == 6 assert all("alicdn.com" in img for img in snapshot.images) # Debug note sur DCData assert any("DCData" in note for note in snapshot.debug.notes) def test_parse_no_errors(self, store, fixture_samsung_ram): """Parse fixture ne génère pas d'erreurs.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) assert len(snapshot.debug.errors) == 0 # ========== Tests comparatifs ========== def test_parse_consistent_results(self, store, fixture_samsung_ram): """Parse multiple fois donne les mêmes résultats.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot1 = store.parse(fixture_samsung_ram, url) snapshot2 = store.parse(fixture_samsung_ram, 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_samsung_ram): """Parse et export JSON fonctionne sans erreur.""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) # Export vers dict data = snapshot.to_dict() assert data["source"] == "aliexpress" assert "Samsung" in data["title"] assert data["price"] == 136.69 assert data["currency"] == "EUR" assert data["reference"] == "1005007187023722" assert len(data["images"]) >= 6 assert "debug" in data def test_parse_html_size_adequate(self, store, fixture_samsung_ram): """Parse fixture - HTML assez volumineux (rendu complet).""" url = "https://fr.aliexpress.com/item/1005007187023722.html" snapshot = store.parse(fixture_samsung_ram, url) # HTML > 200KB = rendu complet # Pas de note sur HTML court assert not any("non rendu" in note.lower() for note in snapshot.debug.notes)