176 lines
7.6 KiB
Python
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()
|