Files
flowdeck/tests/test_external_refs.py
T
Spark d8548eede9
FlowDeck CI / lint (push) Failing after 2m33s
FlowDeck CI / test (push) Failing after 30m3s
FlowDeck CI / docker (push) Skipped
feat: Fusion bloc 1 — barre d'apps commune (ACC-1.1, #17) et références croisées external_ref (ACC-1.3, #18)
2026-10-20 23:17:18 -04:00

127 lines
4.7 KiB
Python

"""Références croisées ``external_ref`` — Fusion ACC-1.3 (Flowdeck).
Vérifie le parseur d'URL profondes (contrat figé dracodev-commons), le
cycle API sur une page et sur un projet (collection), les refus
(422/404/401) et la route profonde ``/collections/{id}`` du contrat
ACC-0.1 (redirection vers la vue native ``/db/{id}``).
"""
import pytest
from app.db import get_conn
from app.services.external_refs import parse_deep_link
# ── Parseur d'URL profondes ─────────────────────────────────────────────
@pytest.mark.parametrize("url,attendu", [
("https://tiktak.dracodev.net/?task=42", ("tiktak", "task", "42")),
("https://tiktak.dracodev.net/?list=3", ("tiktak", "list", "3")),
("https://og.dracodev.net/#file=Perso:Notes/Idée.md",
("obsigate", "note", "Perso:Notes/Idée.md")),
("https://flowdeck.dracodev.net/pages/7", ("flowdeck", "page", "7")),
("https://flowdeck.dracodev.net/collections/9", ("flowdeck", "project", "9")),
("https://git.dracodev.net/Projets/ticktick-clone/issues/213",
("kanbante", "card", "Projets/ticktick-clone#213")),
])
def test_parse_formes_reconnues(url, attendu):
parsed = parse_deep_link(url)
assert parsed is not None
assert parsed[:3] == attendu
@pytest.mark.parametrize("url", [
"https://tiktak.dracodev.net/autre?x=1",
"https://og.dracodev.net/#recherche",
"https://flowdeck.dracodev.net/tableau",
"https://example.com/pages/1",
"pas une url",
"",
])
def test_parse_formes_refusees(url):
assert parse_deep_link(url) is None
# ── Fixtures d'objets ───────────────────────────────────────────────────
def _creer_page() -> int:
with get_conn() as conn:
cur = conn.execute(
"INSERT INTO pages (workspace, title) VALUES ('bruno/flowdeck', 'Page Fusion')"
)
conn.commit()
return cur.lastrowid
def _creer_collection() -> int:
with get_conn() as conn:
cur = conn.execute("INSERT INTO collections (name) VALUES ('Projet Fusion')")
conn.commit()
return cur.lastrowid
# ── API sur une page ────────────────────────────────────────────────────
def test_cycle_refs_page(client):
pid = _creer_page()
r = client.post(f"/api/pages/{pid}/refs",
json={"url": "https://tiktak.dracodev.net/?task=42"})
assert r.status_code == 201, r.text
ref = r.json()
assert ref["target_app"] == "tiktak" and ref["target_id"] == "42"
assert ref["label"] == "TikTak · tâche 42"
assert ref["app_color"] == "#e8762c"
r = client.post(f"/api/pages/{pid}/refs",
json={"url": "https://og.dracodev.net/#file=Perso:A.md",
"label": "Note liée"})
assert r.status_code == 201, r.text
r = client.get(f"/api/pages/{pid}/refs")
assert r.status_code == 200
assert [x["target_app"] for x in r.json()["refs"]] == ["tiktak", "obsigate"]
assert r.json()["refs"][1]["label"] == "Note liée"
r = client.delete(f"/api/refs/{ref['id']}")
assert r.status_code == 200
r = client.get(f"/api/pages/{pid}/refs")
assert [x["target_app"] for x in r.json()["refs"]] == ["obsigate"]
def test_ref_url_inconnue_422(client):
pid = _creer_page()
r = client.post(f"/api/pages/{pid}/refs", json={"url": "https://example.com/x"})
assert r.status_code == 422
def test_delete_ref_inconnue_404(client):
r = client.delete("/api/refs/999999")
assert r.status_code == 404
def test_refs_anonyme_401(client):
from tests.conftest import anon
pid = _creer_page()
r = anon(client).get(f"/api/pages/{pid}/refs")
assert r.status_code == 401
# ── API sur un projet (collection) + route profonde ─────────────────────
def test_cycle_refs_collection(client):
cid = _creer_collection()
r = client.post(f"/api/collections/{cid}/refs",
json={"url": "https://git.dracodev.net/Projets/fusion/issues/5"})
assert r.status_code == 201, r.text
assert r.json()["target_app"] == "kanbante"
r = client.get(f"/api/collections/{cid}/refs")
assert len(r.json()["refs"]) == 1
def test_route_profonde_collection(client):
cid = _creer_collection()
r = client.get(f"/collections/{cid}", follow_redirects=False)
assert r.status_code == 303
assert r.headers["location"] == f"/db/{cid}"
r = client.get("/collections/999999", follow_redirects=False)
assert r.status_code == 404