agenda/tests/test_geomob_recording.py

89 lines
3.4 KiB
Python

"""Check automatic Geomob recording and failure notifications."""
import subprocess
from datetime import date
from unittest.mock import patch
import pytest
from agenda.geomob import GeomobEvent, geomob_email, record_event
EVENT = GeomobEvent(date(2026, 10, 15), "/post/oct-2026", "#geomobLON")
BASE_URL = "https://thegeomob.com"
def test_record_event_success() -> None:
"""Validate before committing, and restrict the commit to conferences."""
with (
patch("agenda.geomob.subprocess.run") as run,
patch("agenda.add_new_conference.add_new_conference", return_value=True) as add,
):
run.return_value.stdout = ""
result = record_event(EVENT, BASE_URL)
commands = [call.args[0] for call in run.call_args_list]
assert commands[1] == ["git", "pull", "--rebase"]
assert commands[2][0] == "python3"
assert commands[2][1].endswith("/validate_yaml.py")
assert commands[3] == ["git", "add", "--", "conferences.yaml"]
assert commands[4][0:3] == ["git", "commit", "--only"]
assert commands[-1] == ["git", "push"]
add.assert_called_once()
assert "committed and pushed" in result
@pytest.mark.parametrize("failed_call", [1, 2, 3, 4, 5])
def test_command_failure_stops_workflow(failed_call: int) -> None:
"""Every command failure appears in the email and stops later commands."""
success = subprocess.CompletedProcess(["git"], 0, stdout="", stderr="")
error = subprocess.CalledProcessError(1, ["failed"], stderr="failure details")
with (
patch(
"agenda.geomob.subprocess.run",
side_effect=[success] * failed_call + [error],
) as run,
patch("agenda.add_new_conference.add_new_conference", return_value=True),
):
result = record_event(EVENT, BASE_URL)
assert run.call_count == failed_call + 1
assert "FAILED" in result
assert "failure details" in result
_, body = geomob_email([EVENT], BASE_URL, {EVENT: result})
assert result in body
def test_dirty_repository() -> None:
"""Do not pull or add a conference over existing edits."""
with (
patch("agenda.geomob.subprocess.run") as run,
patch("agenda.add_new_conference.add_new_conference") as add,
):
run.return_value.stdout = " M conferences.yaml"
assert "uncommitted changes" in record_event(EVENT, BASE_URL)
assert run.call_count == 1
add.assert_not_called()
def test_add_failure() -> None:
"""Generation errors are reported without validating or committing."""
with (
patch("agenda.geomob.subprocess.run") as run,
patch(
"agenda.add_new_conference.add_new_conference",
side_effect=ValueError("bad event"),
),
):
run.return_value.stdout = ""
assert "FAILED at add conference: bad event" in record_event(EVENT, BASE_URL)
assert run.call_count == 2
def test_duplicate_event() -> None:
"""Existing events still validate and push without an empty commit."""
with (
patch("agenda.geomob.subprocess.run") as run,
patch("agenda.add_new_conference.add_new_conference", return_value=False),
):
run.return_value.stdout = ""
assert "Already recorded" in record_event(EVENT, BASE_URL)
assert run.call_count == 4
assert run.call_args.args[0] == ["git", "push"]