Wegwichtel/test/python/test_commands.py
Florian Zumpe 95026aac6e
Some checks failed
Sonarqube Scanner / Build and analyze (push) Failing after 22s
fixed sonarqube scan issues
2026-06-17 15:12:46 +02:00

176 lines
7.6 KiB
Python

"""Unit-Tests für alle importierbaren Python-Kommandozeilenwerkzeuge."""
from __future__ import annotations
import importlib
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
ROOT = Path(__file__).resolve().parents[2]
TOOLS = ROOT / "tools" / "python"
sys.path.insert(0, str(TOOLS))
class RecordingClient:
def __init__(self, get_result=None):
self.calls = []
self.get_result = get_result or {}
def request(self, method, path, **kwargs):
self.calls.append((method, path, kwargs))
if method == "GET":
return dict(self.get_result)
return {"method": method, "path": path}
class CommandTests(unittest.TestCase):
def module(self, name):
return importlib.import_module(name)
def run_with_client(self, name, argv, *, get_result=None, extra_patches=()):
module = self.module(name)
client = RecordingClient(get_result)
patches = [patch.object(module, "client_from_args", return_value=client)]
patches.extend(extra_patches)
for current in patches:
current.start()
self.addCleanup(current.stop)
result = module.main(argv)
return result, client
def test_create_and_append_commands(self):
with tempfile.TemporaryDirectory() as directory:
gpx = Path(directory) / "route.gpx"
picture = Path(directory) / "picture.png"
audio = Path(directory) / "audio.mp3"
for file_path in (gpx, picture, audio):
file_path.write_bytes(b"content")
_, client = self.run_with_client("append_route", ["--route-id", "1", "--gpx", str(gpx)])
self.assertEqual(client.calls[0][0:2], ("POST", "/api/routes/1/append"))
_, client = self.run_with_client(
"create_route",
["--gpx", str(gpx), "--name", "Route", "--slug", "route", "--description", "Text", "--school-name", "Schule"],
)
self.assertEqual(client.calls[0][1], "/api/routes")
self.assertEqual(client.calls[0][2]["fields"]["schoolName"], "Schule")
_, client = self.run_with_client("create_audio", ["--route-id", "1", "--poi-id", "2", "--file", str(audio)])
self.assertIn("audio", client.calls[0][2]["files"])
_, client = self.run_with_client(
"create_picture",
["--route-id", "1", "--poi-id", "2", "--file", str(picture), "--caption", "Bild", "--sequence", "3"],
)
self.assertEqual(client.calls[0][2]["fields"], {"caption": "Bild", "sequence": 3})
_, client = self.run_with_client(
"create_poi",
["--route-id", "1", "--title", "POI", "--description", "Text", "--lat", "50.1", "--lon", "10.2", "--trigger-radius", "25", "--sequence", "0"],
)
self.assertEqual(client.calls[0][2]["json_body"]["sequence"], 0)
self.assertEqual(client.calls[0][2]["json_body"]["description"], "Text")
def test_delete_commands_cover_confirmation_and_requests(self):
cases = [
("delete_route", ["--route-id", "1"], "/api/routes/1"),
("delete_poi", ["--route-id", "1", "--poi-id", "2"], "/api/routes/1/pois/2"),
("delete_picture", ["--route-id", "1", "--poi-id", "2", "--picture-id", "3"], "/api/routes/1/pois/2/pictures/3"),
("delete_audio", ["--route-id", "1", "--poi-id", "2"], "/api/routes/1/pois/2/audio"),
]
for name, argv, path in cases:
with self.subTest(name=name, confirmed=False):
module = self.module(name)
result, client = self.run_with_client(
name,
argv,
extra_patches=(patch.object(module, "confirm", return_value=False),),
)
self.assertEqual(result, {"cancelled": True})
self.assertEqual(client.calls, [])
with self.subTest(name=name, confirmed=True):
module = self.module(name)
_, client = self.run_with_client(
name,
argv,
extra_patches=(patch.object(module, "confirm", return_value=True),),
)
self.assertEqual(client.calls[0][0:2], ("DELETE", path))
def test_restore_and_update_commands(self):
_, client = self.run_with_client("restore_route", ["--route-id", "7"])
self.assertEqual(client.calls[0][0:2], ("POST", "/api/routes/7/restore"))
with tempfile.TemporaryDirectory() as directory:
replacement = Path(directory) / "replacement.bin"
replacement.write_bytes(b"content")
_, client = self.run_with_client(
"update_audio", ["--route-id", "1", "--poi-id", "2", "--file", str(replacement)]
)
self.assertEqual(client.calls[0][0], "PUT")
_, client = self.run_with_client(
"update_picture",
["--route-id", "1", "--poi-id", "2", "--picture-id", "3", "--file", str(replacement)],
get_result={"caption": "Alt", "sequence": 4},
extra_patches=(patch.object(self.module("update_picture"), "ask_with_default", side_effect=lambda label, current, cast=str: current),),
)
self.assertEqual([call[0] for call in client.calls], ["GET", "PUT"])
self.assertIn("files", client.calls[1][2])
module = self.module("update_picture")
_, client = self.run_with_client(
"update_picture",
["--route-id", "1", "--poi-id", "2", "--picture-id", "3"],
get_result={"caption": "Alt", "sequence": 4},
extra_patches=(
patch.object(module, "ask_path", return_value=None),
patch.object(module, "ask_with_default", side_effect=lambda label, current, cast=str: current),
),
)
self.assertIn("json_body", client.calls[1][2])
_, client = self.run_with_client(
"update_route",
["--route-id", "1", "--gpx", str(replacement)],
get_result={"name": "Alt", "description": "Text", "schoolName": "Schule"},
extra_patches=(patch.object(self.module("update_route"), "ask_with_default", side_effect=lambda label, current, cast=str: current),),
)
self.assertIn("files", client.calls[1][2])
module = self.module("update_route")
_, client = self.run_with_client(
"update_route",
["--route-id", "1"],
get_result={"name": "Alt", "description": "Text", "schoolName": "Schule"},
extra_patches=(
patch.object(module, "ask_path", return_value=None),
patch.object(module, "ask_with_default", side_effect=lambda label, current, cast=str: current),
),
)
self.assertIn("json_body", client.calls[1][2])
_, client = self.run_with_client(
"update_poi",
["--route-id", "1", "--poi-id", "2"],
get_result={
"title": "Alt",
"description": "Text",
"lat": 50.0,
"lon": 10.0,
"triggerRadiusM": 25.0,
"sequence": 1,
},
extra_patches=(patch.object(self.module("update_poi"), "ask_with_default", side_effect=lambda label, current, cast=str: current),),
)
self.assertEqual(client.calls[1][2]["json_body"]["title"], "Alt")
if __name__ == "__main__":
unittest.main()