"""GET/POST /api/admin/matrix-editor — Superadmin Export/Import.""" from __future__ import annotations import os from unittest.mock import MagicMock, patch import pytest from fastapi.testclient import TestClient os.environ.setdefault("SKIP_DB_MIGRATE", "1") from auth import require_auth from main import app @pytest.fixture def client() -> TestClient: return TestClient(app) @pytest.fixture(autouse=True) def _clear_overrides(): yield app.dependency_overrides.pop(require_auth, None) def test_matrix_editor_export_requires_superadmin(client: TestClient) -> None: def _admin(): return {"profile_id": 1, "role": "admin"} app.dependency_overrides[require_auth] = _admin r = client.get("/api/admin/matrix-editor/export", headers={"X-Auth-Token": "t"}) assert r.status_code == 403 @patch("routers.matrix_editor._load_editor_payload") def test_matrix_editor_export_json_ok(mock_load, client: TestClient) -> None: def _superadmin(): return {"profile_id": 1, "role": "superadmin"} app.dependency_overrides[require_auth] = _superadmin mock_load.return_value = { "skills": [{"skill_key": "a|b|Test", "skill_name": "Test", "description": "x", "level_definitions": {}}], "skills_csv_rows": [], "maturity_models": [], "matrix_csv_rows": [], } mock_cm = MagicMock() mock_cm.__enter__.return_value = MagicMock() mock_cm.__exit__.return_value = False with patch("routers.matrix_editor.get_db", return_value=mock_cm), patch( "routers.matrix_editor.get_cursor", return_value=MagicMock() ): r = client.get("/api/admin/matrix-editor/export", headers={"X-Auth-Token": "t"}) assert r.status_code == 200 body = r.json() assert body["kind"] == "shinkan.matrix_editor.v1" assert len(body["skills"]) == 1 @patch("routers.matrix_editor._load_editor_payload") def test_matrix_editor_export_csv_skills(mock_load, client: TestClient) -> None: def _superadmin(): return {"profile_id": 1, "role": "superadmin"} app.dependency_overrides[require_auth] = _superadmin mock_load.return_value = { "skills": [], "skills_csv_rows": [ { "skill_key": "main|sub|Skill A", "main_category": "Main", "subcategory": "Sub", "skill_name": "Skill A", "description": "Desc", "importance": 3, "karate_relevance": "", "relevance_level": "", "level_1": "L1", "level_2": "", "level_3": "", "level_4": "", "level_5": "", } ], "maturity_models": [], "matrix_csv_rows": [], } mock_cm = MagicMock() mock_cm.__enter__.return_value = MagicMock() mock_cm.__exit__.return_value = False with patch("routers.matrix_editor.get_db", return_value=mock_cm), patch( "routers.matrix_editor.get_cursor", return_value=MagicMock() ): r = client.get( "/api/admin/matrix-editor/export?format=csv_skills", headers={"X-Auth-Token": "t"}, ) assert r.status_code == 200 assert "skill_key" in r.text assert "Skill A" in r.text @patch("routers.matrix_editor._apply_matrix_import", return_value=0) @patch("routers.matrix_editor._apply_skills_import", return_value=1) @patch("routers.matrix_editor._build_model_lookup", return_value={}) @patch("routers.matrix_editor._build_skill_lookup", return_value={"main|sub|Skill A": 42}) def test_matrix_editor_import_json_ok( mock_skill_lookup, mock_model_lookup, mock_apply_skills, mock_apply_matrix, client: TestClient, ) -> None: def _superadmin(): return {"profile_id": 1, "role": "superadmin"} app.dependency_overrides[require_auth] = _superadmin mock_cm = MagicMock() mock_conn = MagicMock() mock_cm.__enter__.return_value = mock_conn mock_cm.__exit__.return_value = False with patch("routers.matrix_editor.get_db", return_value=mock_cm), patch( "routers.matrix_editor.get_cursor", return_value=MagicMock() ): r = client.post( "/api/admin/matrix-editor/import", headers={"X-Auth-Token": "t", "Content-Type": "application/json"}, json={ "kind": "shinkan.matrix_editor.v1", "skills": [{"skill_key": "main|sub|Skill A", "description": "Neu"}], }, ) assert r.status_code == 200 body = r.json() assert body["ok"] is True assert body["skills_updated"] == 1