Files
flowdeck/tests/test_v753_canvases.py
T
bruno 16f73fe39e
FlowDeck CI / lint (push) Successful in 2m14s
FlowDeck CI / docker (push) Canceled after 0s
FlowDeck CI / test (push) Canceled after 2h7m52s
feat: Add plugins — catalogue on/off à effet réel (v7.58.0, phase 8/8)
- app/services/plugins.py + migration 35 : table plugins (slug, name,
  description, enabled) pré-remplie avec 3 modules câblés — web-tools,
  web-clipper, automations ; ligne absente = activé (défaut sûr)
- automations OFF → dépendance FastAPI posée à l'include_router dans main.py
  (aucun router touché) → toutes les routes /workspace/automations* refusées +
  garde de tick du scheduler en arrière-plan
- web-clipper OFF → GET /extensions et tout /api/v2/web-clipper/* refusés
- web-tools OFF → web_search et fetch_url retirés du schéma ET de execute()
  via ToolRegistry._all() : le LLM ne les voit plus
- UI rendue côté serveur : global Jinja plugin_enabled(slug) — nav
  « Extensions » / « Automations » en {% if %} (absentes du DOM), sections
  conditionnées en x-show dans settings.html
- menu + : l'entrée « Add plugins » devient vivante (fini disabled:true) —
  liste des 3 plugins avec bascule, GET/PATCH /api/agent/plugins[/slug]
  (slug inconnu → 404, 401 sans session)
- tests : tests/test_v758_plugins.py (10 tests) — routes refusées (302 hors
  /api, 404 JSON pour /api*), outils retirés, nav disparue, persistance,
  câblage ; assertions disabled:true == 0 dans les tests des phases 1/3/4/5/7
- livraison : VERSION + app/main = 7.58.0, OpenAPI 525 chemins, CHANGELOG,
  ROADMAP phase 8 cochée (menu + complet), avenant phase 8 (docs)
2026-10-07 10:19:25 -04:00

73 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""v7.53.0 — Menu + : Design System – Canevas (créer / insérer / enregistrer)."""
import json
from pathlib import Path
from app.db import get_conn
ROOT = Path(__file__).resolve().parent.parent
JS_PATH = ROOT / "static" / "js" / "agent_panel_2.js"
def test_canvases_list_includes_design_system(client):
tpl = {t["key"]: t for t in client.get("/board/api/page-templates").json()["templates"] if t.get("builtin")}
assert "design_system" in tpl
assert tpl["design_system"]["name"] == "Design System"
assert tpl["design_system"]["icon"] == "🎨"
def test_blocks_route_builtin(client):
r = client.get("/board/api/page-templates/0/blocks", params={"key": "design_system"})
assert r.status_code == 200, r.text
blocks = r.json()["blocks"]
assert isinstance(blocks, list) and blocks
assert blocks[0]["type"] == "heading_1" and blocks[0]["content"] == "Design System"
# les builtins sont livrés sans id : le front appelle ensureBlockIds()
assert "id" not in blocks[0]
assert client.get("/board/api/page-templates/0/blocks", params={"key": "nope"}).status_code == 404
empty = client.get("/board/api/page-templates/0/blocks", params={"key": "empty"})
assert empty.status_code == 200 and empty.json()["blocks"]
def test_blocks_route_user_template(client):
blocks = [{"type": "heading_1", "content": "Mon canevas"},
{"type": "paragraph", "content": "Contenu."}]
created = client.post("/board/api/page-templates", json={"name": "Mon canevas", "blocks": blocks})
assert created.status_code == 200, created.text
tid = created.json()["id"]
got = client.get(f"/board/api/page-templates/{tid}/blocks")
assert got.status_code == 200
assert [b["content"] for b in got.json()["blocks"]] == ["Mon canevas", "Contenu."]
assert client.get("/board/api/page-templates/999999/blocks").status_code == 404
def test_use_design_system_creates_page(client):
r = client.post("/board/api/page-templates/0/use", json={"key": "design_system"})
assert r.status_code == 200, r.text
page_id = r.json()["id"]
with get_conn() as conn:
row = conn.execute(
"SELECT content, content_format FROM pages WHERE id=?", (page_id,)
).fetchone()
assert row["content_format"] == "blocks"
blocks = json.loads(row["content"])
texts = [b.get("content", "") for b in blocks]
assert "Design System" in texts
# les ids sont assignés côté serveur (_ensure_block_ids)
assert all(b.get("id") for b in blocks)
def test_canvases_menu_wired(client):
src = JS_PATH.read_text(encoding="utf-8")
root = src.split("var FD_PLUS_MENU = [", 1)[1].split("];", 1)[0]
assert "action:'canvases'" in root
assert root.count("disabled:true") == 0 # v7.58.0 : menu complet
for action in ("'canvas'", "'canvas-create'", "'canvas-insert'", "'canvas-save'"):
assert action in src, action
# piège /use : la clé builtin part DANS LE BODY, pas en query string
assert "body: JSON.stringify(c.builtin ? {key: c.key} : {})" in src
assert "ensureBlockIds" in src