Modèles (chemin DB, migration 0.1.0, ordre, réconciliation), classification, client Gitea (pagination, en-tête, écritures), API (CSRF, write-back, codes d'erreur, 502 propre), auth Basic et fail-closed. Tous verts; pyflakes propre.
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
"""Repo classification: rolling window + real archived flag (audit I1)."""
|
|
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
from app.main import classify_repos
|
|
|
|
NOW = datetime(2026, 10, 11, tzinfo=timezone.utc)
|
|
|
|
|
|
def _repo(name, updated, archived=False):
|
|
return {
|
|
"full_name": f"Projets/{name}",
|
|
"updated_at": updated.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
|
"archived": archived,
|
|
}
|
|
|
|
|
|
def test_recent_repo_is_active():
|
|
active, inactive, archived = classify_repos(
|
|
[_repo("a", NOW - timedelta(days=2))], now=NOW
|
|
)
|
|
assert [r["full_name"] for r in active] == ["Projets/a"]
|
|
assert inactive == [] and archived == []
|
|
|
|
|
|
def test_old_repo_is_inactive_not_archived():
|
|
active, inactive, archived = classify_repos(
|
|
[_repo("a", NOW - timedelta(days=900))], now=NOW
|
|
)
|
|
assert inactive and not active and not archived
|
|
|
|
|
|
def test_archived_flag_wins_even_if_recent():
|
|
# 0.1.0 showed recently-touched archived repos as "active".
|
|
active, inactive, archived = classify_repos(
|
|
[_repo("a", NOW - timedelta(hours=1), archived=True)], now=NOW
|
|
)
|
|
assert archived and not active and not inactive
|
|
|
|
|
|
def test_no_hardcoded_year_2027_still_works():
|
|
future = datetime(2027, 1, 5, tzinfo=timezone.utc)
|
|
active, _, _ = classify_repos([_repo("a", future - timedelta(days=3))], now=future)
|
|
assert len(active) == 1
|