From 9f939a86c221cdbff0fde711dfdcf76e614872b0 Mon Sep 17 00:00:00 2001 From: Alyssa Dai Date: Tue, 16 Jul 2024 17:05:44 -0400 Subject: [PATCH] add tests of auth utilities and filter irrelevant warnings --- tests/test_app_events.py | 6 ++++ tests/test_attributes.py | 1 + tests/test_security.py | 64 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/test_security.py diff --git a/tests/test_app_events.py b/tests/test_app_events.py index f59e8ba..eaaf001 100644 --- a/tests/test_app_events.py +++ b/tests/test_app_events.py @@ -10,6 +10,7 @@ from app.api import utility as util +@pytest.mark.filterwarnings("ignore:.*NB_API_ALLOWED_ORIGINS") def test_start_app_without_environment_vars_fails( test_app, monkeypatch, disable_auth ): @@ -26,6 +27,7 @@ def test_start_app_without_environment_vars_fails( ) +@pytest.mark.filterwarnings("ignore:.*NB_API_ALLOWED_ORIGINS") def test_app_with_invalid_environment_vars( test_app, monkeypatch, mock_auth_header, set_mock_verify_token ): @@ -116,6 +118,7 @@ def test_app_with_set_allowed_origins( ) +@pytest.mark.filterwarnings("ignore:.*NB_API_ALLOWED_ORIGINS") def test_stored_vocab_lookup_file_created_on_startup( test_app, set_test_credentials, @@ -128,6 +131,7 @@ def test_stored_vocab_lookup_file_created_on_startup( assert term_labels_path.stat().st_size > 0 +@pytest.mark.filterwarnings("ignore:.*NB_API_ALLOWED_ORIGINS") def test_external_vocab_is_fetched_on_startup( test_app, monkeypatch, set_test_credentials, disable_auth ): @@ -170,6 +174,7 @@ def mock_httpx_get(**kwargs): } +@pytest.mark.filterwarnings("ignore:.*NB_API_ALLOWED_ORIGINS") def test_failed_vocab_fetching_on_startup_raises_warning( test_app, monkeypatch, set_test_credentials, disable_auth ): @@ -196,6 +201,7 @@ def mock_httpx_get(**kwargs): ) +@pytest.mark.filterwarnings("ignore:.*NB_API_ALLOWED_ORIGINS") def test_network_error_on_startup_raises_warning( test_app, monkeypatch, set_test_credentials, disable_auth ): diff --git a/tests/test_attributes.py b/tests/test_attributes.py index 9aae833..3be37a2 100644 --- a/tests/test_attributes.py +++ b/tests/test_attributes.py @@ -17,6 +17,7 @@ def test_root(test_app): assert 'documentation' in response.text +@pytest.mark.filterwarnings("ignore:.*NB_API_ALLOWED_ORIGINS") @pytest.mark.parametrize( "valid_data_element_URI", ["nb:Diagnosis", "nb:Assessment"], diff --git a/tests/test_security.py b/tests/test_security.py new file mode 100644 index 0000000..6eb5b32 --- /dev/null +++ b/tests/test_security.py @@ -0,0 +1,64 @@ +import pytest +from fastapi import HTTPException + +from app.api.security import verify_token + + +@pytest.mark.filterwarnings("ignore:.*NB_API_ALLOWED_ORIGINS") +def test_missing_client_id_raises_error_when_auth_enabled( + monkeypatch, test_app, set_test_credentials +): + """Test that a missing client ID raises an error on startup when authentication is enabled.""" + # We're using what should be default values of CLIENT_ID and AUTH_ENABLED here + # (if the corresponding environment variables are unset), + # but we set the values explicitly here for clarity + monkeypatch.setattr("app.api.security.CLIENT_ID", None) + monkeypatch.setattr("app.api.security.AUTH_ENABLED", True) + + with pytest.raises(ValueError) as exc_info: + with test_app: + pass + + assert "NB_QUERY_CLIENT_ID is not set" in str(exc_info.value) + + +@pytest.mark.filterwarnings("ignore:.*NB_API_ALLOWED_ORIGINS") +def test_missing_client_id_ignored_when_auth_disabled( + monkeypatch, test_app, set_test_credentials +): + """Test that a missing client ID does not raise an error when authentication is disabled.""" + monkeypatch.setattr("app.api.security.CLIENT_ID", None) + monkeypatch.setattr("app.api.security.AUTH_ENABLED", False) + + with test_app: + pass + + +@pytest.mark.parametrize( + "invalid_token", + ["Bearer faketoken", "Bearer", "faketoken", "fakescheme faketoken"], +) +def test_invalid_token_raises_error(invalid_token): + """Test that an invalid token raises an error from the verification process.""" + with pytest.raises(HTTPException) as exc_info: + verify_token(invalid_token) + + assert exc_info.value.status_code == 401 + assert "Invalid token" in exc_info.value.detail + + +@pytest.mark.parametrize( + "invalid_auth_header", + [{}, {"Authorization": ""}, {"badheader": "badvalue"}], +) +def test_query_with_malformed_auth_header_fails( + test_app, set_mock_verify_token, invalid_auth_header +): + """Test that a request to the /query route with a missing or malformed authorization header, fails .""" + + response = test_app.get( + "/query/", + headers=invalid_auth_header, + ) + + assert response.status_code == 403