API-KA — plateforme centrale : collecte quotidienne des 8 services KA, historisation append-only et API publique sur www.api-ka.com
Python 60.9%
HTML 21%
TypeScript 7.3%
JavaScript 5.2%
CSS 4.8%
Shell 0.8%
1# ============================================2# Projet : API-KA3# Fichier : tests/test_backfill.py4# Node : m3u96b5# Author : Simon-Pierre Boucher6# Contact : contact@spboucher.ai7# Date : 2026-08-168# ============================================9"""Tests du rattrapage des dates manquées (src/scheduler/backfill.py)."""1011from __future__ import annotations1213import datetime1415import pytest1617from src.database.db import session_scope18from src.database.models import CollectionRun19from src.scheduler.backfill import backfill_date, missing_dates202122def _insert_success_run(service: str, date_key: datetime.date) -> None:23 now = datetime.datetime.now(tz=datetime.UTC)24 with session_scope() as session:25 session.add(26 CollectionRun(27 service=service,28 date_key=date_key,29 status="success",30 records_count=1,31 duration_seconds=0.1,32 error_message=None,33 node="m3u96b",34 started_at=now,35 finished_at=now,36 )37 )383940def _insert_failed_run(service: str, date_key: datetime.date) -> None:41 now = datetime.datetime.now(tz=datetime.UTC)42 with session_scope() as session:43 session.add(44 CollectionRun(45 service=service,46 date_key=date_key,47 status="failed",48 records_count=0,49 duration_seconds=0.1,50 error_message="boom",51 node="m3u96b",52 started_at=now,53 finished_at=now,54 )55 )565758def test_missing_dates_empty_for_brand_new_service() -> None:59 """Aucune activité connue → aucun backfill (on ne fabrique pas d'historique)."""60 assert missing_dates("foodka", days=7) == []616263def test_missing_dates_detects_gaps_after_first_activity() -> None:64 """Les jours sans collecte APRÈS la première activité sont manqués."""65 today = datetime.date.today()66 _insert_success_run("immoka", today - datetime.timedelta(days=3))67 missing = missing_dates("immoka", days=5)68 assert missing == [69 today - datetime.timedelta(days=2),70 today - datetime.timedelta(days=1),71 ]727374def test_missing_dates_includes_failed_only_dates() -> None:75 """Une date avec seulement un run failed doit être rattrapée."""76 yesterday = datetime.date.today() - datetime.timedelta(days=1)77 _insert_failed_run("fabrika", yesterday)78 assert yesterday in missing_dates("fabrika", days=3)798081def test_missing_dates_excludes_successful_runs() -> None:82 """Une date couverte par un run success n'est plus considérée manquée."""83 yesterday = datetime.date.today() - datetime.timedelta(days=1)84 _insert_success_run("autoka", yesterday)85 assert yesterday not in missing_dates("autoka", days=2)868788def test_missing_dates_rejects_unknown_service() -> None:89 """Un service inconnu lève une ValueError."""90 with pytest.raises(ValueError):91 missing_dates("inconnu")929394def test_backfill_date_runs_collectors(monkeypatch: pytest.MonkeyPatch) -> None:95 """backfill_date relance le collecteur de chaque service demandé."""96 called: list[tuple[str, datetime.date]] = []9798 class FakeCollector:99 def __init__(self, service: str) -> None:100 self.service = service101102 def run(self, date_key: datetime.date) -> dict:103 called.append((self.service, date_key))104 return {"service": self.service, "status": "success", "records_count": 0}105106 monkeypatch.setattr(107 "src.scheduler.backfill.get_collector", lambda service: FakeCollector(service)108 )109110 target = datetime.date(2026, 8, 15)111 results = backfill_date(target, services=["fabrika"])112113 assert called == [("fabrika", target)]114 assert results[0]["status"] == "success"115