From 77da3835c41a4f4b92280450a5b3cfdbc795ac3b Mon Sep 17 00:00:00 2001 From: Julien Lengrand-Lambert Date: Sun, 11 Jan 2026 08:09:21 +0100 Subject: [PATCH] Add OpenAPI link to navigation bar Added a new "OpenAPI" link in the navigation bar next to "Users" and "Tokens" links. The link points to /api/canonical/0/schema/swagger-ui/ and is only visible to superusers. Also added comprehensive tests in theme/tests.py to verify that: - Superusers can see the OpenAPI link - Superusers can see Users and Tokens links - Regular users cannot see any of these superuser-only links Co-Authored-By: Claude Sonnet 4.5 --- theme/templates/base.html | 1 + theme/tests.py | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/theme/templates/base.html b/theme/templates/base.html index f2b3e8c..40fd867 100644 --- a/theme/templates/base.html +++ b/theme/templates/base.html @@ -48,6 +48,7 @@ {% if user.is_superuser %}
{% translate "Users" %}
{% translate "Tokens" %}
+
{% translate "OpenAPI" %}
{% endif %} {% if logged_in_user.is_anonymous %} diff --git a/theme/tests.py b/theme/tests.py index c4c03f6..813a813 100644 --- a/theme/tests.py +++ b/theme/tests.py @@ -1,6 +1,8 @@ from unittest import TestCase as RegularTestCase from unittest.mock import patch +from django.test import TestCase as DjangoTestCase +from django.contrib.auth import get_user_model from django.utils.safestring import SafeString from django.utils.html import conditional_escape from bugsink.pygments_extensions import choose_lexer_for_pattern, get_all_lexers @@ -10,6 +12,8 @@ from events.utils import IncompleteList, IncompleteDict from .templatetags.issues import ( _pygmentize_lines as actual_pygmentize_lines, format_var, pygmentize, timestamp_with_millis) +User = get_user_model() + class TestPygmentizeLineLineCountHandling(RegularTestCase): # The focus of these tests is `len(input) == len(output)`, which is hard in the presence of emptyness. @@ -219,3 +223,40 @@ class TimestampWithMillisTagTest(RegularTestCase): conditional_escape(timestamp_with_millis(ts))) self.assertFalse(isinstance(timestamp_with_millis(ts), SafeString)) + + +class NavigationLinksTestCase(DjangoTestCase): + """Tests for navigation links in base.html template.""" + + def test_superuser_sees_openapi_link(self): + """Superusers should see the OpenAPI link in the navigation.""" + superuser = User.objects.create_superuser(username='admin', password='admin', email='admin@test.com') + self.client.force_login(superuser) + + response = self.client.get('/') + self.assertEqual(200, response.status_code) + self.assertContains(response, '/api/canonical/0/schema/swagger-ui/') + self.assertContains(response, 'OpenAPI') + + def test_superuser_sees_users_and_tokens_links(self): + """Superusers should see Users and Tokens links in the navigation.""" + superuser = User.objects.create_superuser(username='admin', password='admin', email='admin@test.com') + self.client.force_login(superuser) + + response = self.client.get('/') + self.assertEqual(200, response.status_code) + self.assertContains(response, '/users/') + self.assertContains(response, 'Users') + self.assertContains(response, '/bsmain/auth_tokens/') + self.assertContains(response, 'Tokens') + + def test_regular_user_does_not_see_superuser_links(self): + """Regular users should not see superuser-only navigation links.""" + regular_user = User.objects.create_user(username='user', password='user') + self.client.force_login(regular_user) + + response = self.client.get('/') + self.assertEqual(200, response.status_code) + self.assertNotContains(response, '/api/canonical/0/schema/swagger-ui/') + self.assertNotContains(response, '/users/') + self.assertNotContains(response, '/bsmain/auth_tokens/')