146 lines
3.9 KiB
Python
146 lines
3.9 KiB
Python
from datetime import datetime
|
|
|
|
import dashboard
|
|
|
|
|
|
def _make_app():
|
|
return dashboard.create_app(
|
|
get_state=lambda: {
|
|
"running": True,
|
|
"started_at": datetime(2026, 1, 1, 10, 0, 0),
|
|
"last_type": "420",
|
|
"last_attempt_at": datetime(2026, 1, 1, 10, 15, 0),
|
|
"last_success_at": datetime(2026, 1, 1, 10, 20, 0),
|
|
"last_status_code": 204,
|
|
"last_error": None,
|
|
"last_locations": ["Nowhere"],
|
|
},
|
|
get_next_event=lambda: {
|
|
"type": "reminder",
|
|
"at": datetime(2026, 1, 1, 11, 15, 0),
|
|
},
|
|
)
|
|
|
|
|
|
def test_fmt_dt_none_and_datetime():
|
|
assert dashboard._fmt_dt(None) == "—"
|
|
assert dashboard._fmt_dt(
|
|
datetime(2026, 1, 1, 10, 0, 0)) == "2026-01-01T10:00:00"
|
|
|
|
|
|
def test_get_html_template_wraps_content():
|
|
html = dashboard.get_html_template("<p>hello</p>")
|
|
assert "<title>thc-webhook admin</title>" in html
|
|
assert "<p>hello</p>" in html
|
|
|
|
|
|
def test_index_route_renders_status_page():
|
|
app = _make_app()
|
|
client = app.test_client()
|
|
|
|
response = client.get("/")
|
|
|
|
assert response.status_code == 200
|
|
body = response.get_data(as_text=True)
|
|
assert "thc-webhook" in body
|
|
assert "last_type: 420" in body
|
|
assert "type: reminder" in body
|
|
assert "Nowhere" in body
|
|
|
|
|
|
def test_admin_get_renders_template_form(monkeypatch):
|
|
monkeypatch.setattr(
|
|
dashboard,
|
|
"load_templates",
|
|
lambda path: {
|
|
"420": {
|
|
"text": "Blaze",
|
|
"color": 3066993,
|
|
"image_url": "https://example.com/img.png",
|
|
}
|
|
},
|
|
)
|
|
|
|
app = _make_app()
|
|
app.config["TEMPLATES_PATH"] = "templates.json"
|
|
client = app.test_client()
|
|
|
|
response = client.get("/admin")
|
|
|
|
assert response.status_code == 200
|
|
body = response.get_data(as_text=True)
|
|
assert "Admin: templates" in body
|
|
assert "name='420__text'" in body
|
|
assert "name='420__color'" in body
|
|
assert "name='420__color_picker'" in body
|
|
assert "type='color'" in body
|
|
assert "name='420__image_url'" in body
|
|
|
|
|
|
def test_admin_post_validation_error(monkeypatch):
|
|
monkeypatch.setattr(
|
|
dashboard,
|
|
"load_templates",
|
|
lambda path: {"420": {"text": "x", "color": 1}},
|
|
)
|
|
monkeypatch.setattr(dashboard, "parse_color", lambda raw: (
|
|
_ for _ in ()).throw(ValueError("bad color")))
|
|
|
|
save_called = {"value": False}
|
|
|
|
def _save_templates(path, updated):
|
|
save_called["value"] = True
|
|
|
|
monkeypatch.setattr(dashboard, "save_templates", _save_templates)
|
|
|
|
app = _make_app()
|
|
client = app.test_client()
|
|
|
|
response = client.post(
|
|
"/admin",
|
|
data={
|
|
"420__text": "Updated",
|
|
"420__color": "bad",
|
|
"420__image_url": "",
|
|
},
|
|
)
|
|
|
|
assert response.status_code == 400
|
|
assert "invalid color" in response.get_data(as_text=True)
|
|
assert save_called["value"] is False
|
|
|
|
|
|
def test_admin_post_success(monkeypatch):
|
|
monkeypatch.setattr(
|
|
dashboard,
|
|
"load_templates",
|
|
lambda path: {"420": {"text": "x", "color": 1}},
|
|
)
|
|
monkeypatch.setattr(dashboard, "parse_color", lambda raw: 123)
|
|
|
|
saved = {"path": None, "payload": None}
|
|
|
|
def _save_templates(path, updated):
|
|
saved["path"] = path
|
|
saved["payload"] = updated
|
|
|
|
monkeypatch.setattr(dashboard, "save_templates", _save_templates)
|
|
|
|
app = _make_app()
|
|
app.config["TEMPLATES_PATH"] = "custom_templates.json"
|
|
client = app.test_client()
|
|
|
|
response = client.post(
|
|
"/admin",
|
|
data={
|
|
"420__text": "Updated",
|
|
"420__color": "123",
|
|
"420__image_url": "",
|
|
},
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
assert "Saved." in response.get_data(as_text=True)
|
|
assert saved["path"] == "custom_templates.json"
|
|
assert saved["payload"] == {"420": {"text": "Updated", "color": 123}}
|