Files
flowdeck/tests/test_sync_migrations.py
T
bruno b5207216f1 feat: v6.0.0 PWA offline support
- manifest + icones, service worker (precache, network-first, Background Sync)

- module client FlowOffline (IndexedDB, queue, delta, flush) + hook editeur

- endpoints /api/v2/sync/{delta,batch,status} + moteur de sync (conflits LWW/orpheline/copie offline)

- migrations offline_sync_queue + sync_version (triggers)

- UI offline (banner, badge sync, toasts, icone dirty) + doc /help

- tests pytest (sync, migrations, SW, offline) + E2E Playwright; bump 6.0.0
2026-09-18 13:05:40 -04:00

126 lines
4.7 KiB
Python

"""FlowDeck — v6.0.0 PWA: offline-sync schema migrations.
Validates the ``offline_sync_queue`` table, the ``sync_version`` columns and
the BEFORE-UPDATE triggers that bump them on every write.
"""
from app.db import get_conn
def _insert_page(title="Page"):
with get_conn() as conn:
cur = conn.execute(
"INSERT INTO pages (workspace, title, content, content_format, parent_section) "
"VALUES ('', ?, '', 'blocks', 'Private')",
(title,),
)
conn.commit()
return cur.lastrowid
def _insert_collection(name="Coll"):
with get_conn() as conn:
cur = conn.execute(
"INSERT INTO collections (name, schema_json) VALUES (?, '[]')", (name,)
)
conn.commit()
return cur.lastrowid
def _insert_collection_page(coll_id, title="Row"):
with get_conn() as conn:
cur = conn.execute(
"INSERT INTO collection_pages (collection_id, title) VALUES (?, ?)",
(coll_id, title),
)
conn.commit()
return cur.lastrowid
def test_offline_sync_queue_table_and_indexes(client):
with get_conn() as conn:
cols = {r[1] for r in conn.execute("PRAGMA table_info(offline_sync_queue)")}
for expected in ("id", "user_id", "device_id", "type", "payload",
"client_timestamp", "server_version", "status",
"retries", "error", "created_at"):
assert expected in cols, f"offline_sync_queue missing column {expected}"
indexes = {r[1] for r in conn.execute("PRAGMA index_list('offline_sync_queue')")}
assert "idx_syncqueue_user" in indexes
assert "idx_syncqueue_device" in indexes
def test_offline_sync_queue_insert(client):
with get_conn() as conn:
uid = conn.execute(
"INSERT INTO users (login, full_name, email) VALUES ('queuetest', 'Queue', '[email protected]')"
).lastrowid
cur = conn.execute(
"INSERT INTO offline_sync_queue (user_id, device_id, type, payload, client_timestamp) "
"VALUES (?, ?, ?, ?, ?)",
(uid, "dev-abc", "page_update", '{"page_id": 1}', 1750000000000.0),
)
conn.commit()
qid = cur.lastrowid
row = conn.execute(
"SELECT status, server_version, retries FROM offline_sync_queue WHERE id=?",
(qid,),
).fetchone()
assert row["status"] == "pending"
assert row["server_version"] == 0
assert row["retries"] == 0
def test_sync_version_column_and_defaults(client):
pid = _insert_page()
cid = _insert_collection()
cpid = _insert_collection_page(cid)
with get_conn() as conn:
for table, pk in (("pages", pid), ("collection_pages", cpid), ("collections", cid)):
row = conn.execute(f"SELECT sync_version FROM {table} WHERE id=?", (pk,)).fetchone()
assert row is not None, f"sync_version missing on {table}"
assert row["sync_version"] == 1, f"{table} default sync_version should be 1"
def test_sync_version_increments_on_update(client):
pid = _insert_page()
with get_conn() as conn:
conn.execute("UPDATE pages SET title='Renamed' WHERE id=?", (pid,))
conn.commit()
v1 = conn.execute("SELECT sync_version FROM pages WHERE id=?", (pid,)).fetchone()
conn.execute("UPDATE pages SET content='[...]' WHERE id=?", (pid,))
conn.commit()
v2 = conn.execute("SELECT sync_version FROM pages WHERE id=?", (pid,)).fetchone()
assert v1["sync_version"] == 2
assert v2["sync_version"] == 3
def test_sync_version_increments_on_soft_delete(client):
"""deleted_at changes must bump the version too (delta sync sees deletions)."""
pid = _insert_page()
with get_conn() as conn:
conn.execute(
"UPDATE pages SET deleted_at=CURRENT_TIMESTAMP WHERE id=? AND deleted_at IS NULL",
(pid,),
)
conn.commit()
row = conn.execute("SELECT sync_version FROM pages WHERE id=?", (pid,)).fetchone()
assert row["sync_version"] == 2
def test_sync_version_increments_collection_and_rows(client):
cid = _insert_collection()
cpid = _insert_collection_page(cid)
with get_conn() as conn:
conn.execute("UPDATE collections SET name='Renamed' WHERE id=?", (cid,))
conn.execute(
"UPDATE collection_pages SET title='Row2', property_values_json='{}' WHERE id=?",
(cpid,),
)
conn.commit()
col = conn.execute("SELECT sync_version FROM collections WHERE id=?", (cid,)).fetchone()
row = conn.execute(
"SELECT sync_version FROM collection_pages WHERE id=?", (cpid,)
).fetchone()
assert col["sync_version"] == 2
assert row["sync_version"] == 2