Files
flowdeck/tests/test_v514_synced_blocks.py
T
bruno b0cb3a3923
FlowDeck CI / lint (push) Successful in 1m4s
FlowDeck CI / test (push) Successful in 6m28s
FlowDeck CI / docker (push) Successful in 58s
fix: corriger erreurs Ruff lint I001 et W292
2026-09-17 20:38:37 -04:00

258 lines
11 KiB
Python

"""FlowDeck — Tests for v5.14.0 (Synced blocks)."""
from __future__ import annotations
import json
import secrets
from app.db import get_conn
from app.services.synced_blocks import (
add_page_synced,
create_synced_block,
delete_synced_block,
get_page_synced,
get_synced_block,
list_synced_blocks,
remove_page_synced,
update_synced_block,
)
# ── Helpers ──────────────────────────────────────────────────────
def _login(client):
from app.auth.session import SessionManager
login = f"test_{secrets.token_hex(4)}"
with get_conn() as conn:
conn.execute(
"INSERT INTO users (login, full_name, email, is_admin) "
"VALUES (?, 'Test User', ?, 0)",
(login, f"{login}@test.com",),
)
uid = conn.execute("SELECT id FROM users WHERE login=?", (login,)).fetchone()["id"]
conn.commit()
session = SessionManager.create_session({"id": uid, "login": login})
r2 = client.get("/api/csrf-token", cookies={"flowdeck_session": session})
csrf = r2.json()["csrf_token"]
return session, csrf, uid
def _create_page(client, cookie, csrf, title="Test Page", content="[]"):
r = client.post(
f"/board/api/pages?title={title}",
headers={"X-CSRF-Token": csrf},
cookies={"flowdeck_session": cookie},
)
assert r.status_code == 200
return r.json()["id"]
# ── Service tests ────────────────────────────────────────────────
def test_create_synced_block(client):
"""Creating a synced block returns its id and stores it."""
session, _, uid = _login(client)
sid = create_synced_block(workspace="test", title="My synced", content=[{"type": "paragraph", "content": "Hello"}], created_by=uid)
assert sid > 0
sb = get_synced_block(sid)
assert sb is not None
assert sb["title"] == "My synced"
assert json.loads(sb["content"]) == [{"type": "paragraph", "content": "Hello"}]
assert sb["workspace"] == "test"
def test_get_synced_block_not_found(client):
"""Getting a non-existent synced block returns None."""
sb = get_synced_block(99999)
assert sb is None
def test_update_synced_block(client):
"""Updating a synced block changes its content."""
session, _, uid = _login(client)
sid = create_synced_block(workspace="test", title="Original", content=[{"type": "paragraph", "content": "Old"}], created_by=uid)
update_synced_block(sid, "Updated", [{"type": "heading_1", "content": "New"}])
sb = get_synced_block(sid)
assert sb["title"] == "Updated"
assert json.loads(sb["content"]) == [{"type": "heading_1", "content": "New"}]
def test_delete_synced_block(client):
"""Deleting a synced block removes it."""
session, _, uid = _login(client)
sid = create_synced_block(workspace="test", title="To delete", content=[], created_by=uid)
delete_synced_block(sid)
assert get_synced_block(sid) is None
def test_list_synced_blocks(client):
"""Listing synced blocks returns all for a workspace."""
session, _, uid = _login(client)
create_synced_block(workspace="ws1", title="A", content=[], created_by=uid)
create_synced_block(workspace="ws1", title="B", content=[], created_by=uid)
create_synced_block(workspace="ws2", title="C", content=[], created_by=uid)
items = list_synced_blocks("ws1")
assert len(items) == 2
titles = {i["title"] for i in items}
assert titles == {"A", "B"}
# ── Page reference tests ─────────────────────────────────────────
def test_add_page_synced(client):
"""Adding a synced block reference to a page works."""
session, csrf, uid = _login(client)
sid = create_synced_block(workspace="test", title="Sync1", content=[], created_by=uid)
page_id = _create_page(client, session, csrf, "Page with sync")
add_page_synced(page_id, sid, block_index=0)
refs = get_page_synced(page_id)
assert len(refs) == 1
assert refs[0]["synced_block_id"] == sid
def test_remove_page_synced(client):
"""Removing a synced block reference from a page works."""
session, csrf, uid = _login(client)
sid = create_synced_block(workspace="test", title="Sync1", content=[], created_by=uid)
page_id = _create_page(client, session, csrf, "Page with sync")
add_page_synced(page_id, sid, block_index=0)
remove_page_synced(page_id, sid)
assert len(get_page_synced(page_id)) == 0
# ── API endpoint tests ───────────────────────────────────────────
def test_api_list_synced_blocks(client):
"""GET /board/api/synced-blocks returns synced blocks."""
session, _, uid = _login(client)
create_synced_block(workspace="test", title="API Test", content=[], created_by=uid)
r = client.get("/board/api/synced-blocks?workspace=test", cookies={"flowdeck_session": session})
assert r.status_code == 200
data = r.json()
assert len(data["synced_blocks"]) >= 1
assert data["synced_blocks"][0]["title"] == "API Test"
def test_api_create_synced_block(client):
"""POST /board/api/synced-blocks creates a synced block."""
session, csrf, uid = _login(client)
r = client.post("/board/api/synced-blocks", json={
"title": "From API",
"content": [{"type": "paragraph", "content": "Hello from API"}],
"workspace": "test",
}, headers={"X-CSRF-Token": csrf}, cookies={"flowdeck_session": session})
assert r.status_code == 200
data = r.json()
assert data["status"] == "ok"
assert data["synced_block_id"] > 0
sb = get_synced_block(data["synced_block_id"])
assert sb["title"] == "From API"
def test_api_get_synced_block(client):
"""GET /board/api/synced-blocks/{sid} returns the block."""
session, _, uid = _login(client)
sid = create_synced_block(workspace="test", title="GetTest", content=[], created_by=uid)
r = client.get(f"/board/api/synced-blocks/{sid}", cookies={"flowdeck_session": session})
assert r.status_code == 200
assert r.json()["title"] == "GetTest"
def test_api_get_synced_block_404(client):
"""GET /board/api/synced-blocks/{sid} returns 404 for missing block."""
session, _, uid = _login(client)
r = client.get("/board/api/synced-blocks/99999", cookies={"flowdeck_session": session})
assert r.status_code == 404
def test_api_update_synced_block(client):
"""PUT /board/api/synced-blocks/{sid} updates the block."""
session, csrf, uid = _login(client)
sid = create_synced_block(workspace="test", title="ToUpdate", content=[], created_by=uid)
r = client.put(f"/board/api/synced-blocks/{sid}", json={
"title": "Updated",
"content": [{"type": "heading_1", "content": "Updated content"}],
}, headers={"X-CSRF-Token": csrf}, cookies={"flowdeck_session": session})
assert r.status_code == 200
sb = get_synced_block(sid)
assert sb["title"] == "Updated"
assert json.loads(sb["content"]) == [{"type": "heading_1", "content": "Updated content"}]
def test_api_delete_synced_block(client):
"""DELETE /board/api/synced-blocks/{sid} deletes the block."""
session, csrf, uid = _login(client)
sid = create_synced_block(workspace="test", title="ToDelete", content=[], created_by=uid)
r = client.delete(f"/board/api/synced-blocks/{sid}", headers={"X-CSRF-Token": csrf}, cookies={"flowdeck_session": session})
assert r.status_code == 200
assert get_synced_block(sid) is None
def test_api_add_synced_to_page(client):
"""POST /board/api/pages/{id}/synced adds a synced reference."""
session, csrf, uid = _login(client)
sid = create_synced_block(workspace="test", title="PageSync", content=[], created_by=uid)
page_id = _create_page(client, session, csrf, "Page with sync")
r = client.post(f"/board/api/pages/{page_id}/synced", json={
"synced_block_id": sid,
"block_index": 0,
}, headers={"X-CSRF-Token": csrf}, cookies={"flowdeck_session": session})
assert r.status_code == 200
refs = get_page_synced(page_id)
assert len(refs) == 1
def test_api_remove_synced_from_page(client):
"""DELETE /board/api/pages/{id}/synced/{sid} removes a synced reference."""
session, csrf, uid = _login(client)
sid = create_synced_block(workspace="test", title="PageSync", content=[], created_by=uid)
page_id = _create_page(client, session, csrf, "Page with sync")
add_page_synced(page_id, sid, block_index=0)
r = client.delete(f"/board/api/pages/{page_id}/synced/{sid}", headers={"X-CSRF-Token": csrf}, cookies={"flowdeck_session": session})
assert r.status_code == 200
assert len(get_page_synced(page_id)) == 0
def test_api_get_page_synced_refs(client):
"""GET /board/api/pages/{id}/synced returns synced refs for a page."""
session, csrf, uid = _login(client)
sid = create_synced_block(workspace="test", title="RefTest", content=[], created_by=uid)
page_id = _create_page(client, session, csrf, "Page with sync")
add_page_synced(page_id, sid, block_index=0)
r = client.get(f"/board/api/pages/{page_id}/synced", cookies={"flowdeck_session": session})
assert r.status_code == 200
data = r.json()
assert len(data["synced_blocks"]) == 1
assert data["synced_blocks"][0]["synced_block_id"] == sid
def test_save_blocks_with_synced(client):
"""POST /board/api/pages/{id}/blocks with synced blocks updates page_synced_blocks."""
session, csrf, uid = _login(client)
sid = create_synced_block(workspace="test", title="BlockSync", content=[], created_by=uid)
page_id = _create_page(client, session, csrf, "Page with synced blocks")
r = client.post(f"/board/api/pages/{page_id}/blocks", json={
"blocks": [
{"type": "paragraph", "content": "Hello", "id": "b1"},
{"type": "synced", "synced_id": sid, "id": "b2"},
],
"title": "Updated",
}, headers={"X-CSRF-Token": csrf}, cookies={"flowdeck_session": session})
assert r.status_code == 200
# Verify the reference exists
refs = get_page_synced(page_id)
assert any(r["synced_block_id"] == sid for r in refs)
# ── Resolve synced blocks tests ──────────────────────────────────
def test_resolve_synced_block(client):
"""resolve_synced_block replaces synced block references with content."""
from app.services.synced_blocks import resolve_synced_block
session, _, uid = _login(client)
sid = create_synced_block(workspace="test", title="ResolveTest", content=[{"type": "paragraph", "content": "Resolved!"}], created_by=uid)
blocks = [{"type": "synced", "synced_id": sid, "id": "b1"}]
resolved = resolve_synced_block(blocks)
assert len(resolved) == 1
assert resolved[0].get("_synced_id") == sid
assert resolved[0].get("_synced_content") == [{"type": "paragraph", "content": "Resolved!"}]