Skip to content

Add basic integration tests for all endpoints + API Keys tests #1241

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jobs:

- name: Start delphi_web_epidata
run: |
docker run --rm -d -p 10080:80 --env "MODULE_NAME=delphi.epidata.server.main" --env "SQLALCHEMY_DATABASE_URI=mysql+mysqldb://user:pass@delphi_database_epidata:3306/epidata" --env "FLASK_SECRET=abc" --env "FLASK_PREFIX=/epidata" --env "REDIS_HOST=delphi_redis" --env "REDIS_PASSWORD=1234" --env "API_KEY_REGISTER_WEBHOOK_TOKEN=abc" --env "API_KEY_ADMIN_PASSWORD=test_admin_password" --network delphi-net --name delphi_web_epidata delphi_web_epidata
docker run --rm -d -p 10080:80 --env "MODULE_NAME=delphi.epidata.server.main" --env "SQLALCHEMY_DATABASE_URI=mysql+mysqldb://user:pass@delphi_database_epidata:3306/epidata" --env "FLASK_SECRET=abc" --env "FLASK_PREFIX=/epidata" --env "REDIS_HOST=delphi_redis" --env "REDIS_PASSWORD=1234" --env "API_KEY_REGISTER_WEBHOOK_TOKEN=abc" --env "API_KEY_ADMIN_PASSWORD=test_admin_password" --env "TESTING_MODE=True" --network delphi-net --name delphi_web_epidata delphi_web_epidata
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we wanna make this an option in the Makefile as well? (we definitely want to make it default in the Makefile)

another way to achieve the same effect (and only for tests that need to reach the request limiting threshold) would be to write into redis at the beginning of those tests to simulate a large number of requests... if thats not too difficult to do, itll be more robust.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I believe that I have added this variable to Makefile as well, but for some reason it is not there now. Let me explore this a little bit more.

docker ps

- name: Run Unit Tests
Expand Down
1 change: 1 addition & 0 deletions dev/local/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ web:
--env "REDIS_PASSWORD=1234" \
--env "API_KEY_ADMIN_PASSWORD=test_admin_password" \
--env "API_KEY_REGISTER_WEBHOOK_TOKEN=abc" \
--env "TESTING_MODE=True" \
--network delphi-net --name delphi_web_epidata \
delphi_web_epidata >$(LOG_WEB) 2>&1 &

Expand Down
13 changes: 13 additions & 0 deletions integrations/acquisition/covidcast/test_covidcast_meta_caching.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ def setUp(self):
secrets.db.host = 'delphi_database_epidata'
secrets.db.epi = ('user', 'pass')

epidata_cnx = mysql.connector.connect(
user='user',
password='pass',
host='delphi_database_epidata',
database='epidata')
epidata_cur = epidata_cnx.cursor()

epidata_cur.execute("DELETE FROM `api_user`")
epidata_cur.execute('INSERT INTO `api_user`(`api_key`, `email`) VALUES("key", "email")')
epidata_cnx.commit()
epidata_cur.close()
epidata_cnx.close()
Comment on lines +61 to +72
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you use this a couple times... should we make it into a little helper method stored in src/common/integration_test_base_class.py? it doesnt quite fit the requirements of https://en.wikipedia.org/wiki/Rule_of_three_(computer_programming), so its fine to leave as-is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I added this in places where we unittest.TestCase is used and we don't have connection to the epidata database. This can be fixed in next round of refactoring.


# use the local instance of the Epidata API
Epidata.BASE_URL = BASE_URL
Epidata.auth = ('epidata', 'key')
Expand Down
13 changes: 13 additions & 0 deletions integrations/acquisition/covidcast/test_csv_uploading.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ def setUp(self):
secrets.db.host = 'delphi_database_epidata'
secrets.db.epi = ('user', 'pass')

epidata_cnx = mysql.connector.connect(
user='user',
password='pass',
host='delphi_database_epidata',
database='epidata')
epidata_cur = epidata_cnx.cursor()

epidata_cur.execute("DELETE FROM `api_user`")
epidata_cur.execute('INSERT INTO `api_user`(`api_key`, `email`) VALUES("key", "email")')
epidata_cnx.commit()
epidata_cur.close()
epidata_cnx.close()

# use the local instance of the Epidata API
Epidata.BASE_URL = 'http://delphi_web_epidata/epidata/api.php'
Epidata.auth = ('epidata', 'key')
Expand Down
249 changes: 249 additions & 0 deletions integrations/server/test_api_keys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
"""Integration tests for the API Keys"""
import requests

# first party
from delphi.epidata.common.integration_test_base_class import DelphiTestBase


class APIKeysTets(DelphiTestBase):
"""Tests the API Keys behaviour"""

def localSetUp(self):
self.role_name = "cdc"

def _make_request(self, url: str = None, params: dict = {}, auth: tuple = None):
if not url:
url = self.epidata_client.BASE_URL
response = requests.get(url, params=params, auth=auth)
return response

def test_public_route(self):
"""Test public route"""
public_route = "http://delphi_web_epidata/epidata/version"
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(public_route).status_code)
self.assertEqual(status_codes, {200})

def test_no_multiples_data_source(self):
"""Test requests with no multiples and with provided `data_source` and `signal` as a separate query params."""
params = {
"source": "covidcast",
"data_source": "fb-survey",
"signal": "smoothed_wcli",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa",
"time_values": "20200406",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {200})

def test_no_multiples_source_signal(self):
"""Test requests with colon-delimited source-signal param presentation."""
params = {
"source": "covidcast",
"signal": "fb-survey:smoothed_wcli",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa",
"time_values": "20200406",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {200})

def test_multiples_allowed_signal_two_multiples(self):
"""Test requests with 2 multiples and allowed dashboard signal"""
params = {
"source": "covidcast",
"signal": "fb-survey:smoothed_wcli",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa,ny",
"time_values": "20200406,20200407",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {200})

def test_multiples_non_allowed_signal(self):
"""Test requests with 2 multiples and non-allowed dashboard signal"""
params = {
"source": "covidcast",
"signal": "hospital-admissions:smoothed_adj_covid19_from_claims",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa,ny",
"time_values": "20200406,20200407",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {200, 429})

def test_multiples_mixed_allowed_signal_two_multiples(self):
"""Test requests with 2 multiples and mixed-allowed dashboard signal"""
params = {
"source": "covidcast",
"signal": "fb-survey:smoothed_wcli,hospital-admissions:smoothed_adj_covid19_from_claims",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa",
"time_values": "20200406,20200407",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {200, 429})

def test_multiples_allowed_signal_three_multiples(self):
"""Test requests with 3 multiples and allowed dashboard signal"""
params = {
"source": "covidcast",
"signal": "fb-survey:smoothed_wcli,fb-survey:smoothed_wcli",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa,ny",
"time_values": "20200406,20200407",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {401})

def test_multiples_mixed_allowed_signal_three_multiples(self):
"""Test requests with 3 multiples and mixed-allowed dashboard signal"""
params = {
"source": "covidcast",
"signal": "fb-survey:smoothed_wcli,fb-survey:smoothed_wcli1",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa,ny",
"time_values": "20200406,20200407",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {401})

def test_multiples_mixed_allowed_signal_api_key(self):
"""Test requests with 3 multiples and mixed-allowed dashboard signal + valid API Key"""
params = {
"source": "covidcast",
"signal": "fb-survey:smoothed_wcli,fb-survey:smoothed_wcli1",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa,ny",
"time_values": "20200406,20200407",
}
status_codes = set()
for _ in range(10):
status_codes.add(
self._make_request(params=params, auth=self.epidata_client.auth).status_code
)
self.assertEqual(status_codes, {200})

def test_multiples_allowed_signal_api_key(self):
"""Test requests with 3 multiples and allowed dashboard signal + valid API Key"""
params = {
"source": "covidcast",
"signal": "fb-survey:smoothed_wcli,fb-survey:smoothed_wcli",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa,ny",
"time_values": "20200406,20200407",
}
status_codes = set()
for _ in range(10):
status_codes.add(
self._make_request(params=params, auth=self.epidata_client.auth).status_code
)
self.assertEqual(status_codes, {200})

def test_no_multiples_allowed_signal_api_key(self):
"""Test requests with no multiples and allowed dashboard signal + valid API Key"""
params = {
"source": "covidcast",
"signal": "fb-survey:smoothed_wcli",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa",
"time_values": "20200406",
}
status_codes = set()
for _ in range(10):
status_codes.add(
self._make_request(params=params, auth=self.epidata_client.auth).status_code
)
self.assertEqual(status_codes, {200})

def test_no_multiples_allowed_signal_bad_api_key(self):
"""Test requests with no multiples and allowed dashboard signal + bad API Key"""
params = {
"source": "covidcast",
"signal": "fb-survey:smoothed_wcli",
"time_type": "day",
"geo_type": "state",
"geo_value": "pa",
"time_values": "20200406",
}
status_codes = set()
for _ in range(10):
status_codes.add(
self._make_request(
params=params, auth=("bad_key", "bad_email")
).status_code
)
self.assertEqual(status_codes, {200})

def test_restricted_endpoint_no_key(self):
"""Test restricted endpoint with no auth key"""
params = {"source": "cdc", "regions": "1as", "epiweeks": "202020"}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {401})

def test_restricted_endpoint_invalid_key(self):
"""Test restricted endpoint with invalid auth key"""
params = {
"source": "cdc",
"regions": "1as",
"epiweeks": "202020",
"auth": "invalid_key",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {401})

def test_restricted_endpoint_no_roles_key(self):
"""Test restricted endpoint with no roles key"""
params = {
"source": "cdc",
"regions": "1as",
"epiweeks": "202020",
"auth": "key",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {401})

def test_restricted_endpoint_valid_roles_key(self):
"""Test restricted endpoint with valid auth key with required role"""
params = {
"source": "cdc",
"regions": "1as",
"epiweeks": "202020",
"auth": "cdc_key",
}
status_codes = set()
for _ in range(10):
status_codes.add(self._make_request(params=params).status_code)
self.assertEqual(status_codes, {200})
42 changes: 42 additions & 0 deletions integrations/server/test_cdc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# first party
from delphi.epidata.common.integration_test_base_class import DelphiTestBase


class CdcTest(DelphiTestBase):
"""Basic integration tests for cdc endpint."""

def localSetUp(self) -> None:
self.truncate_tables_list = ["cdc_extract"]
self.role_name = "cdc"

def test_cdc(self):
"""Basic integration test for cdc endpoint"""
self.cur.execute(
"INSERT INTO `cdc_extract`(`epiweek`, `state`, `num1`, `num2`, `num3`, `num4`, `num5`, `num6`, `num7`, `num8`, `total`) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
("201102", "AK", "16", "35", "51", "96", "30", "748", "243", "433", "65"),
)
self.cnx.commit()
response = self.epidata_client.cdc(auth="cdc_key", epiweeks=201102, locations="cen9")
self.assertEqual(
response,
{
"epidata": [
{
"location": "cen9",
"epiweek": 201102,
"num1": 16,
"num2": 35,
"num3": 51,
"num4": 96,
"num5": 30,
"num6": 748,
"num7": 243,
"num8": 433,
"total": 65,
"value": None,
}
],
"result": 1,
"message": "success",
},
)
Loading