112 lines
5.0 KiB
Python
112 lines
5.0 KiB
Python
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
|
|
MODULE = Path(__file__).parents[1] / "frontend" / "photo-draft-inbox.js"
|
|
INDEX = Path(__file__).parents[1] / "frontend" / "index.html"
|
|
DASHBOARD = Path(__file__).parents[1] / "frontend" / "dashboard.js"
|
|
WORKER = Path(__file__).parents[1] / "frontend" / "service-worker.js"
|
|
BUNDLE = Path(__file__).parents[1] / "src" / "frontend_bundle.py"
|
|
|
|
|
|
def run_node(script: str):
|
|
completed = subprocess.run(["node", "-e", script], check=True, capture_output=True, text=True)
|
|
return json.loads(completed.stdout)
|
|
|
|
|
|
def test_photo_draft_inbox_combines_stores_without_duplicate_target_cards_and_discards_exact_bundle():
|
|
script = f"""
|
|
const createPhotoDraftInbox = require({json.dumps(str(MODULE))});
|
|
const removed=[];
|
|
const conversation={{
|
|
list:async()=>[
|
|
{{id:'conversation-issue',kind:'photo-reply',photo_store:'conversation',title:'o/r#7',updated_at:30,route:{{kind:'issue',repository:'o/r',number:7}}}},
|
|
{{id:'conversation-update',kind:'photo-reply',photo_store:'conversation',title:'Update #8',updated_at:20,route:{{kind:'update',notification_id:8}}}},
|
|
],
|
|
remove:async target=>removed.push(['conversation',target]),
|
|
}};
|
|
const search={{
|
|
list:async()=>[
|
|
{{id:'search-pull',kind:'photo-reply',photo_store:'search',title:'o/r#9',updated_at:40,route:{{kind:'search',target_kind:'pull',repository:'o/r',number:9}}}},
|
|
],
|
|
remove:async target=>removed.push(['search',target]),
|
|
}};
|
|
const inbox=createPhotoDraftInbox({{conversation,search}});
|
|
(async()=>{{
|
|
const drafts=await inbox.refresh([{{kind:'issue-comment',route:{{kind:'issue',repository:'o/r',number:7}}}}]);
|
|
const description=inbox.description({{kind:'photo-reply',photo_count:2}});
|
|
const searchTarget=inbox.searchTarget(drafts[0]);
|
|
await inbox.discard(drafts[0]);
|
|
process.stdout.write(JSON.stringify({{drafts,description,searchTarget,remaining:inbox.list(),removed}}));
|
|
}})().catch(error=>{{console.error(error);process.exit(1);}});
|
|
"""
|
|
assert run_node(script) == {
|
|
"drafts": [
|
|
{
|
|
"id": "search-pull",
|
|
"kind": "photo-reply",
|
|
"photo_store": "search",
|
|
"title": "o/r#9",
|
|
"updated_at": 40,
|
|
"route": {"kind": "search", "target_kind": "pull", "repository": "o/r", "number": 9},
|
|
},
|
|
{
|
|
"id": "conversation-update",
|
|
"kind": "photo-reply",
|
|
"photo_store": "conversation",
|
|
"title": "Update #8",
|
|
"updated_at": 20,
|
|
"route": {"kind": "update", "notification_id": 8},
|
|
},
|
|
],
|
|
"description": "2 saved photos",
|
|
"searchTarget": {"kind": "pull", "repository": "o/r", "number": 9, "title": "o/r#9"},
|
|
"remaining": [
|
|
{
|
|
"id": "conversation-update",
|
|
"kind": "photo-reply",
|
|
"photo_store": "conversation",
|
|
"title": "Update #8",
|
|
"updated_at": 20,
|
|
"route": {"kind": "update", "notification_id": 8},
|
|
}
|
|
],
|
|
"removed": [["search", {"kind": "pull", "repository": "o/r", "number": 9}]],
|
|
}
|
|
|
|
|
|
def test_photo_draft_inbox_keeps_available_store_when_other_inventory_fails():
|
|
script = f"""
|
|
const createPhotoDraftInbox = require({json.dumps(str(MODULE))});
|
|
const inbox=createPhotoDraftInbox({{
|
|
conversation:{{list:async()=>{{throw new Error('IndexedDB unavailable')}}}},
|
|
search:{{list:async()=>[{{id:'safe',route:{{kind:'search',target_kind:'issue',repository:'o/r',number:2}},updated_at:1}}]}},
|
|
}});
|
|
(async()=>process.stdout.write(JSON.stringify(await inbox.refresh([]))))().catch(error=>{{console.error(error);process.exit(1);}});
|
|
"""
|
|
assert run_node(script) == [
|
|
{"id": "safe", "route": {"kind": "search", "target_kind": "issue", "repository": "o/r", "number": 2}, "updated_at": 1}
|
|
]
|
|
|
|
|
|
def test_mobile_my_work_discovers_reopens_and_discards_photo_only_reply_drafts():
|
|
index = INDEX.read_text()
|
|
dashboard = DASHBOARD.read_text()
|
|
worker = WORKER.read_text()
|
|
bundle = BUNDLE.read_text()
|
|
|
|
assert '<script src="static/photo-draft-inbox.js"></script>' in index
|
|
assert "BASE + 'static/photo-draft-inbox.js'" in worker
|
|
assert '"static/photo-draft-inbox.js"' in bundle
|
|
assert "const photoDraftInbox = createPhotoDraftInbox({" in dashboard
|
|
assert "draftInbox.list().concat(photoDraftInbox.list(), unfiled)" in dashboard
|
|
assert "await photoDraftInbox.refresh(draftInbox.list())" in dashboard
|
|
assert "refreshMyWorkView({ reconcileSession:false, refreshFirstTask:false })" in dashboard
|
|
assert "void refreshPhotoDraftInbox();" in dashboard
|
|
assert "onChange:() => { void refreshPhotoDraftInbox(); }" in dashboard
|
|
assert "await searchReplyDraftStore.save(target, attachments);\n void refreshPhotoDraftInbox();" in dashboard
|
|
assert "photoDraftInbox.description(item)" in dashboard
|
|
assert "photoDraftInbox.searchTarget(item)" in dashboard
|
|
assert "await photoDraftInbox.discard(item)" in dashboard
|