From 5d6f2899b6e5abee3438f2733d7b97e868343ab3 Mon Sep 17 00:00:00 2001 From: Dan Jones <dan.jones@noc.ac.uk> Date: Thu, 9 Feb 2023 10:31:49 +0000 Subject: [PATCH] tests: coverage for api notify and receive + fix to max_messages query string handling --- api_notify_test.py | 59 ++++++++++++++++++++++++++ api_receive_test.py | 98 ++++++++++++++++++++++++++++++++++++++++++++ conftest.py | 14 ++++++- endpoints/receive.py | 3 +- 4 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 api_notify_test.py create mode 100644 api_receive_test.py diff --git a/api_notify_test.py b/api_notify_test.py new file mode 100644 index 0000000..164ee0a --- /dev/null +++ b/api_notify_test.py @@ -0,0 +1,59 @@ +import flask +import json +import pytest +from unittest.mock import patch, mock_open, call +from werkzeug.exceptions import HTTPException +from api import create_app +from endpoints import notify +from conftest import get_auth_header + + +@pytest.mark.usefixtures( + "mock_clients", "mock_client_credentials", "mock_post_notify", "mock_message_notify" +) +def test_post_notify( + mock_clients, mock_client_credentials, mock_post_notify, mock_message_notify +): + app = create_app() + with patch( + "builtins.open", mock_open(read_data=json.dumps(mock_clients)) + ) as mock_file_open, patch.object( + notify, "write_to_queue" + ) as mock_write_to_queue, app.test_client() as app_test_client: + auth_header = get_auth_header(app_test_client, mock_client_credentials) + response = app_test_client.post( + "/notify", json=mock_post_notify, headers=auth_header + ) + assert response.status_code == 200 + mock_write_to_queue.assert_called_once_with( + queue_name="client-1-broadcast", msg=json.dumps(mock_message_notify) + ) + + +@pytest.mark.usefixtures("mock_clients", "mock_post_notify") +def test_post_send_no_token(mock_clients, mock_post_notify): + app = create_app() + with patch( + "builtins.open", mock_open(read_data=json.dumps(mock_clients)) + ) as mock_file_open, patch.object( + notify, "write_to_queue" + ) as mock_write_to_queue, app.test_client() as app_test_client: + response = app_test_client.post("/notify", json=mock_post_notify) + assert response.status_code == 403 + mock_write_to_queue.assert_not_called() + + +@pytest.mark.usefixtures("mock_clients", "mock_post_notify") +def test_post_send_invalid_token(mock_clients, mock_post_notify): + app = create_app() + with patch( + "builtins.open", mock_open(read_data=json.dumps(mock_clients)) + ) as mock_file_open, patch.object( + notify, "write_to_queue" + ) as mock_write_to_queue, app.test_client() as app_test_client: + auth_header = {"Authorization": "made-up-token"} + response = app_test_client.post( + "/notify", json=mock_post_notify, headers=auth_header + ) + assert response.status_code == 403 + mock_write_to_queue.assert_not_called() diff --git a/api_receive_test.py b/api_receive_test.py new file mode 100644 index 0000000..cee13f4 --- /dev/null +++ b/api_receive_test.py @@ -0,0 +1,98 @@ +import flask +import json +import pytest +from unittest.mock import patch, mock_open, call +from werkzeug.exceptions import HTTPException +from api import create_app +from endpoints import receive +from conftest import get_auth_header + + +@pytest.mark.usefixtures( + "mock_clients", "mock_client_credentials", "mock_read_from_queue_return" +) +def test_get_receive( + mock_clients, mock_client_credentials, mock_read_from_queue_return +): + app = create_app() + with patch( + "builtins.open", mock_open(read_data=json.dumps(mock_clients)) + ) as mock_file_open, patch.object( + receive, "read_from_queue" + ) as mock_read_from_queue, app.test_client() as app_test_client: + mock_read_from_queue.return_value = mock_read_from_queue_return + auth_header = get_auth_header(app_test_client, mock_client_credentials) + response = app_test_client.get( + "/receive", headers=auth_header + ) + assert response.status_code == 200 + mock_read_from_queue.assert_called_once_with( + queue_name="client-1-inbox", max_msgs=10 + ) + assert response.json == mock_read_from_queue_return + + +@pytest.mark.usefixtures( + "mock_clients", "mock_client_credentials", "mock_read_from_queue_return" +) +def test_get_receive_max_messages( + mock_clients, mock_client_credentials, mock_read_from_queue_return +): + app = create_app() + with patch( + "builtins.open", mock_open(read_data=json.dumps(mock_clients)) + ) as mock_file_open, patch.object( + receive, "read_from_queue" + ) as mock_read_from_queue, app.test_client() as app_test_client: + mock_read_from_queue.return_value = mock_read_from_queue_return + auth_header = get_auth_header(app_test_client, mock_client_credentials) + max_messages = 2 + response = app_test_client.get( + "/receive", query_string={ "max_messages": max_messages }, headers=auth_header + ) + assert response.status_code == 200 + mock_read_from_queue.assert_called_once_with( + queue_name="client-1-inbox", max_msgs=max_messages + ) + assert response.json == mock_read_from_queue_return + + +@pytest.mark.usefixtures( + "mock_clients", "mock_read_from_queue_return" +) +def test_get_receive_no_token( + mock_clients, mock_read_from_queue_return +): + app = create_app() + with patch( + "builtins.open", mock_open(read_data=json.dumps(mock_clients)) + ) as mock_file_open, patch.object( + receive, "read_from_queue" + ) as mock_read_from_queue, app.test_client() as app_test_client: + mock_read_from_queue.return_value = mock_read_from_queue_return + response = app_test_client.get( + "/receive" + ) + assert response.status_code == 403 + mock_read_from_queue.assert_not_called() + + +@pytest.mark.usefixtures( + "mock_clients", "mock_read_from_queue_return" +) +def test_get_receive_invalid_token( + mock_clients, mock_read_from_queue_return +): + app = create_app() + with patch( + "builtins.open", mock_open(read_data=json.dumps(mock_clients)) + ) as mock_file_open, patch.object( + receive, "read_from_queue" + ) as mock_read_from_queue, app.test_client() as app_test_client: + mock_read_from_queue.return_value = mock_read_from_queue_return + auth_header = {"Authorization": "made-up-token"} + response = app_test_client.get( + "/receive", headers=auth_header + ) + assert response.status_code == 403 + mock_read_from_queue.assert_not_called() diff --git a/conftest.py b/conftest.py index c6fcacd..bf5c70d 100644 --- a/conftest.py +++ b/conftest.py @@ -88,5 +88,15 @@ def mock_post_notify(): @pytest.fixture def mock_message_notify(): - post = posts()["send"] - return {"message": post["body"]} + post = posts()["notify"] + return {"topic": "broadcast", "message": post["body"]} + + +@pytest.fixture +def mock_read_from_queue_return(): + return [ + { + "topic": "soar.client-1.something", + "message": "this is a pub/sub message from client-1" + } + ] diff --git a/endpoints/receive.py b/endpoints/receive.py index bc299fa..8c892ca 100644 --- a/endpoints/receive.py +++ b/endpoints/receive.py @@ -22,7 +22,8 @@ class Receive(AuthResource): if errors: abort(400, message=str(errors)) - max_messages = request.args.get("max_messages", 10) + # force query string parameter value into int + max_messages = int(request.args.get("max_messages", 10)) allow = self.auth(request) if allow: -- GitLab