feat(icon): Notion-style icon picker + custom workspace emojis; fix side peek file content & ctx menu overflow
This commit is contained in:
+72
-1
@@ -484,12 +484,27 @@ class TestCoverIcon:
|
||||
page = _page(client, cookie, csrf, "Icon long")
|
||||
r = client.post(
|
||||
f"/board/api/pages/{page}/icon",
|
||||
json={"icon": "x" * 32},
|
||||
json={"icon": "x" * 600},
|
||||
headers={"Content-Type": "application/json", **_cookie_headers(cookie, csrf)},
|
||||
cookies={"flowdeck_session": cookie},
|
||||
)
|
||||
assert r.status_code == 400
|
||||
|
||||
def test_custom_emoji_url_accepted_as_icon(self, client):
|
||||
cookie, csrf = _login(client)
|
||||
_workspace(client, cookie)
|
||||
page = _page(client, cookie, csrf, "Custom icon")
|
||||
url = "/api/files/1/emoji_123_cat.png"
|
||||
r = client.post(
|
||||
f"/board/api/pages/{page}/icon",
|
||||
json={"icon": url},
|
||||
headers={"Content-Type": "application/json", **_cookie_headers(cookie, csrf)},
|
||||
cookies={"flowdeck_session": cookie},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
r2 = client.get(f"/board/api/pages/{page}", cookies={"flowdeck_session": cookie})
|
||||
assert r2.json()["page_icon"] == url
|
||||
|
||||
def test_public_page_renders_cover_and_icon(self, client):
|
||||
cookie, csrf = _login(client)
|
||||
_workspace(client, cookie)
|
||||
@@ -543,3 +558,59 @@ class TestEditorEndpointPaths:
|
||||
assert "fetch('/api/pages/'+this.pid+'/versions" not in tpl
|
||||
assert "fetch('/api/pages/'+this.pid+'/backlinks" not in tpl
|
||||
assert "fetch('/api/og/metadata" not in tpl
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
# v5.6.0: custom workspace emojis
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
|
||||
class TestCustomEmojis:
|
||||
def test_list_empty(self, client):
|
||||
cookie, _ = _login(client)
|
||||
_workspace(client, cookie)
|
||||
r = client.get("/api/custom-emojis", cookies={"flowdeck_session": cookie})
|
||||
assert r.status_code == 200
|
||||
assert r.json()["emojis"] == []
|
||||
|
||||
def test_upload_and_delete(self, client):
|
||||
cookie, csrf = _login(client)
|
||||
_workspace(client, cookie)
|
||||
png = b"\x89PNG\r\n\x1a\n" + b"0" * 16
|
||||
r = client.post(
|
||||
"/api/custom-emojis",
|
||||
data={"name": "pushup"},
|
||||
files={"file": ("pushup.png", png, "image/png")},
|
||||
headers=_cookie_headers(cookie, csrf),
|
||||
cookies={"flowdeck_session": cookie},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
emoji = r.json()["emoji"]
|
||||
assert emoji["name"] == "pushup"
|
||||
assert emoji["url"].startswith("/api/files/")
|
||||
|
||||
listed = client.get("/api/custom-emojis", cookies={"flowdeck_session": cookie}).json()["emojis"]
|
||||
assert any(e["id"] == emoji["id"] for e in listed)
|
||||
|
||||
d = client.request(
|
||||
"DELETE",
|
||||
f"/api/custom-emojis/{emoji['id']}",
|
||||
headers=_cookie_headers(cookie, csrf),
|
||||
cookies={"flowdeck_session": cookie},
|
||||
)
|
||||
assert d.status_code == 200
|
||||
after = client.get("/api/custom-emojis", cookies={"flowdeck_session": cookie}).json()["emojis"]
|
||||
assert all(e["id"] != emoji["id"] for e in after)
|
||||
|
||||
def test_reject_non_image(self, client):
|
||||
cookie, csrf = _login(client)
|
||||
_workspace(client, cookie)
|
||||
r = client.post(
|
||||
"/api/custom-emojis",
|
||||
data={"name": "bad"},
|
||||
files={"file": ("evil.sh", b"#!/bin/sh", "text/plain")},
|
||||
headers=_cookie_headers(cookie, csrf),
|
||||
cookies={"flowdeck_session": cookie},
|
||||
)
|
||||
assert r.status_code == 400
|
||||
|
||||
|
||||
Reference in New Issue
Block a user