115 lines
3.8 KiB
Python
115 lines
3.8 KiB
Python
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from src.views import dashboard
|
|
|
|
|
|
MY_WORK = Path(__file__).parents[1] / "frontend" / "my-work.js"
|
|
|
|
|
|
def test_my_work_queue_prioritizes_labels_then_reviews_and_keeps_repo_identity():
|
|
payload = {
|
|
"user": {"login": "timmy"},
|
|
"issues": [
|
|
{
|
|
"id": 1,
|
|
"number": 7,
|
|
"title": "Assigned issue",
|
|
"state": "open",
|
|
"repository": "stackchain/mobile",
|
|
"labels": [],
|
|
"assignees": ["timmy"],
|
|
"updated_at": "2026-08-06T12:00:00Z",
|
|
"url": "https://forge.example/mobile/issues/7",
|
|
},
|
|
{
|
|
"id": 2,
|
|
"number": 7,
|
|
"title": "Priority issue",
|
|
"state": "open",
|
|
"repository": "stackchain/api",
|
|
"labels": ["P0"],
|
|
"assignees": [],
|
|
"updated_at": "2026-08-06T11:00:00Z",
|
|
"url": "https://forge.example/api/issues/7",
|
|
},
|
|
],
|
|
"pull_requests": [
|
|
{
|
|
"id": 3,
|
|
"number": 4,
|
|
"title": "Review PR",
|
|
"state": "open",
|
|
"repository": "stackchain/web",
|
|
"work_reasons": ["review_requested"],
|
|
"updated_at": "2026-08-06T13:00:00Z",
|
|
"url": "https://forge.example/web/pulls/4",
|
|
}
|
|
],
|
|
}
|
|
script = f"""
|
|
const buildMyWork = require({json.dumps(str(MY_WORK))});
|
|
const queue = buildMyWork({json.dumps(payload)});
|
|
process.stdout.write(JSON.stringify(queue));
|
|
"""
|
|
|
|
result = subprocess.run(
|
|
["node", "-e", script], check=True, capture_output=True, text=True
|
|
)
|
|
queue = json.loads(result.stdout)
|
|
|
|
assert [item["title"] for item in queue] == [
|
|
"Priority issue",
|
|
"Review PR",
|
|
"Assigned issue",
|
|
]
|
|
assert queue[0]["key"] == "stackchain/api#7"
|
|
assert queue[0]["reason"] == "P0 priority"
|
|
assert queue[1]["reason"] == "Needs your review"
|
|
assert queue[1]["is_review"] is True
|
|
assert queue[2]["reason"] == "Assigned to you"
|
|
|
|
|
|
def test_my_work_reviews_filter_and_summary_are_actionable():
|
|
items = [
|
|
{"title": "Issue", "kind": "issue", "is_review": False, "is_assigned": True},
|
|
{"title": "Assigned PR", "kind": "pull", "is_review": False, "is_assigned": True},
|
|
{"title": "Review PR", "kind": "pull", "is_review": True, "is_assigned": False},
|
|
]
|
|
script = f"""
|
|
const buildMyWork = require({json.dumps(str(MY_WORK))});
|
|
const items = {json.dumps(items)};
|
|
process.stdout.write(JSON.stringify({{
|
|
reviews: buildMyWork.filterMyWork(items, 'review'),
|
|
summary: buildMyWork.summarizeMyWork(items),
|
|
}}));
|
|
"""
|
|
|
|
result = subprocess.run(
|
|
["node", "-e", script], check=True, capture_output=True, text=True
|
|
)
|
|
output = json.loads(result.stdout)
|
|
|
|
assert [item["title"] for item in output["reviews"]] == ["Review PR"]
|
|
assert output["summary"] == "1 review · 2 assigned"
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_mobile_dashboard_puts_filterable_my_work_before_auxiliary_panels():
|
|
html = await dashboard()
|
|
|
|
assert html.index('id="my-work"') < html.index('data-panel-key="context"')
|
|
assert 'data-work-filter="all"' in html
|
|
assert 'data-work-filter="issue"' in html
|
|
assert 'data-work-filter="pull"' in html
|
|
assert 'data-work-filter="review"' in html
|
|
assert '.work-filter' in html and 'min-height: 44px' in html
|
|
assert '.my-work-card' in html and 'min-height: 44px' in html
|
|
assert '<script src="static/my-work.js"></script>' in html
|
|
assert "buildMyWork(data)" in html
|
|
assert "markMyWorkStale()" in html
|
|
assert "filterMyWork(lastMyWork, selectedWorkFilter)" in html
|