Skip to content

Commit

Permalink
#150: Complete TODOs from 'backend can be set for tests' work
Browse files Browse the repository at this point in the history
  • Loading branch information
MRichards99 committed Dec 3, 2020
1 parent e8f1139 commit 74215cd
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 24 deletions.
12 changes: 11 additions & 1 deletion datagateway_api/common/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@

def create_backend(backend_type):
"""
TODO - Add docstring
Create an instance of a backend dependent on the value parsed into the function. The
value will typically be from the contents of `config.json`, however when creating a
backend during automated tests the value will be from the Flask app's config (which
will be set in the API's config at `common.config`
The API will exit if a valid value isn't given.
:param backend_type: The type of backend that should be created and used for the API
:type backend_type: :class:`str`
:return: Either an instance of `common.dataase.backend.DatabaseBackend` or
`common.icat.backend.PythonICATBackend`
"""

if backend_type == "db":
Expand Down
10 changes: 8 additions & 2 deletions datagateway_api/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import requests

# from datagateway_api.src.main import app

log = logging.getLogger()

Expand All @@ -25,7 +24,14 @@ def get_backend_type(self):

def set_backend_type(self, backend_type):
"""
TODO - Explain the reason behind the setter
This setter is used as a way for automated tests to set the backend type. The
API can detect if the Flask app setup is from an automated test by checking the
app's config for a `TEST_BACKEND`. If this value exists (a KeyError will be
raised when the API is run normally, which will then grab the backend type from
`config.json`), it needs to be set using this function. This is required because
creating filters in the `QueryFilterFactory` is backend-specific so the backend
type must be fetched. This must be done using this module (rather than directly
importing and checking the Flask app's config) to avoid circular import issues.
"""
self.config["backend"] = backend_type

Expand Down
15 changes: 9 additions & 6 deletions datagateway_api/common/query_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ class QueryFilterFactory(object):
@staticmethod
def get_query_filter(request_filter):
"""
Given a filter return a matching Query filter object
Given a filter, return a matching Query filter object
This factory is not in common.filters so the created filter can be for the
correct backend. Moving the factory into that file would mean the filters would
be based off the abstract classes (because they're in the same file) which won't
enable filters to be unique to the backend
The filters are imported inside this method to enable the unit tests to not rely
on the contents of `config.json`. If they're imported at the top of the file,
the backend type won't have been updated if the Flask app has been created from
an automated test (file imports occur before `create_api_endpoints()` executes).
:param request_filter: dict - The filter to create the QueryFilter for
:param request_filter: The filter to create the QueryFilter for
:type request_filter: :class:`dict`
:return: The QueryFilter object created
:raises ApiError: If the backend type contains an invalid value
:raises FilterError: If the filter name is not recognised
"""

backend_type = config.get_backend_type()
Expand Down
1 change: 0 additions & 1 deletion datagateway_api/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ def create_api_endpoints(flask_app, api, spec):
except KeyError:
backend_type = config.get_backend_type()

# TODO - Add :param backend: to the endpoint functions
backend = create_backend(backend_type)

for entity_name in endpoints:
Expand Down
16 changes: 16 additions & 0 deletions datagateway_api/src/resources/entities/entity_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ def get_endpoint(name, entity_type, backend):
api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles")
:param name: The name of the entity
:type name: :class:`str`
:param entity_type: The entity the endpoint will use in queries
:type entity_type: :class:`str`
:param backend: The backend instance used for processing requests
:type backend: :class:`DatabaseBackend` or :class:`PythonICATBackend`
:return: The generated endpoint class
"""

Expand Down Expand Up @@ -162,7 +166,11 @@ def get_id_endpoint(name, entity_type, backend):
api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles/<int:id_>")
:param name: The name of the entity
:type name: :class:`str`
:param entity_type: The entity the endpoint will use in queries
:type entity_type: :class:`str`
:param backend: The backend instance used for processing requests
:type backend: :class:`DatabaseBackend` or :class:`PythonICATBackend`
:return: The generated id endpoint class
"""

