SPB Git forge

spb/crea-ka

Public

Créa·Ka — annuaire public cross-plateforme des créateurs de contenu québécois (crea-ka.com)

52commits 1branches 0releases
11.3 MBsize
maindefault branch
19 days agolast push
Python 73.6% HTML 13.2% TypeScript 6% JavaScript 4.5% CSS 1.7% Dockerfile 0.6%
4.8 KB · 110 lines python
Raw Blame History
1# ==============================================================================2# Author: Simon-Pierre Boucher <contact@spboucher.ai>3# File:   tests/test_vague2.py4# Desc:   Tests vague 2 — flux RSS des balados, nouvelles plateformes5#         (spotify/discord/apple-podcasts), liaison bio-liens, compteurs X6# ==============================================================================7from pathlib import Path89from creaka.connectors.balados_rss import parse_feed, _parse_feed_regex10from creaka.connectors.bio_liens import extract_bio_accounts11from creaka.connectors.x_profil import parse_counts, parse_syndication12from creaka.normalize import canonical_url, normalize_platform, platform_from_url1314FIXTURE = (Path(__file__).parent / "fixtures" / "balado_sample.xml").read_bytes()151617# --- balados-rss ----------------------------------------------------------------1819def test_parse_feed_champs():20    feed = parse_feed(FIXTURE)21    assert feed["episodes"] == 322    assert feed["last_episode"].strftime("%Y-%m-%d") == "2026-08-01"23    assert feed["image"] == "https://exemple.qc.ca/pochette.jpg"24    assert feed["link"] == "https://www.balado-exemple.ca"25    assert "balado d'exemple" in feed["description"].lower()26    assert "Comedy" in feed["categories"]272829def test_parse_feed_repli_regex_flux_tronque():30    # flux coupé au milieu d'un item : le repli regex garde l'en-tête du canal31    trunc = FIXTURE.split(b"<item>")[0] + b"<item><title>coup"32    feed = _parse_feed_regex(trunc)33    assert feed is not None34    assert feed["image"] == "https://exemple.qc.ca/pochette.jpg"35    assert feed["link"] == "https://www.balado-exemple.ca"36    assert feed["episodes"] == 1373839def test_parse_feed_illisible():40    assert parse_feed(b"pas du xml") is None414243# --- nouvelles plateformes (normalize) --------------------------------------------4445def test_platform_from_url_spotify_discord_apple():46    assert platform_from_url(47        "https://open.spotify.com/show/4rOoJ6Egrf8K2IrywzwOMk") == \48        ("spotify", "4rooj6egrf8k2irywzwomk")49    assert platform_from_url(50        "https://open.spotify.com/intl-fr/artist/06HL4z0CvFAxyc27GXpf02") is not None51    assert platform_from_url("https://discord.gg/AbCd123") == ("discord", "abcd123")52    assert platform_from_url("https://discord.com/invite/AbCd123") == \53        ("discord", "abcd123")54    assert platform_from_url(55        "https://podcasts.apple.com/ca/podcast/mon-balado/id1502950331") == \56        ("podcast", "1502950331")575859def test_canonical_url_conserve_url_source():60    # IDs Spotify et invitations Discord : sensibles à la casse → on garde l'URL61    src = "https://open.spotify.com/show/4rOoJ6Egrf8K2IrywzwOMk"62    assert canonical_url("spotify", "4roo", fallback=src) == src63    assert normalize_platform("spotify") == "spotify"64    assert normalize_platform("discord") == "discord"65    assert normalize_platform("apple podcasts") == "podcast"666768# --- bio-liens --------------------------------------------------------------------6970def test_extract_bio_accounts_urls_completes_seulement():71    bio = ("Humoriste. Balado : https://open.spotify.com/show/4rOoJ6Egrf8K2Iryw "72           "· YouTube www.youtube.com/@moncompte · suivez @autretiktok !")73    accounts = extract_bio_accounts(bio, existing_keys=set())74    keys = {a.key for a in accounts}75    assert "youtube:moncompte" in keys76    assert any(k.startswith("spotify:") for k in keys)77    # « @autretiktok » textuel = ambigu → JAMAIS rattaché78    assert not any("autretiktok" in k for k in keys)79    assert all(a.signal == "cross_link" for a in accounts)808182def test_extract_bio_accounts_ignore_comptes_connus():83    bio = "Mon YouTube : https://youtube.com/@moncompte"84    assert extract_bio_accounts(bio, existing_keys={"youtube:moncompte"}) == []858687# --- x-profil ---------------------------------------------------------------------8889def test_parse_syndication_next_data():90    html = ('<html><script id="__NEXT_DATA__" type="application/json">'91            '{"props":{"pageProps":{"timeline":{"entries":[{"content":{"tweet":'92            '{"user":{"screen_name":"MonCompte","followers_count":4321,'93            '"friends_count":99,"verified":true,'94            '"profile_image_url_https":"https://pbs.twimg.com/x_normal.jpg"'95            '}}}}]}}}}</script></html>')96    info = parse_syndication(html, "moncompte")97    assert info["followers"] == 432198    assert info["following"] == 9999    assert info["verified"] is True100    assert info["avatar"].endswith("x_400x400.jpg")101    # autre handle dans la timeline (retweet) : JAMAIS pris pour le profil102    assert parse_syndication(html, "autrecompte") is None103104105def test_parse_counts_etat_integre():106    html = ('...t:VXNlcjo=:relationship_counts",__typename:'107            '"UserRelationshipCounts",followers:12068,following:847,...')108    assert parse_counts(html) == (12068, 847)109    assert parse_counts("<html>Se connecter</html>") is None110