Skip to content

Commit

Permalink
test: increase test coverage for search API #313
Browse files Browse the repository at this point in the history
  • Loading branch information
MRichards99 committed Feb 16, 2022
1 parent e1ee64c commit d62e45a
Show file tree
Hide file tree
Showing 7 changed files with 309 additions and 11 deletions.
7 changes: 7 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,10 @@ def test_config_data():
def test_config(test_config_data):
with patch("builtins.open", mock_open(read_data=json.dumps(test_config_data))):
return APIConfig.load("test/path")


@pytest.fixture()
def test_config_without_search_api(test_config_data):
del test_config_data["search_api"]
with patch("builtins.open", mock_open(read_data=json.dumps(test_config_data))):
return APIConfig.load("test/path")
33 changes: 29 additions & 4 deletions test/search_api/filters/test_search_api_where_filter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest

from datagateway_api.src.common.date_handler import DateHandler
from datagateway_api.src.common.filter_order_handler import FilterOrderHandler
from datagateway_api.src.search_api.filters import SearchAPIWhereFilter
from datagateway_api.src.search_api.nested_where_filters import NestedWhereFilters
Expand All @@ -24,8 +25,8 @@ class TestSearchAPIWhereFilter:
),
pytest.param(
SearchAPIWhereFilter("pid", "pid:1", "eq"),
"Instrument",
"SELECT o FROM Instrument o WHERE o.id = '1'",
"Sample",
"SELECT o FROM Sample o WHERE o.id = '1'",
id="Id instrument value (mapping that maps to multiple ICAT fields)",
),
pytest.param(
Expand Down Expand Up @@ -145,8 +146,20 @@ class TestSearchAPIWhereFilter:
"Document",
"SELECT o FROM Investigation o JOIN o.parameters AS p WHERE"
" p.dateTimeValue = '2018-05-05T15:00:00.000Z'",
id="Datetime parameter value (mapping that maps to multiple ICAT"
" fields)",
id="Datetime (of type string) parameter value (mapping that maps to"
" multiple ICAT fields)",
),
pytest.param(
SearchAPIWhereFilter(
"parameters.value",
DateHandler.str_to_datetime_object("2018-05-05T15:00:00.000Z"),
"eq",
),
"Document",
"SELECT o FROM Investigation o JOIN o.parameters AS p WHERE"
" p.dateTimeValue = '2018-05-05 15:00:00+00:00'",
id="Datetime (of type date) parameter value (mapping that maps to"
" multiple ICAT fields)",
),
pytest.param(
SearchAPIWhereFilter("parameters.value", 20, "eq"),
Expand All @@ -164,6 +177,14 @@ class TestSearchAPIWhereFilter:
id="Numeric (float) parameter value (mapping that maps to multiple ICAT"
"fields)",
),
pytest.param(
SearchAPIWhereFilter("parameters.value", ["test"], "eq"),
"Document",
"SELECT o FROM Investigation o JOIN o.parameters AS p WHERE"
" p.stringValue = '['test']'",
id="Other type parameter value (mapping that maps to multiple ICAT"
"fields)",
),
],
)
def test_valid_apply_where_filter(self, filter_input, entity_name, expected_query):
Expand Down Expand Up @@ -281,3 +302,7 @@ def test_valid_apply_nested_filters(
filter_handler.apply_filters(test_query)

assert str(test_query.icat_query.query) == expected_query

def test_str_where_filter(self):
test_filter = SearchAPIWhereFilter("name", "WISH", "eq")
assert str(test_filter) == repr(test_filter)
6 changes: 5 additions & 1 deletion test/search_api/test_error_handling.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest

from datagateway_api.src.common.exceptions import (
ApiError,
BadRequestError,
FilterError,
MissingRecordError,
Expand All @@ -22,6 +23,7 @@ class TestErrorHandling:
pytest.param(TypeError, BadRequestError, 400, id="Type error"),
pytest.param(ValueError, BadRequestError, 400, id="Value error"),
pytest.param(AttributeError, BadRequestError, 400, id="Attribute error"),
pytest.param(ImportError, ImportError, 500, id="Import error"),
],
)
def test_valid_error_raised(
Expand All @@ -35,7 +37,9 @@ def raise_exception():
raise_exception()
except Exception as e:
assert isinstance(e.args[0], dict)
assert e.status_code == status_code
# Non-API defined exception won't have a `status_code` attribute
if isinstance(e, ApiError):
assert e.status_code == status_code
assert list(e.args[0]["error"].keys()) == ["statusCode", "name", "message"]

with pytest.raises(expected_exception):
Expand Down
41 changes: 41 additions & 0 deletions test/search_api/test_nested_where_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,44 @@ def test_nested_classes(
test_nest = NestedWhereFilters(lhs, rhs, joining_operator)
where_clause = str(test_nest)
assert where_clause == expected_where_clause

@pytest.mark.parametrize(
"test_filters, query",
[
pytest.param(
SearchAPIWhereFilter("name", "test name", "eq"),
SearchAPIQuery("File"),
id="Single WHERE filter",
),
pytest.param(
NestedWhereFilters(
[SearchAPIWhereFilter("name", "test name", "eq")],
[SearchAPIWhereFilter("id", 3, "eq")],
"OR",
SearchAPIQuery("File"),
),
SearchAPIQuery("File"),
id="NestedWhereFilters object",
),
pytest.param(
[
SearchAPIWhereFilter("name", "test name", "eq"),
SearchAPIWhereFilter("id", 3, "eq"),
],
SearchAPIQuery("File"),
id="List of WHERE filters",
),
],
)
def test_apply_filter(self, test_filters, query):
NestedWhereFilters.set_search_api_query(test_filters, query)

if not isinstance(test_filters, list):
test_filters = [test_filters]

for filter_ in test_filters:
if isinstance(filter_, NestedWhereFilters):
assert filter_.lhs[0].search_api_query == query
assert filter_.rhs[0].search_api_query == query
else:
assert filter_.search_api_query == query
66 changes: 66 additions & 0 deletions test/search_api/test_panosc_mappings.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from unittest.mock import patch

import pytest

from datagateway_api.src.common.exceptions import FilterError, SearchAPIError
Expand All @@ -9,6 +11,70 @@ def test_valid_load_mappings(self, test_panosc_mappings):
test_mappings = PaNOSCMappings()
assert test_mappings.mappings == test_panosc_mappings.mappings

@pytest.mark.parametrize(
"search_api_config_flag",
[
pytest.param(True, id="Search API config present"),
pytest.param(False, id="No search API config"),
],
)
def test_invalid_load_mappings(
self, test_config, test_config_without_search_api, search_api_config_flag,
):
if search_api_config_flag:
current_test_config = test_config
else:
current_test_config = test_config_without_search_api

with patch(
"datagateway_api.src.common.config.Config.config", current_test_config,
):
if search_api_config_flag:
with pytest.raises(SystemExit):
PaNOSCMappings("bad/path")
else:
# Shouldn't SysExit if a user isn't using the search API
PaNOSCMappings("bad/path")

@pytest.mark.parametrize(
"panosc_entity_name, field_name, expected_panosc_entity_name"
", expected_icat_field_name",
[
pytest.param("Dataset", "title", "Dataset", "name", id="String mapping"),
pytest.param(
"Document",
"members",
"Member",
"investigationUsers",
id="Dict mapping",
),
pytest.param(
"Parameter",
"value",
"Parameter",
["numericValue", "stringValue", "dateTimeValue"],
id="List mapping",
),
],
)
def test_valid_get_icat_mapping(
self,
test_panosc_mappings,
panosc_entity_name,
field_name,
expected_panosc_entity_name,
expected_icat_field_name,
):
icat_mapping = test_panosc_mappings.get_icat_mapping(
panosc_entity_name, field_name,
)

assert icat_mapping == (expected_panosc_entity_name, expected_icat_field_name)

def test_invalid_get_icat_mapping(self, test_panosc_mappings):
with pytest.raises(FilterError):
test_panosc_mappings.get_icat_mapping("UnknownEntity", "unknownFieldName")

@pytest.mark.parametrize(
"test_panosc_entity_name, test_panosc_related_field_name, expected_entity_name",
[
Expand Down
40 changes: 40 additions & 0 deletions test/search_api/test_search_api_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from icat.query import Query
import pytest

from datagateway_api.src.common.exceptions import SearchAPIError
from datagateway_api.src.datagateway_api.icat.query import ICATQuery
from datagateway_api.src.search_api.query import SearchAPIICATQuery, SearchAPIQuery
from datagateway_api.src.search_api.session_handler import SessionHandler


class TestSearchAPIQuery:
def test_search_api_query_init(self, test_panosc_mappings):
panosc_entity_name = "Document"
test_query = SearchAPIQuery(panosc_entity_name)

assert test_query.panosc_entity_name == panosc_entity_name
assert (
test_query.icat_entity_name
== test_panosc_mappings.mappings[panosc_entity_name]["base_icat_entity"]
)

def test_search_api_query_repr(self, test_panosc_mappings):
panosc_entity_name = "Document"
test_query = SearchAPIQuery(panosc_entity_name)
assert (
repr(test_query)
== f"PaNOSC Entity Name: {panosc_entity_name}, ICAT Entity Name:"
f" {test_panosc_mappings.mappings[panosc_entity_name]['base_icat_entity']},"
f" ICAT Query: {str(test_query.icat_query.query)}"
)

def test_valid_search_api_icat_query_init(self):
test_query = SearchAPIICATQuery(SessionHandler.client, "Investigation")
assert isinstance(test_query, ICATQuery)
assert isinstance(test_query.query, Query)

def test_invalid_search_api_icat_query_init(self):
with pytest.raises(SearchAPIError):
SearchAPIICATQuery(
SessionHandler.client, "Investigation", includes="UnknownEntity",
)
Loading

0 comments on commit d62e45a

Please sign in to comment.