@@ -48,7 +48,14 @@ def mock_pipeline_factory():
4848@pytest .fixture
4949def test_client (mock_pipeline_factory ) -> TestClient :
5050 """Create a test client for the FastAPI application."""
51- app = init_app (mock_pipeline_factory )
51+ app = init_app (mock_pipeline_factory , read_only = False )
52+ return TestClient (app )
53+
54+
55+ @pytest .fixture
56+ def test_client_read_only (mock_pipeline_factory ) -> TestClient :
57+ """Create a test client for the FastAPI application in read-only mode."""
58+ app = init_app (mock_pipeline_factory , read_only = True )
5259 return TestClient (app )
5360
5461
@@ -58,6 +65,12 @@ def test_app_initialization(mock_pipeline_factory) -> None:
5865 assert app is not None
5966 assert app .title == "CodeGate"
6067 assert app .version == __version__
68+ assert hasattr (app , "read_only" )
69+ assert app .read_only is False
70+
71+ # Test with read_only=True
72+ app_read_only = init_app (mock_pipeline_factory , read_only = True )
73+ assert app_read_only .read_only is True
6174
6275
6376def test_cors_middleware (mock_pipeline_factory ) -> None :
@@ -96,6 +109,12 @@ def test_version_endpoint(mock_fetch_latest_version, test_client: TestClient) ->
96109 assert response_data ["is_latest" ] is False
97110
98111
112+ def test_version_endpoint_read_only (test_client_read_only : TestClient ) -> None :
113+ """Test the version endpoint is not available in read-only mode."""
114+ response = test_client_read_only .get ("/api/v1/version" )
115+ assert response .status_code == 404 # Should return 404 Not Found in read-only mode
116+
117+
99118@patch ("codegate.pipeline.secrets.manager.SecretsManager" )
100119@patch ("codegate.server.get_provider_registry" )
101120def test_provider_registration (mock_registry , mock_secrets_mgr , mock_pipeline_factory ) -> None :
@@ -145,6 +164,21 @@ def test_workspaces_routes(mock_pipeline_factory) -> None:
145164 assert len (dashboard_routes ) > 0
146165
147166
167+ def test_read_only_mode (mock_pipeline_factory ) -> None :
168+ """Test that v1 API is not included in read-only mode."""
169+ # Test with read_only=False (default)
170+ app = init_app (mock_pipeline_factory , read_only = False )
171+ routes = [route .path for route in app .routes ]
172+ v1_routes = [route for route in routes if route .startswith ("/api/v1" )]
173+ assert len (v1_routes ) > 0
174+
175+ # Test with read_only=True
176+ app_read_only = init_app (mock_pipeline_factory , read_only = True )
177+ routes_read_only = [route .path for route in app_read_only .routes ]
178+ v1_routes_read_only = [route for route in routes_read_only if route .startswith ("/api/v1" )]
179+ assert len (v1_routes_read_only ) == 0
180+
181+
148182def test_system_routes (mock_pipeline_factory ) -> None :
149183 """Test that system routes are included."""
150184 app = init_app (mock_pipeline_factory )
@@ -469,6 +503,37 @@ def test_serve_certificate_options(cli_runner: CliRunner) -> None:
469503 ), f"{ key } does not match expected value"
470504
471505
506+ def test_serve_read_only_mode (cli_runner : CliRunner ) -> None :
507+ """Test serve command with read-only mode."""
508+ with (
509+ patch ("src.codegate.cli.setup_logging" ) as mock_setup_logging ,
510+ patch ("src.codegate.cli.init_app" ) as mock_init_app ,
511+ ):
512+ # Mock the init_app function to return a MagicMock
513+ mock_app = MagicMock ()
514+ mock_init_app .return_value = mock_app
515+
516+ # Execute CLI command with read-only flag
517+ result = cli_runner .invoke (
518+ cli ,
519+ [
520+ "serve" ,
521+ "--read-only" ,
522+ ],
523+ )
524+
525+ # Check the result of the command
526+ assert result .exit_code == 0
527+
528+ # Ensure logging setup was called with expected arguments
529+ mock_setup_logging .assert_called_once_with ("INFO" , "JSON" )
530+
531+ # Verify that init_app was called with read_only=True
532+ mock_init_app .assert_called_once ()
533+ _ , kwargs = mock_init_app .call_args
534+ assert kwargs .get ("read_only" ) is True
535+
536+
472537def test_main_function () -> None :
473538 """Test main function."""
474539 with patch ("sys.argv" , ["cli" ]), patch ("codegate.cli.cli" ) as mock_cli :
0 commit comments