From 923ed0a4349e25cf48e8b7b57002680c7d1c492b Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Tue, 6 Oct 2020 16:26:44 +0300 Subject: [PATCH] tests/test_api.py: Add tests for /items POST handlers This adds tests for the new /items POST handler, both with mocked data and a live connection to a Solr statistics core. Tests that only work when Solr is available are marked with XFAIL so that they don't turn the whole test suite red. In each test I try to assert as many parameters as we can know for each response so that we cover all expectations. For example, when we test a valid limit parameter we should test whether the response not only has the same limit parameter, but that the number of items has actually been limited and the number of pages has been adjusted accordingly. See: https://docs.pytest.org/en/stable/skipping.html --- tests/test_api.py | 315 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 06642b3..06a8518 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,6 +1,7 @@ from falcon import testing import json import pytest +from unittest.mock import patch from dspace_statistics_api.app import api @@ -65,3 +66,317 @@ def test_get_items_invalid_page(client): response = client.simulate_get("/items", query_string="page=-1") assert response.status_code == 400 + + +@pytest.mark.xfail +def test_post_items_valid_dateFrom(client): + """Test POSTing a request with a valid dateFrom parameter in the request body.""" + + request_body = { + "dateFrom": "2020-01-01T00:00:00Z", + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 200 + assert response.json["limit"] == 100 + assert response.json["currentPage"] == 0 + assert isinstance(response.json["totalPages"], int) + assert len(response.json["statistics"]) == 2 + assert isinstance(response.json["statistics"][0]["views"], int) + assert isinstance(response.json["statistics"][0]["downloads"], int) + assert isinstance(response.json["statistics"][1]["views"], int) + assert isinstance(response.json["statistics"][1]["downloads"], int) + + +def test_post_items_valid_dateFrom_mocked(client): + """Mock test POSTing a request with a valid dateFrom parameter in the request body.""" + + request_body = { + "dateFrom": "2020-01-01T00:00:00Z", + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + get_views_return_value = { + "c3910974-c3a5-4053-9dce-104aa7bb1620": 21, + "887cc5f8-b5e7-4a2f-9053-49c91ab81313": 0, + } + get_downloads_return_value = { + "c3910974-c3a5-4053-9dce-104aa7bb1620": 575, + "887cc5f8-b5e7-4a2f-9053-49c91ab81313": 899, + } + + with patch( + "dspace_statistics_api.app.get_views", return_value=get_views_return_value + ): + with patch( + "dspace_statistics_api.app.get_downloads", + return_value=get_downloads_return_value, + ): + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 200 + assert response.json["limit"] == 100 + assert response.json["currentPage"] == 0 + assert isinstance(response.json["totalPages"], int) + assert len(response.json["statistics"]) == 2 + assert isinstance(response.json["statistics"][0]["views"], int) + assert isinstance(response.json["statistics"][0]["downloads"], int) + assert isinstance(response.json["statistics"][1]["views"], int) + assert isinstance(response.json["statistics"][1]["downloads"], int) + + +def test_post_items_invalid_dateFrom(client): + """Test POSTing a request with an invalid dateFrom parameter in the request body.""" + + request_body = { + "dateFrom": "2020-01-01T00:00:00", + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 400 + + +@pytest.mark.xfail +def test_post_items_valid_dateTo(client): + """Test POSTing a request with a valid dateTo parameter in the request body.""" + + request_body = { + "dateTo": "2020-01-01T00:00:00Z", + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 200 + assert response.json["limit"] == 100 + assert response.json["currentPage"] == 0 + assert isinstance(response.json["totalPages"], int) + assert len(response.json["statistics"]) == 2 + assert isinstance(response.json["statistics"][0]["views"], int) + assert isinstance(response.json["statistics"][0]["downloads"], int) + assert isinstance(response.json["statistics"][1]["views"], int) + assert isinstance(response.json["statistics"][1]["downloads"], int) + + +def test_post_items_valid_dateTo_mocked(client): + """Mock test POSTing a request with a valid dateTo parameter in the request body.""" + + request_body = { + "dateTo": "2020-01-01T00:00:00Z", + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + get_views_return_value = { + "c3910974-c3a5-4053-9dce-104aa7bb1620": 21, + "887cc5f8-b5e7-4a2f-9053-49c91ab81313": 0, + } + get_downloads_return_value = { + "c3910974-c3a5-4053-9dce-104aa7bb1620": 575, + "887cc5f8-b5e7-4a2f-9053-49c91ab81313": 899, + } + + with patch( + "dspace_statistics_api.app.get_views", return_value=get_views_return_value + ): + with patch( + "dspace_statistics_api.app.get_downloads", + return_value=get_downloads_return_value, + ): + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 200 + assert response.json["limit"] == 100 + assert response.json["currentPage"] == 0 + assert isinstance(response.json["totalPages"], int) + assert len(response.json["statistics"]) == 2 + assert isinstance(response.json["statistics"][0]["views"], int) + assert isinstance(response.json["statistics"][0]["downloads"], int) + assert isinstance(response.json["statistics"][1]["views"], int) + assert isinstance(response.json["statistics"][1]["downloads"], int) + + +def test_post_items_invalid_dateTo(client): + """Test POSTing a request with an invalid dateTo parameter in the request body.""" + + request_body = { + "dateFrom": "2020-01-01T00:00:00", + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 400 + + +@pytest.mark.xfail +def test_post_items_valid_limit(client): + """Test POSTing a request with a valid limit parameter in the request body.""" + + request_body = { + "limit": 1, + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 200 + assert response.json["limit"] == 1 + assert response.json["currentPage"] == 0 + assert isinstance(response.json["totalPages"], int) + assert len(response.json["statistics"]) == 1 + assert isinstance(response.json["statistics"][0]["views"], int) + assert isinstance(response.json["statistics"][0]["downloads"], int) + + +def test_post_items_valid_limit_mocked(client): + """Mock test POSTing a request with a valid limit parameter in the request body.""" + + request_body = { + "limit": 1, + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + get_views_return_value = {"c3910974-c3a5-4053-9dce-104aa7bb1620": 21} + get_downloads_return_value = {"c3910974-c3a5-4053-9dce-104aa7bb1620": 575} + + with patch( + "dspace_statistics_api.app.get_views", return_value=get_views_return_value + ): + with patch( + "dspace_statistics_api.app.get_downloads", + return_value=get_downloads_return_value, + ): + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 200 + assert response.json["limit"] == 1 + assert response.json["currentPage"] == 0 + assert isinstance(response.json["totalPages"], int) + assert len(response.json["statistics"]) == 1 + assert isinstance(response.json["statistics"][0]["views"], int) + assert isinstance(response.json["statistics"][0]["downloads"], int) + + +def test_post_items_invalid_limit(client): + """Test POSTing a request with an invalid limit parameter in the request body.""" + + request_body = { + "limit": -1, + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 400 + + +@pytest.mark.xfail +def test_post_items_valid_page(client): + """Test POSTing a request with a valid page parameter in the request body.""" + + request_body = { + "page": 0, + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 200 + assert response.json["limit"] == 100 + assert response.json["currentPage"] == 0 + assert response.json["totalPages"] == 0 + assert len(response.json["statistics"]) == 2 + assert isinstance(response.json["statistics"][0]["views"], int) + assert isinstance(response.json["statistics"][0]["downloads"], int) + assert isinstance(response.json["statistics"][1]["views"], int) + assert isinstance(response.json["statistics"][1]["downloads"], int) + + +def test_post_items_valid_page_mocked(client): + """Mock test POSTing a request with a valid page parameter in the request body.""" + + request_body = { + "page": 0, + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + get_views_return_value = { + "c3910974-c3a5-4053-9dce-104aa7bb1620": 21, + "887cc5f8-b5e7-4a2f-9053-49c91ab81313": 0, + } + get_downloads_return_value = { + "c3910974-c3a5-4053-9dce-104aa7bb1620": 575, + "887cc5f8-b5e7-4a2f-9053-49c91ab81313": 899, + } + + with patch( + "dspace_statistics_api.app.get_views", return_value=get_views_return_value + ): + with patch( + "dspace_statistics_api.app.get_downloads", + return_value=get_downloads_return_value, + ): + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 200 + assert response.json["limit"] == 100 + assert response.json["currentPage"] == 0 + assert isinstance(response.json["totalPages"], int) + assert len(response.json["statistics"]) == 2 + assert isinstance(response.json["statistics"][0]["views"], int) + assert isinstance(response.json["statistics"][0]["downloads"], int) + assert isinstance(response.json["statistics"][1]["views"], int) + assert isinstance(response.json["statistics"][1]["downloads"], int) + + +def test_post_items_invalid_page(client): + """Test POSTing a request with an invalid page parameter in the request body.""" + + request_body = { + "page": -1, + "items": [ + "c3910974-c3a5-4053-9dce-104aa7bb1620", + "887cc5f8-b5e7-4a2f-9053-49c91ab81313", + ], + } + + response = client.simulate_post("/items", json=request_body) + + assert response.status_code == 400