77
88# --- MOCK EXTERNAL DEPENDENCIES ---
99# Prevent import errors for Azure modules.
10+ from unittest .mock import MagicMock , patch
11+ import pytest
12+ from fastapi .testclient import TestClient
13+
14+ # Mock Azure dependencies to prevent import errors
1015sys .modules ["azure.monitor" ] = MagicMock ()
1116sys .modules ["azure.monitor.events.extension" ] = MagicMock ()
1217sys .modules ["azure.monitor.opentelemetry" ] = MagicMock ()
1318
19+
1420# Set required environment variables
21+ # Mock environment variables before importing app
1522os .environ ["COSMOSDB_ENDPOINT" ] = "https://mock-endpoint"
1623os .environ ["COSMOSDB_KEY" ] = "mock-key"
1724os .environ ["COSMOSDB_DATABASE" ] = "mock-database"
2936
3037client = TestClient (app )
3138
32- # --- FAKE CLASSES AND FUNCTIONS ---
3339class FakePlan :
3440 id = "fake_plan_id"
3541 summary = "Fake plan summary"
@@ -114,14 +120,28 @@ async def get_all_messages(self):
114120 "ts" : 123456789 ,
115121 }]
116122
117- # --- PYTEST FIXTURE TO OVERRIDE DEPENDENCIES ---
123+
118124@pytest .fixture (autouse = True )
119125def override_dependencies (monkeypatch ):
120126 # Override authentication so that the headers always yield a valid user.
127+
128+ # Mock telemetry initialization to prevent errors
129+ with patch ("azure.monitor.opentelemetry.configure_azure_monitor" , MagicMock ()):
130+ from src .backend .app import app
131+
132+ # Initialize FastAPI test client
133+ client = TestClient (app )
134+
135+
136+ @pytest .fixture (autouse = True )
137+ def mock_dependencies (monkeypatch ):
138+ """Mock dependencies to simplify tests."""
139+
121140 monkeypatch .setattr (
122141 "src.backend.auth.auth_utils.get_authenticated_user_details" ,
123142 lambda headers : {"user_principal_id" : "mock-user-id" },
124143 )
144+
125145 # Override the agent tools retrieval to return a tool with the expected values.
126146 monkeypatch .setattr (
127147 "src.backend.utils.retrieve_all_agent_tools" ,
@@ -135,25 +155,37 @@ def override_dependencies(monkeypatch):
135155 monkeypatch .setattr ("src.backend.app.initialize_runtime_and_context" , fake_initialize_runtime_and_context )
136156 monkeypatch .setattr ("src.backend.app.CosmosBufferedChatCompletionContext" , FakeCosmos )
137157 monkeypatch .setattr ("src.backend.app.track_event_if_configured" , lambda event , props : None )
138-
139- # --- TEST CASES ---
140- # Note: We remove extra fields (like "user_id") from payloads so that they match the expected schema.
158+
141159
142160def test_input_task_invalid_json ():
143161 invalid_json = "Invalid JSON data"
144162 headers = {"Authorization" : "Bearer mock-token" }
145163 response = client .post ("/input_task" , data = invalid_json , headers = headers )
146164 assert response .status_code == 422
147165 assert "detail" in response .json ()
166+
148167
149168def test_input_task_missing_description ():
150169 payload = {"session_id" : "" }
151170 headers = {"Authorization" : "Bearer mock-token" }
152171 response = client .post ("/input_task" , json = payload , headers = headers )
172+ monkeypatch .setattr (
173+ "src.backend.utils.retrieve_all_agent_tools" ,
174+ lambda : [{"agent" : "test_agent" , "function" : "test_function" }],
175+ )
176+
177+
178+ def test_input_task_invalid_json ():
179+ """Test the case where the input JSON is invalid."""
180+ invalid_json = "Invalid JSON data"
181+
182+ headers = {"Authorization" : "Bearer mock-token" }
183+ response = client .post ("/input_task" , data = invalid_json , headers = headers )
184+
153185 assert response .status_code == 422
154186 assert "detail" in response .json ()
155187
156-
188+
157189def test_human_feedback_valid ():
158190 payload = {
159191 "step_id" : "step1" ,
@@ -301,7 +333,37 @@ def test_get_plans_not_found():
301333 headers = {"Authorization" : "Bearer mock-token" }
302334 response = client .get ("/plans" , params = {"session_id" : "nonexistent" }, headers = headers )
303335 assert response .status_code == 404
304- assert response .json ()["detail" ] == "Plan not found"
336+
337+
338+ def test_input_task_missing_description ():
339+ """Test the case where the input task description is missing."""
340+ input_task = {
341+ "session_id" : None ,
342+ "user_id" : "mock-user-id" ,
343+ }
344+
345+ headers = {"Authorization" : "Bearer mock-token" }
346+ response = client .post ("/input_task" , json = input_task , headers = headers )
347+
348+ # Assert response for missing description
349+ assert response .status_code == 422
350+ assert "detail" in response .json ()
351+
352+
353+ def test_basic_endpoint ():
354+ """Test a basic endpoint to ensure the app runs."""
355+ response = client .get ("/" )
356+ assert response .status_code == 404 # The root endpoint is not defined
357+
358+
359+ def test_input_task_empty_description ():
360+ """Tests if /input_task handles an empty description."""
361+ empty_task = {"session_id" : None , "user_id" : "mock-user-id" , "description" : "" }
362+ headers = {"Authorization" : "Bearer mock-token" }
363+ response = client .post ("/input_task" , json = empty_task , headers = headers )
364+
365+ assert response .status_code == 422
366+ assert "detail" in response .json () # Assert error message for missing description
305367
306368
307369if __name__ == "__main__" :
0 commit comments