From df2a5d853e54859ceeb9ca4655b826c08be21e60 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 8 Nov 2026 17:55:12 +1100 Subject: [PATCH] Add CI checks for /api-doc/ endpoint (#13210) * Add CI checks for /api-doc/ endpoint Ref: https://github.com/inventree/InvenTree/issues/13200 * fix playwright test * Reduce flakiness --- src/backend/InvenTree/InvenTree/test_views.py | 46 ++++++++++++++++- src/frontend/tests/helpers.ts | 27 +++++++++- src/frontend/tests/pui_general.spec.ts | 49 +++++++++++++++---- 3 files changed, 110 insertions(+), 12 deletions(-) diff --git a/src/backend/InvenTree/InvenTree/test_views.py b/src/backend/InvenTree/InvenTree/test_views.py index d135a57e5c..8c20ee742f 100644 --- a/src/backend/InvenTree/InvenTree/test_views.py +++ b/src/backend/InvenTree/InvenTree/test_views.py @@ -1,6 +1,7 @@ """Unit tests for the main web views.""" import os +import re from django.test import override_settings from django.urls import reverse @@ -18,12 +19,55 @@ class ViewTests(InvenTreeTestCase): SITE_URL='http://testserver', CSRF_TRUSTED_ORIGINS=['http://testserver'] ) def test_api_doc(self): - """Test that the api-doc view works.""" + """Test that the api-doc view renders a usable Redoc page. + + A 200 response alone is not sufficient - the page is a thin HTML shell + which loads Redoc from a CDN and points it at the schema endpoint. + Ref: https://github.com/inventree/InvenTree/issues/13200 + """ api_url = os.path.join(reverse('index'), 'api-doc') + '/' response = self.client.get(api_url) self.assertEqual(response.status_code, 200) + html = response.content.decode() + schema_url = reverse('schema') + + # The page must point Redoc at our schema endpoint + self.assertIn(schema_url, html) + + # Find the Redoc bundle which is loaded by the page + scripts = re.findall(r']*)\ssrc="([^"]+)"', html) + redoc_scripts = [(attrs, src) for attrs, src in scripts if 'redoc' in src] + self.assertEqual(len(redoc_scripts), 1, 'Redoc script not found in api-doc') + + attrs, src = redoc_scripts[0] + + # The Redoc version must be pinned - '@latest' can (and did) change under us + match = re.search(r'redoc@(\d+)(?:\.\d+)*/', src) + self.assertIsNotNone( + match, f'Redoc distribution must be pinned to a version: {src}' + ) + + # Redoc >= 3 is ES-module only and cannot be loaded via a classic