Expand Down Expand Up @@ -292,7 +300,11 @@ def get_count_endpoint(name, entity_type, backend):
api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles/count")
:param name: The name of the entity
:type name: :class:`str`
:param entity_type: The entity the endpoint will use in queries
:type entity_type: :class:`str`
:param backend: The backend instance used for processing requests
:type backend: :class:`DatabaseBackend` or :class:`PythonICATBackend`
:return: The generated count endpoint class
"""

Expand Down Expand Up @@ -345,7 +357,11 @@ def get_find_one_endpoint(name, entity_type, backend):
api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles/findone")
:param name: The name of the entity
:type name: :class:`str`
:param entity_type: The entity the endpoint will use in queries
:type entity_type: :class:`str`
:param backend: The backend instance used for processing requests
:type backend: :class:`DatabaseBackend` or :class:`PythonICATBackend`
:return: The generated findOne endpoint class
"""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@

def session_endpoints(backend):
"""
TODO - Add docstring
Generate a flask_restful Resource class using the configured backend. In main.py
these generated classes are registered with the api e.g.
`api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles")`
:param backend: The backend instance used for processing requests
:type backend: :class:`DatabaseBackend` or :class:`PythonICATBackend`
:return: The generated session endpoint class
"""

class Sessions(Resource):
Expand Down
32 changes: 28 additions & 4 deletions datagateway_api/src/resources/table_endpoints/table_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@

def instrument_facility_cycles_endpoint(backend):
"""
TODO - Add docstring
Generate a flask_restful Resource class using the configured backend. In main.py
these generated classes are registered with the api e.g.
`api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles")`
:param backend: The backend instance used for processing requests
:type backend: :class:`DatabaseBackend` or :class:`PythonICATBackend`
:return: The generated endpoint class
"""
pass

Expand Down Expand Up @@ -68,7 +74,13 @@ def get(self, id_):

def count_instrument_facility_cycles_endpoint(backend):
"""
TODO - Add docstring
Generate a flask_restful Resource class using the configured backend. In main.py
these generated classes are registered with the api e.g.
`api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles")`
:param backend: The backend instance used for processing requests
:type backend: :class:`DatabaseBackend` or :class:`PythonICATBackend`
:return: The generated endpoint class
"""
pass

Expand Down Expand Up @@ -122,7 +134,13 @@ def get(self, id_):

def instrument_investigation_endpoint(backend):
"""
TODO - Add docstring
Generate a flask_restful Resource class using the configured backend. In main.py
these generated classes are registered with the api e.g.
`api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles")`
:param backend: The backend instance used for processing requests
:type backend: :class:`DatabaseBackend` or :class:`PythonICATBackend`
:return: The generated endpoint class
"""
pass

Expand Down Expand Up @@ -189,7 +207,13 @@ def get(self, instrument_id, cycle_id):

def count_instrument_investigation_endpoint(backend):
"""
TODO - Add docstring
Generate a flask_restful Resource class using the configured backend. In main.py
these generated classes are registered with the api e.g.
`api.add_resource(get_endpoint("Datafiles", DATAFILE), "/datafiles")`
:param backend: The backend instance used for processing requests
:type backend: :class:`DatabaseBackend` or :class:`PythonICATBackend`
:return: The generated endpoint class
"""
pass

Expand Down
6 changes: 1 addition & 5 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@ def multiple_investigation_test_data(icat_client):

@pytest.fixture(scope="package")
def flask_test_app():
"""
TODO - Explain why a generic test app is needed that doesn't rely on any backend
"""
"""This is used to check the endpoints exist and have the correct HTTP methods"""
test_app = Flask(__name__)
api, spec = create_app_infrastructure(test_app)
create_api_endpoints(test_app, api, spec)
Expand All @@ -129,7 +127,6 @@ def flask_test_app():

@pytest.fixture(scope="package")
def flask_test_app_icat(flask_test_app):
"""TODO - Explain ICAT test client"""
icat_app = Flask(__name__)
icat_app.config["TESTING"] = True
icat_app.config["TEST_BACKEND"] = "python_icat"
Expand All @@ -142,7 +139,6 @@ def flask_test_app_icat(flask_test_app):

@pytest.fixture(scope="package")
def flask_test_app_db():
"""TODO - Add DB test client doc"""
db_app = Flask(__name__)
db_app.config["TESTING"] = True
db_app.config["TEST_BACKEND"] = "db"
Expand Down
4 changes: 0 additions & 4 deletions test/test_date_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,3 @@ def test_valid_boundary_datetime(self):
)
str_date_output = DateHandler.datetime_object_to_str(example_date)
assert str_date_output == "2020-02-29 23:59:59"

def test_invalid_datetime(self):
# TODO - Not sure how to create an invalid datetime object
pass

0 comments on commit 74215cd

Please sign in to comment.