""" API endpoint tests for PastCast backend. Tests route handlers, input validation, and error responses. """ import json import pytest class TestHealthEndpoint: """Tests for /health endpoint.""" def test_health_returns_200(self, client): response = client.get("/health") assert response.status_code == 200 def test_health_returns_json(self, client): response = client.get("/health") data = response.get_json() assert data["status"] == "healthy" assert "timestamp" in data assert "model" in data class TestWeatherProbability: """Tests for /weather/probability endpoint.""" def test_missing_location_returns_400(self, client): response = client.post( "/weather/probability", data=json.dumps({"date_range": {"start_date": "2024-06-15"}}), content_type="application/json", ) assert response.status_code == 400 data = response.get_json() assert "error" in data def test_missing_date_range_returns_400(self, client): response = client.post( "/weather/probability", data=json.dumps({ "location": {"latitude": 12.97, "longitude": 77.59, "city_name": "Bengaluru"} }), content_type="application/json", ) assert response.status_code == 400 def test_invalid_latitude_returns_400(self, client): response = client.post( "/weather/probability", data=json.dumps({ "location": {"latitude": 999, "longitude": 77.59}, "date_range": {"start_date": "2024-06-15"}, }), content_type="application/json", ) assert response.status_code == 400 data = response.get_json() assert "latitude" in data["error"].lower() or "out of range" in data["error"].lower() def test_valid_request_returns_200(self, client): response = client.post( "/weather/probability", data=json.dumps({ "location": {"latitude": 12.97, "longitude": 77.59, "city_name": "Bengaluru"}, "date_range": {"start_date": "2024-06-15"}, }), content_type="application/json", ) assert response.status_code == 200 data = response.get_json() assert "probabilities" in data assert "location" in data assert data["location"]["city_name"] == "Bengaluru" def test_response_contains_required_fields(self, client): response = client.post( "/weather/probability", data=json.dumps({ "location": {"latitude": 28.61, "longitude": 77.23, "city_name": "Delhi"}, "date_range": {"start_date": "2024-01-15"}, }), content_type="application/json", ) data = response.get_json() probs = data["probabilities"] assert "rain" in probs assert "extreme_heat" in probs assert "high_wind" in probs assert "cloudy" in probs assert "good_weather" in probs assert "summary" in probs class TestChatEndpoints: """Tests for /api/* chat endpoints.""" def test_create_session(self, client): response = client.post("/api/session") assert response.status_code == 200 data = response.get_json() assert "session_id" in data assert data["status"] == "created" def test_empty_message_rejected(self, client): response = client.post( "/api/message", data=json.dumps({"text": ""}), content_type="application/json", ) data = response.get_json() assert data["reply"] == "Please enter a message." def test_clear_chat(self, client): response = client.post( "/api/clear", data=json.dumps({}), content_type="application/json", ) assert response.status_code == 200 def test_history_endpoint(self, client): response = client.get("/api/history") assert response.status_code == 200 data = response.get_json() assert isinstance(data, list) class TestErrorHandling: """Tests for global error handling.""" def test_404_returns_json(self, client): response = client.get("/nonexistent-endpoint") assert response.status_code == 404 data = response.get_json() assert "error" in data def test_405_returns_json(self, client): response = client.get("/api/session") # GET instead of POST assert response.status_code == 405 data = response.get_json() assert "error" in data class TestInputValidation: """Tests for input sanitisation.""" def test_very_long_input_truncated(self, client): long_text = "A" * 1000 response = client.post( "/api/message", data=json.dumps({"text": long_text}), content_type="application/json", ) assert response.status_code == 200 def test_control_characters_stripped(self, client): response = client.post( "/api/message", data=json.dumps({"text": "Hello\x00\x01World"}), content_type="application/json", ) assert response.status_code == 200