From e529ad60fa70c37eb14935aaeea47221f55949b2 Mon Sep 17 00:00:00 2001 From: Alex Blank Date: Mon, 27 Jul 2026 20:17:59 +0200 Subject: [PATCH] test(v2): define repository initialization contract --- tests/integration/test_repositories.py | 62 ++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 tests/integration/test_repositories.py diff --git a/tests/integration/test_repositories.py b/tests/integration/test_repositories.py new file mode 100644 index 0000000..f232d6f --- /dev/null +++ b/tests/integration/test_repositories.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +from pathlib import Path + +import httpx +import pytest + +from backup_tool.api.app import create_app +from backup_tool.config import Settings + + +@pytest.mark.asyncio +async def test_admin_can_create_and_inspect_allowlisted_repository(tmp_path: Path) -> None: + key = tmp_path / "key" + key.write_bytes(b"x" * 32) + key.chmod(0o600) + root = tmp_path / "repos" + root.mkdir() + settings = Settings( + repository_roots=(root,), + local_source_roots=(tmp_path,), + restore_roots=(tmp_path,), + master_key_file=key, + data_dir=tmp_path, + database_url=f"sqlite+aiosqlite:///{tmp_path / 'db.sqlite'}", + ) + app = create_app(settings) + from backup_tool.db.models import Base + + async with app.state.engine.begin() as connection: + await connection.run_sync(Base.metadata.create_all) + transport = httpx.ASGITransport(app=app) + async with httpx.AsyncClient(transport=transport, base_url="https://test") as client: + setup = await client.post( + "/api/v2/setup", json={"username": "admin", "password": "a secure password"} + ) + assert setup.status_code == 201 + csrf = client.cookies["backup_tool_csrf"] + created = await client.post( + "/api/v2/repositories", + json={ + "name": "main", + "relative_path": "main", + "compression": "none", + "encryption": "none", + }, + headers={"X-CSRF-Token": csrf}, + ) + assert created.status_code == 201, created.text + body = created.json() + assert body["name"] == "main" + assert body["format_version"] == 1 + assert (root / "main" / "repository.json").is_file() + got = await client.get(f"/api/v2/repositories/{body['id']}") + assert got.status_code == 200 + changed = await client.patch( + f"/api/v2/repositories/{body['id']}", + json={"compression": "gzip"}, + headers={"X-CSRF-Token": csrf}, + ) + assert changed.status_code == 409 + await app.state.engine.dispose()