Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion registration/templates/registration/utility_pages.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
<script src="{% static 'js/jquery.loadTemplate.min.js' %}"></script>
<script src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'js/address-fields.js' %}"></script>
<script src="{% static 'js/validator.js' %}"></script>
<script src="{% static 'js/main.js' %}"></script>

{% block javascript %}
Expand Down
75 changes: 75 additions & 0 deletions registration/tests/test_maintenance_mode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import shutil
import tempfile
from http import HTTPStatus
from pathlib import Path

from django.test import SimpleTestCase, override_settings


class MaintenanceModeTest(SimpleTestCase):
"""Test that django-maintenance-mode works as configured.

Uses SimpleTestCase (no database) since maintenance mode is purely
middleware-based and doesn't require DB access.
"""

def setUp(self):

Check failure

Code scanning / SonarCloud

Insecure temporary file creation methods should not be used High test

'tempfile.mktemp' is insecure. Use 'tempfile.TemporaryFile' instead See more on SonarQube Cloud
self._tmp_dir = tempfile.mkdtemp()
self.state_file = Path(self._tmp_dir) / "maintenance_mode_state.txt"
self.state_file.write_text("0")

def tearDown(self):
shutil.rmtree(self._tmp_dir, ignore_errors=True)

def _enable_maintenance(self):
self.state_file.write_text("1")

def _disable_maintenance(self):
self.state_file.write_text("0")

@override_settings(MAINTENANCE_MODE=True)
def test_maintenance_mode_returns_503(self):
"""When maintenance mode is on, normal pages return 503."""
response = self.client.get("/registration/")
self.assertEqual(response.status_code, HTTPStatus.SERVICE_UNAVAILABLE)

@override_settings(MAINTENANCE_MODE=True)
def test_maintenance_page_renders_without_error(self):
"""The 503 maintenance template renders successfully (no missing static files)."""
response = self.client.get("/registration/")
self.assertEqual(response.status_code, HTTPStatus.SERVICE_UNAVAILABLE)
self.assertIn(b"maintenance", response.content.lower())

@override_settings(MAINTENANCE_MODE=False)
def test_normal_mode_does_not_return_503(self):
"""When maintenance mode is off, pages are not blocked by maintenance middleware."""
self.client.raise_request_exception = False
response = self.client.get("/registration/")
self.assertNotEqual(response.status_code, HTTPStatus.SERVICE_UNAVAILABLE)

@override_settings(MAINTENANCE_MODE=True, MAINTENANCE_MODE_IGNORE_ADMIN_SITE=True)
def test_admin_site_accessible_during_maintenance(self):
"""Admin site is reachable even during maintenance (per MAINTENANCE_MODE_IGNORE_ADMIN_SITE)."""
response = self.client.get("/admin/login/")
self.assertNotEqual(response.status_code, HTTPStatus.SERVICE_UNAVAILABLE)

@override_settings(
MAINTENANCE_MODE=True, MAINTENANCE_MODE_IGNORE_URLS=("^/accounts/",)
)
def test_ignored_urls_accessible_during_maintenance(self):
"""URLs matching MAINTENANCE_MODE_IGNORE_URLS are accessible during maintenance."""
self.client.raise_request_exception = False
response = self.client.get("/accounts/login/")
self.assertNotEqual(response.status_code, HTTPStatus.SERVICE_UNAVAILABLE)

def test_state_file_controls_maintenance_mode(self):
"""The file-based state backend enables/disables maintenance mode."""
self.client.raise_request_exception = False
with self.settings(MAINTENANCE_MODE_STATE_FILE_PATH=str(self.state_file)):
self._disable_maintenance()
response = self.client.get("/registration/")
self.assertNotEqual(response.status_code, HTTPStatus.SERVICE_UNAVAILABLE)

self._enable_maintenance()
response = self.client.get("/registration/")
self.assertEqual(response.status_code, HTTPStatus.SERVICE_UNAVAILABLE)