File size: 9,274 Bytes
5422df1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
"""Deployment tests for Wall Construction API.

Tests that verify the full stack is properly deployed and functional:
- Database migrations have run successfully
- API endpoints are accessible and return correct status codes
- CRUD operations work end-to-end
- Data persistence works correctly
"""

from __future__ import annotations

import pytest
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient


@pytest.mark.django_db
@pytest.mark.deployment
class TestDeploymentHealth:
    """Test deployment health and basic API functionality."""

    def test_api_root_accessible(self, api_client: APIClient) -> None:
        """Test API root endpoint is accessible."""
        url = "/"

        response = api_client.get(url)

        assert response.status_code in (
            status.HTTP_200_OK,
            status.HTTP_301_MOVED_PERMANENTLY,
            status.HTTP_302_FOUND,
        )

    def test_profiles_endpoint_accessible(self, api_client: APIClient) -> None:
        """Test profiles list endpoint returns 200 with empty database."""
        url = reverse("profile-list")

        response = api_client.get(url)

        assert response.status_code == status.HTTP_200_OK
        assert "results" in response.data
        assert "count" in response.data
        assert isinstance(response.data["results"], list)

    def test_wallsections_endpoint_accessible(self, api_client: APIClient) -> None:
        """Test wallsections list endpoint returns 200 with empty database."""
        url = reverse("wallsection-list")

        response = api_client.get(url)

        assert response.status_code == status.HTTP_200_OK
        assert "results" in response.data
        assert "count" in response.data
        assert isinstance(response.data["results"], list)


@pytest.mark.django_db
@pytest.mark.deployment
class TestDeploymentEndToEnd:
    """Test end-to-end workflows to verify deployment integrity."""

    def test_create_profile_and_retrieve(self, api_client: APIClient) -> None:
        """Test creating a profile and retrieving it verifies database works."""
        list_url = reverse("profile-list")

        # Create profile
        create_payload = {
            "name": "Deployment Test Profile",
            "team_lead": "Test Lead",
            "is_active": True,
        }
        create_response = api_client.post(list_url, create_payload, format="json")

        assert create_response.status_code == status.HTTP_201_CREATED
        assert create_response.data["name"] == "Deployment Test Profile"
        assert "id" in create_response.data

        profile_id = create_response.data["id"]

        # Retrieve profile
        detail_url = reverse("profile-detail", kwargs={"pk": profile_id})
        retrieve_response = api_client.get(detail_url)

        assert retrieve_response.status_code == status.HTTP_200_OK
        assert retrieve_response.data["id"] == profile_id
        assert retrieve_response.data["name"] == "Deployment Test Profile"
        assert retrieve_response.data["team_lead"] == "Test Lead"

    def test_create_wallsection_with_profile(self, api_client: APIClient) -> None:
        """Test creating wallsection with profile verifies foreign keys work."""
        # Create profile first
        profile_url = reverse("profile-list")
        profile_payload = {"name": "Wall Builder", "team_lead": "Builder Lead"}
        profile_response = api_client.post(
            profile_url,
            profile_payload,
            format="json",
        )
        assert profile_response.status_code == status.HTTP_201_CREATED
        profile_id = profile_response.data["id"]

        # Create wallsection
        wallsection_url = reverse("wallsection-list")
        wallsection_payload = {
            "profile": profile_id,
            "section_name": "Section 1",
        }
        wallsection_response = api_client.post(
            wallsection_url,
            wallsection_payload,
            format="json",
        )

        assert wallsection_response.status_code == status.HTTP_201_CREATED
        assert wallsection_response.data["profile"] == profile_id
        assert wallsection_response.data["section_name"] == "Section 1"
        assert "id" in wallsection_response.data

    def test_list_profiles_after_creation(self, api_client: APIClient) -> None:
        """Test listing profiles returns created profiles."""
        url = reverse("profile-list")

        # Create multiple profiles
        for i in range(3):
            payload = {
                "name": f"Profile {i}",
                "team_lead": f"Lead {i}",
            }
            create_response = api_client.post(url, payload, format="json")
            assert create_response.status_code == status.HTTP_201_CREATED

        # List all profiles
        list_response = api_client.get(url)

        assert list_response.status_code == status.HTTP_200_OK
        assert list_response.data["count"] == 3
        assert len(list_response.data["results"]) == 3

    def test_update_profile(self, api_client: APIClient) -> None:
        """Test updating a profile verifies write operations work."""
        # Create profile
        list_url = reverse("profile-list")
        create_payload = {"name": "Original Name", "team_lead": "Original Lead"}
        create_response = api_client.post(list_url, create_payload, format="json")
        assert create_response.status_code == status.HTTP_201_CREATED
        profile_id = create_response.data["id"]

        # Update profile
        detail_url = reverse("profile-detail", kwargs={"pk": profile_id})
        update_payload = {
            "name": "Updated Name",
            "team_lead": "Updated Lead",
            "is_active": False,
        }
        update_response = api_client.put(detail_url, update_payload, format="json")

        assert update_response.status_code == status.HTTP_200_OK
        assert update_response.data["name"] == "Updated Name"
        assert update_response.data["team_lead"] == "Updated Lead"
        assert update_response.data["is_active"] is False

    def test_delete_profile(self, api_client: APIClient) -> None:
        """Test deleting a profile verifies delete operations work."""
        # Create profile
        list_url = reverse("profile-list")
        create_payload = {"name": "To Delete", "team_lead": "Delete Lead"}
        create_response = api_client.post(list_url, create_payload, format="json")
        assert create_response.status_code == status.HTTP_201_CREATED
        profile_id = create_response.data["id"]

        # Delete profile
        detail_url = reverse("profile-detail", kwargs={"pk": profile_id})
        delete_response = api_client.delete(detail_url)

        assert delete_response.status_code == status.HTTP_204_NO_CONTENT

        # Verify deletion
        retrieve_response = api_client.get(detail_url)
        assert retrieve_response.status_code == status.HTTP_404_NOT_FOUND


@pytest.mark.django_db
@pytest.mark.deployment
class TestDatabaseMigrations:
    """Test that database migrations have been applied correctly."""

    def test_profile_model_exists(self, api_client: APIClient) -> None:
        """Test Profile model table exists and is accessible."""
        url = reverse("profile-list")

        response = api_client.get(url)

        assert response.status_code == status.HTTP_200_OK

    def test_wallsection_model_exists(self, api_client: APIClient) -> None:
        """Test WallSection model table exists and is accessible."""
        url = reverse("wallsection-list")

        response = api_client.get(url)

        assert response.status_code == status.HTTP_200_OK

    def test_profile_fields_exist(self, api_client: APIClient) -> None:
        """Test Profile model has all required fields."""
        url = reverse("profile-list")
        payload = {
            "name": "Field Test",
            "team_lead": "Test Lead",
            "is_active": True,
        }

        response = api_client.post(url, payload, format="json")

        assert response.status_code == status.HTTP_201_CREATED
        assert "id" in response.data
        assert "name" in response.data
        assert "team_lead" in response.data
        assert "is_active" in response.data
        assert "created_at" in response.data
        assert "updated_at" in response.data

    def test_wallsection_fields_exist(self, api_client: APIClient) -> None:
        """Test WallSection model has all required fields."""
        # Create profile first
        profile_url = reverse("profile-list")
        profile_response = api_client.post(
            profile_url,
            {"name": "Test", "team_lead": "Lead"},
            format="json",
        )
        profile_id = profile_response.data["id"]

        # Create wallsection
        url = reverse("wallsection-list")
        payload = {
            "profile": profile_id,
            "section_name": "Test Section",
        }

        response = api_client.post(url, payload, format="json")

        assert response.status_code == status.HTTP_201_CREATED
        assert "id" in response.data
        assert "profile" in response.data
        assert "section_name" in response.data
        assert "created_at" in response.data