Files
zyrarbot/tests/test_api_surface.py
T

73 lines
2.2 KiB
Python

"""Przypina powierzchnię API - panel jest osobnym klientem, więc kontrakt musi być stabilny."""
from __future__ import annotations
import tempfile
import unittest
from zyrarbot.application import Application
from zyrarbot.settings import Settings
EXPECTED_ENDPOINTS = {
("get", "/api/status"),
("get", "/api/health"),
("post", "/api/play"),
("post", "/api/play_file"),
("post", "/api/pause"),
("post", "/api/resume"),
("post", "/api/skip"),
("post", "/api/stop"),
("post", "/api/volume"),
("post", "/api/loop"),
("post", "/api/loop_playlist"),
("post", "/api/loop_cycle"),
("post", "/api/jump"),
("post", "/api/remove"),
("post", "/api/reorder"),
("post", "/api/queue/plays"),
("get", "/api/uploads"),
("post", "/api/upload"),
("delete", "/api/uploads/{filename}"),
("post", "/api/connect"),
("post", "/api/disconnect"),
}
class ApiSurfaceTest(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls._workdir = tempfile.TemporaryDirectory()
settings = Settings(
discord_token="test",
config_dir=f"{cls._workdir.name}/config",
uploads_dir=f"{cls._workdir.name}/uploads",
static_dir=f"{cls._workdir.name}/static",
)
cls.spec = Application(settings).web.openapi()
@classmethod
def tearDownClass(cls) -> None:
cls._workdir.cleanup()
def _declared(self) -> set[tuple[str, str]]:
return {
(method, path)
for path, operations in self.spec["paths"].items()
for method in operations
}
def test_all_expected_endpoints_are_declared(self):
self.assertEqual(set(), EXPECTED_ENDPOINTS - self._declared())
def test_no_endpoint_added_without_updating_this_test(self):
# Panel jest odrębnym klientem - nowa trasa powinna trafić tu świadomie.
self.assertEqual(set(), self._declared() - EXPECTED_ENDPOINTS)
def test_openapi_document_is_well_formed(self):
self.assertTrue(self.spec["openapi"].startswith("3."))
self.assertIn("ŻyrarBOT", self.spec["info"]["title"])
if __name__ == "__main__":
unittest.main()