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
This commit is contained in:
Oliver authored and GitHub committed 2026-11-08 17:55:12 +11:00
1 parent 3866f7dbf5
commit df2a5d853e
3 files changed
+110 -12

No files matched your search

+45 -1
View File
@@ -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'<script([^>]*)\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 <script>
if int(match.group(1)) >= 3:
self.assertIn(
'type="module"',
attrs,
f'Redoc {match.group(1)}.x must be loaded as an ES module: {src}',
)
# The schema which Redoc loads must contain generated API data
response = self.client.get(schema_url, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
schema = response.json()
self.assertTrue(schema['openapi'].startswith('3.'))
self.assertEqual(schema['info']['title'], 'InvenTree API')
self.assertIn('/api/part/', schema['paths'])
self.assertIn('/api/stock/', schema['paths'])
self.assertGreater(len(schema['paths']), 100)
@override_settings(
SITE_URL='http://testserver', CSRF_TRUSTED_ORIGINS=['http://testserver']
)