Skip to content

Comments

Add OpenAPI link to navigation bar#301

Merged
vanschelven merged 4 commits intobugsink:mainfrom
jlengrand:add-openapi-link
Jan 11, 2026
Merged

Add OpenAPI link to navigation bar#301
vanschelven merged 4 commits intobugsink:mainfrom
jlengrand:add-openapi-link

Conversation

@jlengrand
Copy link
Contributor

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

Note: This commit was created by AI.... I'm creating a PR to get the CI to run and will review it myself before removing the WIP flag

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 <[email protected]>
@CLAassistant
Copy link

CLAassistant commented Jan 11, 2026

CLA assistant check
All committers have signed the CLA.

@jlengrand
Copy link
Contributor Author

Trying to run tests locally like a good citizen, but the main branch already has failing tests on my system. Looking into it.

    ~/Developer/bugsink    main  python manage.py test                                                                       ✔  bugsink   08:39:36  

Found 284 test(s).
Creating test database for alias 'default'...
Destroying old test database for alias 'default'...
System check identified no issues (0 silenced).
.............................................................................................EE..........E.EEEE..EE........................EE...............................................................................................................................................
======================================================================
ERROR: test_assemble_artifact_bundle (files.tests.FilesTests.test_assemble_artifact_bundle)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/files/tests.py", line 89, in test_assemble_artifact_bundle
    raise Exception(f"Not all artifact bundles found in {SAMPLES_DIR}; I insist on having some to test with.")
Exception: Not all artifact bundles found in ../event-samples; I insist on having some to test with.

======================================================================
ERROR: test_assemble_artifact_bundle_small_chunks (files.tests.FilesTests.test_assemble_artifact_bundle_small_chunks)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/files/tests.py", line 176, in test_assemble_artifact_bundle_small_chunks
    with open(filename, 'rb') as f:
         ~~~~^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '../event-samples/bugsink/artifact_bundles/51a5a327666cf1d11e23adfd55c3becad27ae769.zip'

======================================================================
ERROR: test_envelope_endpoint (ingest.tests.IngestViewTestCase.test_envelope_endpoint)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/ingest/tests.py", line 300, in test_envelope_endpoint
    filename = glob(SAMPLES_DIR + "/bugsink/contexts.json")[0]  # pick a fixed one for reproducibility
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

======================================================================
ERROR: test_envelope_endpoint_event_and_minidump (ingest.tests.IngestViewTestCase.test_envelope_endpoint_event_and_minidump)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/ingest/tests.py", line 342, in test_envelope_endpoint_event_and_minidump
    filename = glob(SAMPLES_DIR + "/bugsink/contexts.json")[0]  # pick a fixed one for reproducibility
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

======================================================================
ERROR: test_envelope_endpoint_minidump_only (ingest.tests.IngestViewTestCase.test_envelope_endpoint_minidump_only)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/ingest/tests.py", line 392, in test_envelope_endpoint_minidump_only
    filename = glob(SAMPLES_DIR + "/minidumps/linux_overflow.dmp")[0]  # pick a fixed one for reproducibility
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

======================================================================
ERROR: test_envelope_endpoint_minidump_only_when_feature_off (ingest.tests.IngestViewTestCase.test_envelope_endpoint_minidump_only_when_feature_off)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/[email protected]/3.14.0_1/Frameworks/Python.framework/Versions/3.14/lib/python3.14/contextlib.py", line 85, in inner
    return func(*args, **kwds)
  File "/Users/julienlengrand-lambert/Developer/bugsink/ingest/tests.py", line 431, in test_envelope_endpoint_minidump_only_when_feature_off
    filename = glob(SAMPLES_DIR + "/minidumps/linux_overflow.dmp")[0]  # pick a fixed one for reproducibility
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

======================================================================
ERROR: test_envelope_endpoint_reused_ids_different_exceptions (ingest.tests.IngestViewTestCase.test_envelope_endpoint_reused_ids_different_exceptions)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/ingest/tests.py", line 518, in test_envelope_endpoint_reused_ids_different_exceptions
    filename = glob(SAMPLES_DIR + "/sentry/mobile1-xen.json")[0]  # this one has 'exception.values[0].type'
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

