Files
schedls/tests/unit/test_output.py
T
mdaleo404 aded37d491
CI / test (3.11) (push) Canceled after 0s
CI / test (3.12) (push) Canceled after 0s
CI / test (3.13) (push) Canceled after 0s
CI / test (3.14) (push) Canceled after 0s
CI / package (push) Canceled after 0s
CI / precommit-and-security (push) Canceled after 11s
CI / typecheck (push) Canceled after 11s
Initial code commit
2026-09-25 11:16:19 +01:00

106 lines
3.2 KiB
Python

from __future__ import annotations
import io
import json
from datetime import UTC, datetime
from schedls.models import (
Backend,
Command,
CronDetails,
JobSource,
Schedule,
ScheduledJob,
ScheduleKind,
Scope,
SystemdDetails,
)
from schedls.output import Output, job_to_dict, jobs_document, sanitize_text
def _systemd_job() -> ScheduledJob:
return ScheduledJob(
name="backup",
backend=Backend.SYSTEMD,
scope=Scope.USER,
managed=True,
enabled=True,
schedule=Schedule(ScheduleKind.CALENDAR, "*-*-* 02:00:00", ("*-*-* 02:00:00",)),
command=Command(argv=("/usr/local/bin/backup", "/srv/data")),
source=JobSource("systemd user timer", path="/home/u/.config/systemd/user/schedls-backup.timer"),
next_run=datetime(2026, 9, 25, 2, 0, tzinfo=UTC),
systemd=SystemdDetails(
timer_unit="schedls-backup.timer",
service_unit="schedls-backup.service",
persistent=True,
),
)
def _cron_job() -> ScheduledJob:
return ScheduledJob(
name="cron-3",
backend=Backend.CRON,
scope=Scope.USER,
managed=False,
enabled=None,
schedule=Schedule(ScheduleKind.CRON, "0 4 * * 0"),
command=Command(raw="/usr/local/bin/cleanup"),
source=JobSource("current user's crontab", line=3),
cron=CronDetails(expression="0 4 * * 0", line=3),
)
def test_job_to_dict_systemd() -> None:
data = job_to_dict(_systemd_job())
assert data["name"] == "backup"
assert data["backend"] == "systemd"
assert data["managed"] is True
assert data["next_run"].endswith("+00:00")
assert data["systemd"]["persistent"] is True
def test_job_to_dict_cron_missing_data_is_null() -> None:
data = job_to_dict(_cron_job())
assert data["next_run"] is None
assert data["last_run"] is None
assert data["enabled"] is None
def test_jobs_document_schema_and_no_ansi() -> None:
document = jobs_document([_systemd_job(), _cron_job()], ["a warning"])
assert document["schema_version"] == 1
assert len(document["jobs"]) == 2
dumped = json.dumps(document)
assert "\x1b" not in dumped
assert "backup" in dumped
def test_output_table_and_key_values() -> None:
stream = io.StringIO()
output = Output(json_mode=False, color="never", stdout=stream)
output.table(["NAME", "BACKEND"], [["backup", "systemd"], ["cleanup", "cron"]])
text = stream.getvalue()
assert "NAME" in text
assert "backup" in text
assert "\x1b" not in text
def test_output_json_mode() -> None:
stream = io.StringIO()
output = Output(json_mode=True, color="never", stdout=stream)
output.emit_json({"schema_version": 1, "jobs": []})
assert json.loads(stream.getvalue())["schema_version"] == 1
def test_sanitize_text_escapes_control_characters() -> None:
text = "a\x1b[31mred\x1b[0m\nb\tc\x00d\x7f"
assert sanitize_text(text) == "a\\x1b[31mred\\x1b[0m\nb\tc\\x00d\\x7f"
def test_output_write_is_verbatim() -> None:
stream = io.StringIO()
output = Output(color="never", stdout=stream)
output.write("line one\nline two")
assert stream.getvalue() == "line one\nline two"