from pathlib import Path from flask import Flask ROOT = Path(__file__).resolve().parents[1] def _client(): from routes.cicd_routes import cicd_bp app = Flask(__name__, template_folder=str(ROOT / "templates")) app.register_blueprint(cicd_bp) return app.test_client() def test_cicd_routes_do_not_execute_legacy_cluster_commands(): source = (ROOT / "routes" / "cicd_routes.py").read_text(encoding="utf-8") assert "kubectl" not in source assert "rollout restart" not in source assert "rollout undo" not in source assert "get_k8s_pods_status" not in source assert "execute_uat_rollback" not in source assert "execute_gcp_rollback" not in source def test_cicd_restart_pods_action_is_rejected(monkeypatch): from routes import cicd_routes def fail_if_called(*args, **kwargs): raise AssertionError("legacy cluster subprocess should not be called") monkeypatch.setattr(cicd_routes.subprocess, "run", fail_if_called) response = _client().post( "/api/cicd/auto-fix", json={"action": "restart_pods", "environment": "uat"}, ) assert response.status_code == 400 assert response.get_json()["success"] is False def test_cicd_rollback_is_disabled(monkeypatch): from routes import cicd_routes def fail_if_called(*args, **kwargs): raise AssertionError("legacy cluster subprocess should not be called") monkeypatch.setattr(cicd_routes.subprocess, "run", fail_if_called) response = _client().post("/api/cicd/rollback", json={"environment": "uat"}) assert response.status_code == 410 payload = response.get_json() assert payload["success"] is False assert "Docker Compose" in payload["error"] def test_cicd_diagnosis_uses_runtime_note_without_cluster_probe(monkeypatch): from routes import cicd_routes class FakeResponse: status_code = 200 elapsed = type("Elapsed", (), {"total_seconds": lambda self: 0.05})() def json(self): return {"status": "healthy", "version": "test"} def fake_get(*args, **kwargs): return FakeResponse() def fail_if_called(*args, **kwargs): raise AssertionError("legacy cluster subprocess should not be called") monkeypatch.setattr(cicd_routes.requests, "get", fake_get) monkeypatch.setattr(cicd_routes.subprocess, "run", fail_if_called) diagnosis = cicd_routes.run_diagnosis("uat") runtime_checks = [check for check in diagnosis["checks"] if check["name"] == "執行環境狀態"] assert runtime_checks assert runtime_checks[0]["runtime"] == "Docker Compose on 192.168.0.188" def test_cicd_gitlab_api_is_quiet_when_legacy_integration_disabled(monkeypatch): from routes import cicd_routes def fail_if_called(*args, **kwargs): raise AssertionError("disabled GitLab integration should not call network or SSH") monkeypatch.setattr(cicd_routes, "GITLAB_ENABLED", False) monkeypatch.setattr(cicd_routes.requests, "get", fail_if_called) monkeypatch.setattr(cicd_routes.subprocess, "run", fail_if_called) assert cicd_routes.gitlab_api("/projects/1/pipelines") is None assert cicd_routes.get_recent_pipelines(limit=3) == []