113 lines
3.7 KiB
Python
113 lines
3.7 KiB
Python
"""Palier 6 (0.9.0): board dynamique sans refresh (issue #15)."""
|
|
|
|
import re
|
|
|
|
import app.main as main
|
|
from tests.conftest import csrf_from
|
|
|
|
|
|
def _page_counts(html: str) -> dict[str, int]:
|
|
counts = {}
|
|
for col, count in re.findall(
|
|
r'data-column="(\w+)">\s*<div class="column-header".*?column-count[^>]*>(\d+)',
|
|
html, re.S,
|
|
):
|
|
counts[col] = int(count)
|
|
return counts
|
|
|
|
|
|
def test_api_board_matches_page(client, fake_gitea):
|
|
page = client.get("/board/Projets/demo")
|
|
assert page.status_code == 200
|
|
api = client.get("/api/board/Projets/demo")
|
|
assert api.status_code == 200
|
|
data = api.json()
|
|
assert data["repo"] == "Projets/demo"
|
|
page_counts = _page_counts(page.text)
|
|
for col in ("backlog", "todo", "in_progress", "qa", "review", "done"):
|
|
assert data["columns"][col]["count"] == page_counts[col], col
|
|
assert "Tâche un" in data["columns"]["backlog"]["html"]
|
|
assert 'data-issue="1"' in data["columns"]["backlog"]["html"]
|
|
# Empty column carries the same hint as the server-rendered page.
|
|
assert "Glissez une carte ici" in data["columns"]["qa"]["html"]
|
|
|
|
|
|
def test_api_board_reflects_move(client, fake_gitea):
|
|
token = csrf_from(client)
|
|
r = client.post("/api/move", data={
|
|
"repo_full_name": "Projets/demo", "issue_number": 1,
|
|
"from_column": "backlog", "to_column": "in_progress",
|
|
"to_order": "1", "csrf_token": token,
|
|
})
|
|
assert r.status_code == 200 and r.json()["ok"]
|
|
data = client.get("/api/board/Projets/demo").json()
|
|
assert 'data-issue="1"' in data["columns"]["in_progress"]["html"]
|
|
# #5 ("Tâche focus", also unplaced) stays in the backlog.
|
|
assert data["columns"]["backlog"]["count"] == 1
|
|
assert 'data-issue="5"' in data["columns"]["backlog"]["html"]
|
|
|
|
|
|
def test_board_page_uses_board_live_not_live(client, fake_gitea):
|
|
page = client.get("/board/Projets/demo")
|
|
assert "/static/js/board-live.js" in page.text
|
|
assert "/static/js/live.js" not in page.text
|
|
focus = client.get("/focus")
|
|
assert "/static/js/live.js" in focus.text # unchanged elsewhere
|
|
|
|
|
|
def test_move_broadcasts_board_changed(client, fake_gitea, monkeypatch):
|
|
sent = []
|
|
|
|
async def record(payload):
|
|
sent.append(payload)
|
|
|
|
monkeypatch.setattr(main.hub, "broadcast", record)
|
|
token = csrf_from(client)
|
|
r = client.post("/api/move", data={
|
|
"repo_full_name": "Projets/demo", "issue_number": 1,
|
|
"from_column": "backlog", "to_column": "todo",
|
|
"to_order": "1", "csrf_token": token,
|
|
})
|
|
assert r.status_code == 200
|
|
assert any(
|
|
p.get("type") == "board-changed" and p.get("repo") == "Projets/demo"
|
|
for p in sent
|
|
), sent
|
|
|
|
|
|
def test_create_issue_broadcasts(client, fake_gitea, monkeypatch):
|
|
sent = []
|
|
|
|
async def record(payload):
|
|
sent.append(payload)
|
|
|
|
monkeypatch.setattr(main.hub, "broadcast", record)
|
|
token = csrf_from(client)
|
|
r = client.post("/api/issues", data={
|
|
"repo_full_name": "Projets/demo", "title": "Nouvelle carte live",
|
|
"column": "backlog", "csrf_token": token,
|
|
})
|
|
assert r.status_code == 201
|
|
assert any(p.get("type") == "board-changed" for p in sent), sent
|
|
|
|
|
|
def test_webhook_label_event_broadcasts(client, fake_gitea, monkeypatch):
|
|
sent = []
|
|
|
|
async def record(payload):
|
|
sent.append(payload)
|
|
|
|
monkeypatch.setattr(main.hub, "broadcast", record)
|
|
r = client.post(
|
|
"/webhooks/gitea",
|
|
json={
|
|
"action": "labeled",
|
|
"repository": {"full_name": "Projets/demo"},
|
|
"issue": {"number": 1},
|
|
},
|
|
headers={"x-gitea-event": "issues"},
|
|
)
|
|
assert r.status_code == 200
|
|
assert r.json()["ok"] is True
|
|
assert sent and sent[0]["action"] == "labeled"
|