======================================================================
ERROR: test_filestore (ingest.tests.IngestViewTestCase.test_filestore)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/ingest/tests.py", line 594, in test_filestore
    self.test_envelope_endpoint()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/Users/julienlengrand-lambert/Developer/bugsink/ingest/tests.py", line 300, in test_envelope_endpoint
    filename = glob(SAMPLES_DIR + "/bugsink/contexts.json")[0]  # pick a fixed one for reproducibility
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

======================================================================
ERROR: test_ingest_eviction (ingest.tests.IngestViewTestCase.test_ingest_eviction)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/ingest/tests.py", line 623, in test_ingest_eviction
    known_broken = [SAMPLES_DIR + "/" + s.strip() for s in _readlines(SAMPLES_DIR + "/KNOWN-BROKEN")]
                                                           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/julienlengrand-lambert/Developer/bugsink/ingest/tests.py", line 61, in _readlines
    with open(filename) as f:
         ~~~~^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '../event-samples/KNOWN-BROKEN'

======================================================================
ERROR: test_many_issues_ingest_and_show (issues.tests.IntegrationTest.test_many_issues_ingest_and_show)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/issues/tests.py", line 482, in test_many_issues_ingest_and_show
    known_broken = [SAMPLES_DIR + "/" + s.strip() for s in _readlines(SAMPLES_DIR + "/KNOWN-BROKEN")]
                                                           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/julienlengrand-lambert/Developer/bugsink/issues/tests.py", line 46, in _readlines
    with open(filename) as f:
         ~~~~^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '../event-samples/KNOWN-BROKEN'

======================================================================
ERROR: test_render_stacktrace_md (issues.tests.IntegrationTest.test_render_stacktrace_md)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/julienlengrand-lambert/Developer/bugsink/issues/tests.py", line 575, in test_render_stacktrace_md
    with open(filename) as f:
         ~~~~^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '../event-samples/bugsink/frames-with-missing-info.json'

----------------------------------------------------------------------
Ran 284 tests in 9.139s

FAILED (errors=11)
Destroying test database for alias 'default'...

@jlengrand
Copy link
Contributor Author

EDIT : Alright I see in the CI files that tests depend on the bugsink/event-samples repo.

@jlengrand
Copy link
Contributor Author

Much better. Tests passing now

    ~/Dev/bugsink    main  python manage.py test                                   ✔  bugsink   08:44:59  
Found 284 test(s).
Creating test database for alias 'default'...
Destroying old test database for alias 'default'...
System check identified no issues (0 silenced).
.....................................................................................................................................................................................................
----------------------------------------------------------------------
Ran 284 tests in 27.519s

OK
Destroying test database for alias 'default'...

@jlengrand
Copy link
Contributor Author

jlengrand commented Jan 11, 2026

From a feature perspective, I do see the link showing when running the application. Both as super user and normal user.

admin

image

non admin

image

(linking to the correct URL)

image

Now my new tests are failing. Let's see if I can fix them myself, as a python n00b, or if I remove them (given it seems there was no link related tests before :)).

@jlengrand
Copy link
Contributor Author

  • I've changed the tests so they make sense, ensuring link access it correct for admins, normal users and anonymous users.
  • Decided to make the API only visible for logged in users (which makes most sense to me?)
  • For the tests to pass, I've had to mock the atomic_value and phone_home arguments. Being a non Python / Django developer, I am unsure whether that is accessible. Probably you have a better solution.

@jlengrand jlengrand changed the title WIP : Add OpenAPI link to navigation bar Add OpenAPI link to navigation bar Jan 11, 2026
@vanschelven
Copy link
Contributor

vanschelven commented Jan 11, 2026

Thanks! This is indeed a very good idea for visibility of the API.

Regarding the mocking, I have a more idiomatic solution. if you click the button described here I'll push it to the branch. EDIT: nevermind this was already so

@vanschelven vanschelven merged commit e4989cf into bugsink:main Jan 11, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants