Skip to content

Commit 6007801

Browse files
authored
Merge pull request #1209 from TOMToolkit/1109-create-a-basedataservice-class
establish basic tests for BaseDataService class
2 parents d353eaa + 1bef356 commit 6007801

4 files changed

Lines changed: 160 additions & 9 deletions

File tree

tom_dataservices/dataservices.py

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
from abc import ABC, abstractmethod
22

33

4+
class MissingDataException(Exception):
5+
pass
6+
7+
48
class BaseDataService(ABC):
59
"""
610
Base class for all Data Services. Data Services are classes that are responsible for querying external services
@@ -17,17 +21,17 @@ class BaseDataService(ABC):
1721
# Class variable that can store query results if necessary
1822
query_results = {}
1923

20-
@abstractmethod
21-
def pre_query_validation_service(self, query_parameters):
22-
"""Same thing as query_service, but a dry run"""
23-
2424
@abstractmethod
2525
def query_service(self, query_parameters):
2626
"""takes in the serialized data from the query form and actually submits the query to the service"""
2727

28-
@abstractmethod
28+
def pre_query_validation(self, query_parameters):
29+
"""Same thing as query_service, but a dry run"""
30+
raise NotImplementedError
31+
2932
def get_form_class(self):
3033
"""Returns the full form class for querying this service"""
34+
raise NotImplementedError
3135

3236
def get_additional_context_data(self):
3337
"""
@@ -63,14 +67,53 @@ def query_targets(self, query_parameters):
6367
"""Set up and run a specialized query for retrieving targets from a DataService."""
6468
return self.query_service(query_parameters)
6569

66-
def to_data_product(self, query_results):
70+
def to_data_product(self, query_results=None, **kwargs):
71+
"""
72+
Upper level function to create a new DataProduct from the query results
73+
Can take either new query results, or use stored results form a recent `query_service()`
74+
:param query_results: Query results from the DataService
75+
:returns: Target object
76+
"""
77+
query_results = query_results or self.query_results
78+
if not query_results:
79+
raise MissingDataException('No query results. Did you call query_service()?')
80+
else:
81+
return self.create_data_product_from_query(query_results, **kwargs)
82+
83+
def create_data_product_from_query(self, query_results=None, **kwargs):
6784
"""Create a new DataProduct from the query results"""
6885
raise NotImplementedError
6986

70-
def to_reduced_datums(self, query_results):
71-
"""Create a new ReducedDatum of the appropriate type from the query results"""
87+
def to_reduced_datums(self, query_results=None, **kwargs):
88+
"""
89+
Upper level function to create a new ReducedDatum from the query results
90+
Can take either new query results, or use stored results form a recent `query_service()`
91+
:param query_results: Query results from the DataService
92+
:returns: Target object
93+
"""
94+
query_results = query_results or self.query_results
95+
if not query_results:
96+
raise MissingDataException('No query results. Did you call query_service()?')
97+
else:
98+
return self.create_reduced_datums_from_query(query_results, **kwargs)
99+
100+
def create_reduced_datums_from_query(self, query_results=None, **kwargs):
101+
"""Create a new reduced_datum of the appropriate type from the query results"""
72102
raise NotImplementedError
73103

74-
def to_target(self, query_results):
104+
def to_target(self, query_results=None, **kwargs):
105+
"""
106+
Upper level function to create a new target from the query results
107+
Can take either new query results, or use stored results form a recent `query_service()`
108+
:param query_results: Query results from the DataService
109+
:returns: Target object
110+
"""
111+
target_parameters = query_results or self.query_results
112+
if not target_parameters:
113+
raise MissingDataException('No query results. Did you call query_service()?')
114+
else:
115+
return self.create_target_from_query(target_parameters, **kwargs)
116+
117+
def create_target_from_query(self, query_results, **kwargs):
75118
"""Create a new target from the query results"""
76119
raise NotImplementedError

tom_dataservices/forms.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from django import forms
2+
from crispy_forms.helper import FormHelper
3+
from crispy_forms.layout import Submit
4+
5+
6+
class BaseQueryForm(forms.Form):
7+
"""
8+
Form class representing the default form for a dataservice.
9+
"""
10+
11+
def __init__(self, *args, **kwargs):
12+
super().__init__(*args, **kwargs)
13+
self.helper = FormHelper()
14+
self.helper.add_input(Submit('submit', 'Submit'))

tom_dataservices/tests/__init__.py

Whitespace-only changes.

tom_dataservices/tests/tests.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
from django import forms
2+
from django.test import TestCase
3+
4+
from tom_dataservices.dataservices import BaseDataService, MissingDataException
5+
from tom_dataservices.forms import BaseQueryForm
6+
from tom_targets.models import Target
7+
8+
9+
test_query_results = {'ra': 24, 'dec': 77, 'name': 'faketarget', 'type': 'SIDEREAL'}
10+
11+
12+
class TestDataServiceForm(BaseQueryForm):
13+
""" A DataService must implement a form in order to be displayed in a TOM.
14+
They should subclass `BaseQueryForm`. This test form will only have one field.
15+
"""
16+
name = forms.CharField(required=True)
17+
18+
19+
class TestDataService(BaseDataService):
20+
name = 'TEST'
21+
service_notes = "This is a test DataService."
22+
23+
def query_service(self, term):
24+
if term == 'notfound':
25+
raise MissingDataException
26+
self.query_results = test_query_results
27+
return
28+
29+
def get_form_class(self):
30+
return TestDataServiceForm
31+
32+
def create_target_from_query(self, query_results, **kwargs):
33+
return Target(**query_results)
34+
35+
36+
class EmptyTestDataService(BaseDataService):
37+
name = 'TEST'
38+
service_notes = "This is a test DataService."
39+
40+
def query_service(self, term):
41+
if term == 'notfound':
42+
raise MissingDataException
43+
self.query_results = test_query_results
44+
return
45+
46+
47+
class TestDataServiceClass(TestCase):
48+
"""
49+
Test the functionality of the DataService class via the TestDataService.
50+
"""
51+
def test_query_service(self):
52+
new_test_query = TestDataService()
53+
self.assertEqual(new_test_query.query_results, {})
54+
new_test_query.query_service('mytarget')
55+
self.assertEqual(new_test_query.query_results, test_query_results)
56+
57+
def test_to_target(self):
58+
new_test_query = TestDataService()
59+
# Show to_target() returns error with no query_results
60+
with self.assertRaises(MissingDataException):
61+
new_test_query.to_target()
62+
# Show to_target() works with the default query_results
63+
new_test_query.query_targets('mytarget')
64+
target = new_test_query.to_target()
65+
self.assertEqual(target.name, test_query_results['name'])
66+
# Show to_target() works independently of the query.
67+
new_test_query_results = test_query_results.copy()
68+
new_test_query_results['name'] = 'target2'
69+
target2 = new_test_query.to_target(new_test_query_results)
70+
self.assertEqual(target2.name, 'target2')
71+
72+
73+
class TestUnimplementedDataServiceClass(TestCase):
74+
"""
75+
Test the functionality of a DataService with unimplemented methods.
76+
"""
77+
78+
def test_no_create_data_product_from_query(self):
79+
new_test_query = EmptyTestDataService()
80+
# Show to_data_product() returns error when create_data_product_from_query undefined
81+
with self.assertRaises(NotImplementedError):
82+
new_test_query.to_data_product(test_query_results)
83+
84+
def test_no_create_target_from_query(self):
85+
new_test_query = EmptyTestDataService()
86+
# Show to_data_product() returns error when create_data_product_from_query undefined
87+
with self.assertRaises(NotImplementedError):
88+
new_test_query.to_target(test_query_results)
89+
90+
def test_no_create_reduced_datums_from_query(self):
91+
new_test_query = EmptyTestDataService()
92+
# Show to_data_product() returns error when create_data_product_from_query undefined
93+
with self.assertRaises(NotImplementedError):
94+
new_test_query.to_reduced_datums(test_query_results)

0 commit comments

Comments
 (0)