File size: 5,368 Bytes
7cc1e9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
"""
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