Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Tests

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

jobs:
pytest:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- name: Install DejaVu fonts
# Matches the Dockerfile; the swatch renderer prefers DejaVu for umlauts.
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends fonts-dejavu-core

- name: Install dependencies
run: pip install -r requirements-dev.txt

- name: Run tests
run: pytest -q
9 changes: 7 additions & 2 deletions handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ async def _await_slice(job_id, timeout=300, interval=4):
"failed": "❌", "skipped": "⏭️", "cancelled": "🚫",
}
# Finished statuses hidden from !liste — they just pile up and clutter the view.
_DONE_QUEUE_STATUS = {"completed", "cancelled", "skipped"}
_DONE_QUEUE_STATUS = {"completed", "cancelled", "skipped", "failed"}


async def _skip(group_id):
Expand Down Expand Up @@ -1063,7 +1063,12 @@ async def _list(group_id):
# didn't queue (e.g. a Bambu Studio print — we don't know).
e = ejects.get(it.get("id"))
tag = eject_tag if e else (noeject_tag if e is False else "")
lines.append(f'{i}. {_STATUS_EMOJI.get(st, "")} {nm} ({st}){tag}'.replace(" ", " "))
# Sliced print time in seconds (verified against the real Bambuddy
# /queue/ payload — the field is always `print_time_seconds`), shown as
# e.g. ' · 21 min'; omitted when the queue item doesn't carry it.
secs = it.get("print_time_seconds")
dur = f" · {colors._fmt_minutes(secs)}" if secs else ""
lines.append(f'{i}. {_STATUS_EMOJI.get(st, "")} {nm} ({st}){dur}{tag}'.replace(" ", " "))
await signal_client.send_to_group(group_id, i18n.t(lang, "list_header") + "\n".join(lines))


Expand Down
50 changes: 50 additions & 0 deletions tests/test_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import asyncio
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
import config # noqa: E402
import handlers # noqa: E402
import store # noqa: E402


def _setup(tmp_path, monkeypatch, queue_items):
config.DB_PATH = str(tmp_path / "t.db")
store.init_db()
sent = []

async def fake_send(group_id, msg, **k):
sent.append(msg)

async def fake_list_queue():
return queue_items

monkeypatch.setattr(handlers.signal_client, "send_to_group", fake_send)
monkeypatch.setattr(handlers.bambuddy, "list_queue", fake_list_queue)
return sent


def test_list_shows_print_duration(tmp_path, monkeypatch):
sent = _setup(tmp_path, monkeypatch, [
{"id": 1, "status": "pending", "library_file_name": "Quick",
"print_time_seconds": 1267}, # 21 min
{"id": 2, "status": "pending", "library_file_name": "Long",
"print_time_seconds": 7800}, # 2h10
{"id": 3, "status": "pending", "library_file_name": "Unknown"}, # no time
])
asyncio.run(handlers._list("g1"))
out = sent[-1]
assert "Quick (pending) · 21 min" in out
assert "Long (pending) · 2h10" in out
# No duration field → nothing appended after the status.
assert "Unknown (pending)\n" in out or out.rstrip().endswith("Unknown (pending)")


def test_list_done_jobs_hidden(tmp_path, monkeypatch):
sent = _setup(tmp_path, monkeypatch, [
{"id": 1, "status": "failed", "library_file_name": "Boom"},
{"id": 2, "status": "completed", "library_file_name": "Done"},
])
asyncio.run(handlers._list("g1"))
assert "Boom" not in sent[-1]
assert "Done" not in sent[-1]
Loading