From abe4e667e2a940b02c3c53bd7e71ab8992e87e0c Mon Sep 17 00:00:00 2001 From: Jeremy Hooke Date: Thu, 17 Dec 2020 16:55:55 +1100 Subject: [PATCH] Test that all URLs give 404s ... rather than Exceptions. Since we just hit this case again in the Stac API. --- cubedash/_stac.py | 4 +-- integration_tests/asserts.py | 9 ++++-- integration_tests/test_page_loads.py | 41 +++++++++++++++++++++++++ integration_tests/test_stac.py | 45 ++++++++++++++++++++++++---- 4 files changed, 90 insertions(+), 9 deletions(-) diff --git a/cubedash/_stac.py b/cubedash/_stac.py index 3df240b91..e60f22523 100644 --- a/cubedash/_stac.py +++ b/cubedash/_stac.py @@ -373,7 +373,7 @@ def collection_items(collection: str): """ all_time_summary = _model.get_time_summary(collection) if not all_time_summary: - abort(404, "Product not yet summarised") + abort(404, f"Product {collection!r} not found among summaries.") feature_collection = _handle_search_request( request_args=request.args, @@ -393,7 +393,7 @@ def collection_items(collection: str): def item(collection: str, dataset_id: str): dataset = _model.STORE.get_item(dataset_id) if not dataset: - abort(404, "No such dataset") + abort(404, f"No dataset found with id {dataset_id!r}") actual_product_name = dataset.product_name if collection != actual_product_name: diff --git a/integration_tests/asserts.py b/integration_tests/asserts.py index dc4990946..19768700c 100644 --- a/integration_tests/asserts.py +++ b/integration_tests/asserts.py @@ -41,9 +41,14 @@ def get_html_response(client: FlaskClient, url: str) -> Tuple[HTML, Response]: return html, response -def get_text_response(client: FlaskClient, url: str) -> Tuple[str, Response]: +def get_text_response( + client: FlaskClient, url: str, expect_status_code=200 +) -> Tuple[str, Response]: response: Response = client.get(url, follow_redirects=True) - assert response.status_code == 200, response.data.decode("utf-8") + assert response.status_code == expect_status_code, ( + f"Expected status {expect_status_code} not {response.status_code}." + f"\nGot:\n{indent(response.data.decode('utf-8'), ' ' * 6)}" + ) return response.data.decode("utf-8"), response diff --git a/integration_tests/test_page_loads.py b/integration_tests/test_page_loads.py index 4bac0817e..08d4f46f5 100644 --- a/integration_tests/test_page_loads.py +++ b/integration_tests/test_page_loads.py @@ -2,6 +2,7 @@ Tests that load pages and check the contained text. """ import json +from datetime import datetime from io import StringIO from textwrap import indent @@ -708,3 +709,43 @@ def check_doc_start_has_hint(hint: str, url: str): "EO1 Dataset", "/dataset/57848615-2421-4d25-bfef-73f57de0574d.odc-metadata.yaml", ) + + +def test_all_give_404s(client: FlaskClient): + """ + We should get 404 messages, not exceptions, for missing things. + """ + + def expect_404(url: str, message_contains: str = None): + __tracebackhide__ = True + response = get_text_response(client, url, expect_status_code=404) + if message_contains and message_contains not in response: + raise AssertionError( + f"Expected {message_contains!r} in response {response!r}" + ) + + name = "does_not_exist" + time = datetime.utcnow() + region_code = "not_a_region" + dataset_id = "37296b9a-e6ec-4bfd-ab80-cc32902429d1" + + expect_404(f"/metadata-types/{name}") + expect_404(f"/metadata-types/{name}.odc-type.yaml") + + expect_404(f"/datasets/{name}") + expect_404(f"/products/{name}") + expect_404(f"/products/{name}.odc-product.yaml") + + expect_404(f"/products/{name}/extents/{time:%Y}") + expect_404(f"/products/{name}/extents/{time:%Y/%m}") + expect_404(f"/products/{name}/extents/{time:%Y/%m/%d}") + + expect_404(f"/products/{name}/datasets/{time:%Y}") + expect_404(f"/products/{name}/datasets/{time:%Y/%m}") + expect_404(f"/products/{name}/datasets/{time:%Y/%m/%d}") + + expect_404(f"/region/{name}/{region_code}") + expect_404(f"/region/{name}/{region_code}/{time:%Y/%m/%d}") + + expect_404(f"/dataset/{dataset_id}") + expect_404(f"/dataset/{dataset_id}.odc-metadata.yaml") diff --git a/integration_tests/test_stac.py b/integration_tests/test_stac.py index b144eb490..e885b004a 100644 --- a/integration_tests/test_stac.py +++ b/integration_tests/test_stac.py @@ -3,19 +3,20 @@ """ import json -import jsonschema -import pytest import urllib.parse from collections import Counter, defaultdict +from pathlib import Path +from pprint import pformat +from typing import Dict, Generator, Iterable, List, Optional, Union + +import jsonschema +import pytest from dateutil import tz from flask import Response from flask.testing import FlaskClient from jsonschema import SchemaError -from pathlib import Path -from pprint import pformat from shapely.geometry import shape as shapely_shape from shapely.validation import explain_validity -from typing import Dict, Generator, Iterable, List, Optional, Union import cubedash._stac from cubedash import _model @@ -672,6 +673,40 @@ def test_stac_collection_items(stac_client: FlaskClient): validate_items(_iter_items_across_pages(stac_client, item_links), expect_count=306) +def test_returns_404s(stac_client: FlaskClient): + """ + We should get 404 messages, not exceptions, for missing things. + + (and stac errors are expected in json) + """ + + def expect_404(url: str, message_contains: str = None): + __tracebackhide__ = True + data = get_json(stac_client, url, expect_status_code=404) + if message_contains and message_contains not in data.get("description", ""): + raise AssertionError( + f"Expected {message_contains!r} in description of response {data!r}" + ) + + # Product + expect_404( + "/stac/collections/does_not_exist", message_contains="Unknown collection" + ) + + # Product items + expect_404( + "/stac/collections/does_not_exist/items", + message_contains="Product 'does_not_exist' not found", + ) + + # Dataset + wrong_dataset_id = "37296b9a-e6ec-4bfd-ab80-cc32902429d1" + expect_404( + f"/stac/collections/does_not_exist/items/{wrong_dataset_id}", + message_contains="No dataset found", + ) + + def test_stac_item(stac_client: FlaskClient, populated_index: Index): # Load one stac dataset from the test data.