runs queue order manipulation and whitespace tightnening

This commit is contained in:
Abel Luck 2026-03-31 10:23:46 +02:00
parent a88eba7dd1
commit 99fd33f770
10 changed files with 478 additions and 121 deletions

View file

@ -138,7 +138,7 @@ def test_runs_page_renders_completed_execution_end_time_as_relative_hoverable_ti
assert ">2 hours ago<" in body
def test_runs_page_renders_queued_execution_table() -> None:
def test_runs_page_renders_combined_running_jobs_table() -> None:
body = str(
runs_page(
queued_executions=(
@ -156,12 +156,16 @@ def test_runs_page_renders_queued_execution_table() -> None:
"run_disabled": True,
"run_post_path": "/actions/jobs/7/run-now",
"cancel_post_path": "/actions/queued-executions/42/cancel",
"move_up_disabled": True,
"move_up_post_path": None,
"move_down_disabled": True,
"move_down_post_path": None,
},
)
)
)
assert "Queued job executions" in body
assert "Running jobs" in body
assert "queued-source" in body
assert ">Queued<" in body
assert "/actions/queued-executions/42/cancel" in body
@ -296,6 +300,23 @@ def test_render_stream_yields_on_connect_and_refresh() -> None:
asyncio.run(run())
def test_render_stream_uses_view_transition_for_queue_reorders() -> None:
async def run() -> None:
queue = RefreshBroker().subscribe()
async def render() -> str:
return '<main id="morph">queue</main>'
stream = render_stream(queue, render, render_on_connect=False)
await queue.put("queue-reordered")
event = await anext(stream)
await stream.aclose()
assert "useViewTransition true" in str(event)
asyncio.run(run())
def test_render_dashboard_shows_dashboard_information_architecture(
monkeypatch, tmp_path: Path
) -> None:
@ -1118,7 +1139,7 @@ def test_settings_action_rejects_non_positive_max_concurrent_jobs(
asyncio.run(run())
def test_render_runs_shows_running_upcoming_and_completed_tables(
def test_render_runs_shows_running_scheduled_and_completed_tables(
monkeypatch, tmp_path: Path
) -> None:
db_path = tmp_path / "runs-render.db"
@ -1149,15 +1170,13 @@ def test_render_runs_shows_running_upcoming_and_completed_tables(
body = str(await render_runs(app))
assert "Running job executions" in body
assert "Queued job executions" in body
assert "Running jobs" in body
assert "Scheduled jobs" in body
assert "Completed job executions" in body
assert "runs-render-source" in body
assert f"/job/{job.id}/execution/{execution.get_id()}/logs" in body
assert "data-next-run-at" in body
assert "in " in body
assert "Already running" not in body
asyncio.run(run())
@ -1187,15 +1206,14 @@ def test_render_runs_shows_empty_state_rows(monkeypatch, tmp_path: Path) -> None
app = create_app()
body = str(await render_runs(app))
assert body.count("No job executions are running.") == 1
assert "No queued executions are waiting." in body
assert body.count("No jobs are running or queued.") == 1
assert "No jobs are scheduled." in body
assert "No job executions have completed yet." in body
asyncio.run(run())
def test_render_runs_shows_queued_execution_separately_from_scheduled_jobs(
def test_render_runs_keeps_queued_execution_in_scheduled_jobs_table(
monkeypatch, tmp_path: Path
) -> None:
db_path = tmp_path / "runs-queued-render.db"
@ -1241,14 +1259,16 @@ def test_render_runs_shows_queued_execution_separately_from_scheduled_jobs(
async def run() -> None:
body = str(await render_runs(app))
assert "Queued job executions" in body
assert "Running jobs" in body
assert "Scheduled jobs" in body
assert "queued-source" in body
assert "scheduled-source" in body
assert ">Queued<" in body
assert (
f"/actions/queued-executions/{int(queued_execution.get_id())}/cancel"
in body
)
assert "Ready" in body
asyncio.run(run())
@ -1296,6 +1316,7 @@ def test_render_runs_shows_cancel_button_for_running_row_with_queued_follow_up(
in body
)
assert ">Cancel<" in body
assert "Running jobs" in body
asyncio.run(run())
@ -1336,6 +1357,10 @@ def test_render_runs_keeps_all_action_controls_visible_in_html_after_compaction(
"run_disabled": True,
"run_post_path": "/actions/jobs/2/run-now",
"cancel_post_path": "/actions/queued-executions/22/cancel",
"move_up_disabled": True,
"move_up_post_path": None,
"move_down_disabled": True,
"move_down_post_path": None,
},
),
upcoming_jobs=(
@ -1374,6 +1399,7 @@ def test_render_runs_keeps_all_action_controls_visible_in_html_after_compaction(
)
)
assert "Running jobs" in body
assert ">Stop<" in body
assert ">Cancel<" in body
assert ">Run now<" in body
@ -1432,6 +1458,78 @@ def test_cancel_queued_execution_action_deletes_pending_row_without_touching_run
asyncio.run(run())
def test_move_queued_execution_action_reorders_queue(
monkeypatch, tmp_path: Path
) -> None:
db_path = tmp_path / "move-queued-action.db"
log_dir = tmp_path / "out" / "logs"
monkeypatch.setenv("REPUBLISHER_DB_PATH", str(db_path))
async def run() -> None:
app = create_app()
app.config["REPUB_LOG_DIR"] = log_dir
client = app.test_client()
first_source = create_source(
name="First queued source",
slug="first-queued-source",
source_type="feed",
notes="",
spider_arguments="",
enabled=True,
cron_minute="*/5",
cron_hour="*",
cron_day_of_month="*",
cron_day_of_week="*",
cron_month="*",
feed_url="https://example.com/first.xml",
)
second_source = create_source(
name="Second queued source",
slug="second-queued-source",
source_type="feed",
notes="",
spider_arguments="",
enabled=True,
cron_minute="*/5",
cron_hour="*",
cron_day_of_month="*",
cron_day_of_week="*",
cron_month="*",
feed_url="https://example.com/second.xml",
)
first_job = Job.get(Job.source == first_source)
second_job = Job.get(Job.source == second_source)
first_execution = JobExecution.create(
job=first_job,
created_at=datetime(2026, 3, 30, 12, 0, tzinfo=UTC),
running_status=JobExecutionStatus.PENDING,
)
second_execution = JobExecution.create(
job=second_job,
created_at=datetime(2026, 3, 30, 12, 5, tzinfo=UTC),
running_status=JobExecutionStatus.PENDING,
)
response = await client.post(
f"/actions/queued-executions/{int(second_execution.get_id())}/move-up"
)
assert response.status_code == 204
body = str(await render_runs(app))
assert body.index("second-queued-source") < body.index("first-queued-source")
assert (
f"/actions/queued-executions/{int(second_execution.get_id())}/move-down"
in body
)
assert (
f"/actions/queued-executions/{int(first_execution.get_id())}/move-up"
in body
)
asyncio.run(run())
def test_toggle_job_enabled_action_removes_queued_execution(
monkeypatch, tmp_path: Path
) -> None: