|
| 1 | +import time |
1 | 2 | from typing import TYPE_CHECKING |
2 | 3 |
|
3 | 4 | import pytest |
4 | 5 | from django.urls import reverse |
| 6 | +from django.utils import timezone |
| 7 | +from django.utils.http import http_date |
5 | 8 | from flag_engine.segments.constants import EQUAL |
6 | 9 | from rest_framework import status |
7 | 10 | from rest_framework.test import APIClient |
@@ -175,3 +178,62 @@ def test_get_environment_document_fails_with_invalid_key( |
175 | 178 | # We get a 403 since only the server side API keys are able to access the |
176 | 179 | # environment document |
177 | 180 | assert response.status_code == status.HTTP_403_FORBIDDEN |
| 181 | + |
| 182 | + |
| 183 | +def test_environment_document_if_modified_since( |
| 184 | + organisation_one: "Organisation", |
| 185 | + organisation_one_project_one: "Project", |
| 186 | +) -> None: |
| 187 | + # Given |
| 188 | + project = organisation_one_project_one |
| 189 | + environment = Environment.objects.create(name="Test Environment", project=project) |
| 190 | + api_key = EnvironmentAPIKey.objects.create(environment=environment).key |
| 191 | + |
| 192 | + client = APIClient() |
| 193 | + client.credentials(HTTP_X_ENVIRONMENT_KEY=api_key) |
| 194 | + url = reverse("api-v1:environment-document") |
| 195 | + |
| 196 | + # When - first request |
| 197 | + response1 = client.get(url) |
| 198 | + |
| 199 | + # Then - first request should return 200 and include Last-Modified header |
| 200 | + assert response1.status_code == status.HTTP_200_OK |
| 201 | + last_modified = response1.headers["Last-Modified"] |
| 202 | + assert last_modified == http_date(environment.updated_at.timestamp()) |
| 203 | + |
| 204 | + # When - second request with If-Modified-Since header |
| 205 | + client.credentials( |
| 206 | + HTTP_X_ENVIRONMENT_KEY=api_key, |
| 207 | + HTTP_IF_MODIFIED_SINCE=last_modified, |
| 208 | + ) |
| 209 | + response2 = client.get(url) |
| 210 | + |
| 211 | + # Then - second request should return 304 Not Modified |
| 212 | + assert response2.status_code == status.HTTP_304_NOT_MODIFIED |
| 213 | + assert len(response2.content) == 0 |
| 214 | + |
| 215 | + # sleep for 1s since If-Modified-Since is only accurate to the nearest second |
| 216 | + # https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/If-Modified-Since |
| 217 | + time.sleep(1) |
| 218 | + |
| 219 | + # When - environment is updated |
| 220 | + environment.updated_at = timezone.now() |
| 221 | + environment.save() |
| 222 | + |
| 223 | + # Then - request with same If-Modified-Since header should return 200 |
| 224 | + response3 = client.get(url) |
| 225 | + assert response3.status_code == status.HTTP_200_OK |
| 226 | + assert response3.headers["Last-Modified"] == http_date( |
| 227 | + environment.updated_at.timestamp() |
| 228 | + ) |
| 229 | + |
| 230 | + # When - request without If-Modified-Since header |
| 231 | + client.credentials( |
| 232 | + HTTP_X_ENVIRONMENT_KEY=api_key, |
| 233 | + HTTP_IF_MODIFIED_SINCE="", |
| 234 | + ) |
| 235 | + response4 = client.get(url) |
| 236 | + |
| 237 | + # Then - actual environment is returned with a 200 |
| 238 | + assert response4.status_code == status.HTTP_200_OK |
| 239 | + assert len(response4.content) > 0 |
0 commit comments