Skip to content

Commit 841d0c2

Browse files
committed
adapt testsuite to /v2. See ExpDev07#65
1 parent f64b1ab commit 841d0c2

File tree

13 files changed

+324
-109
lines changed

13 files changed

+324
-109
lines changed

app/routes/v2/locations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ def location(id):
3737
'location': {
3838
**jhu.get(id).serialize(), **{ 'timelines': timelines }
3939
}
40-
})
40+
})

tests/expected_output/v1_all.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"locations":[{"coordinates":{"latitude":"15","longitude":"101"},"country":"Thailand","country_code":"TH","id":0,"latest":{"confirmed":114,"deaths":114,"recovered":114},"province":""},{"coordinates":{"latitude":"36","longitude":"138"},"country":"Japan","country_code":"JP","id":1,"latest":{"confirmed":839,"deaths":839,"recovered":839},"province":""},{"coordinates":{"latitude":"1.2833","longitude":"103.8333"},"country":"Singapore","country_code":"SG","id":2,"latest":{"confirmed":226,"deaths":226,"recovered":226},"province":""},{"coordinates":{"latitude":"28.1667","longitude":"84.25"},"country":"Nepal","country_code":"NP","id":3,"latest":{"confirmed":1,"deaths":1,"recovered":1},"province":""},{"coordinates":{"latitude":"2.5","longitude":"112.5"},"country":"Malaysia","country_code":"MY","id":4,"latest":{"confirmed":428,"deaths":428,"recovered":428},"province":""},{"coordinates":{"latitude":"49.2827","longitude":"-123.1207"},"country":"Canada","country_code":"CA","id":5,"latest":{"confirmed":73,"deaths":73,"recovered":73},"province":"British Columbia"},{"coordinates":{"latitude":"-33.8688","longitude":"151.2093"},"country":"Australia","country_code":"AU","id":6,"latest":{"confirmed":134,"deaths":134,"recovered":134},"province":"New South Wales"},{"coordinates":{"latitude":"-37.8136","longitude":"144.9631"},"country":"Australia","country_code":"AU","id":7,"latest":{"confirmed":57,"deaths":57,"recovered":57},"province":"Victoria"},{"coordinates":{"latitude":"-28.0167","longitude":"153.4"},"country":"Australia","country_code":"AU","id":8,"latest":{"confirmed":61,"deaths":61,"recovered":61},"province":"Queensland"},{"coordinates":{"latitude":"11.55","longitude":"104.9167"},"country":"Cambodia","country_code":"KH","id":9,"latest":{"confirmed":7,"deaths":7,"recovered":7},"province":""}]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"location":{"coordinates":{"latitude":"36","longitude":"138"},"country":"Japan","country_code":"JP","id":1,"latest":{"confirmed":839,"deaths":839,"recovered":839},"province":"","timelines":{"confirmed":{"latest":839,"timeline":{"2020-01-22T00:00:00Z":2,"2020-01-23T00:00:00Z":1,"2020-01-24T00:00:00Z":2,"2020-01-25T00:00:00Z":2,"2020-01-26T00:00:00Z":4,"2020-01-27T00:00:00Z":4,"2020-01-28T00:00:00Z":7,"2020-01-29T00:00:00Z":7,"2020-01-30T00:00:00Z":11,"2020-01-31T00:00:00Z":15,"2020-02-01T00:00:00Z":20,"2020-02-02T00:00:00Z":20,"2020-02-03T00:00:00Z":20,"2020-02-04T00:00:00Z":22,"2020-02-05T00:00:00Z":22,"2020-02-06T00:00:00Z":45,"2020-02-07T00:00:00Z":25,"2020-02-08T00:00:00Z":25,"2020-02-09T00:00:00Z":26,"2020-02-10T00:00:00Z":26,"2020-02-11T00:00:00Z":26,"2020-02-12T00:00:00Z":28,"2020-02-13T00:00:00Z":28,"2020-02-14T00:00:00Z":29,"2020-02-15T00:00:00Z":43,"2020-02-16T00:00:00Z":59,"2020-02-17T00:00:00Z":66,"2020-02-18T00:00:00Z":74,"2020-02-19T00:00:00Z":84,"2020-02-20T00:00:00Z":94,"2020-02-21T00:00:00Z":105,"2020-02-22T00:00:00Z":122,"2020-02-23T00:00:00Z":147,"2020-02-24T00:00:00Z":159,"2020-02-25T00:00:00Z":170,"2020-02-26T00:00:00Z":189,"2020-02-27T00:00:00Z":214,"2020-02-28T00:00:00Z":228,"2020-02-29T00:00:00Z":241,"2020-03-01T00:00:00Z":256,"2020-03-02T00:00:00Z":274,"2020-03-03T00:00:00Z":293,"2020-03-04T00:00:00Z":331,"2020-03-05T00:00:00Z":360,"2020-03-06T00:00:00Z":420,"2020-03-07T00:00:00Z":461,"2020-03-08T00:00:00Z":502,"2020-03-09T00:00:00Z":511,"2020-03-10T00:00:00Z":581,"2020-03-11T00:00:00Z":639,"2020-03-12T00:00:00Z":639,"2020-03-13T00:00:00Z":701,"2020-03-14T00:00:00Z":773,"2020-03-15T00:00:00Z":839}},"deaths":{"latest":839,"timeline":{"2020-01-22T00:00:00Z":2,"2020-01-23T00:00:00Z":1,"2020-01-24T00:00:00Z":2,"2020-01-25T00:00:00Z":2,"2020-01-26T00:00:00Z":4,"2020-01-27T00:00:00Z":4,"2020-01-28T00:00:00Z":7,"2020-01-29T00:00:00Z":7,"2020-01-30T00:00:00Z":11,"2020-01-31T00:00:00Z":15,"2020-02-01T00:00:00Z":20,"2020-02-02T00:00:00Z":20,"2020-02-03T00:00:00Z":20,"2020-02-04T00:00:00Z":22,"2020-02-05T00:00:00Z":22,"2020-02-06T00:00:00Z":45,"2020-02-07T00:00:00Z":25,"2020-02-08T00:00:00Z":25,"2020-02-09T00:00:00Z":26,"2020-02-10T00:00:00Z":26,"2020-02-11T00:00:00Z":26,"2020-02-12T00:00:00Z":28,"2020-02-13T00:00:00Z":28,"2020-02-14T00:00:00Z":29,"2020-02-15T00:00:00Z":43,"2020-02-16T00:00:00Z":59,"2020-02-17T00:00:00Z":66,"2020-02-18T00:00:00Z":74,"2020-02-19T00:00:00Z":84,"2020-02-20T00:00:00Z":94,"2020-02-21T00:00:00Z":105,"2020-02-22T00:00:00Z":122,"2020-02-23T00:00:00Z":147,"2020-02-24T00:00:00Z":159,"2020-02-25T00:00:00Z":170,"2020-02-26T00:00:00Z":189,"2020-02-27T00:00:00Z":214,"2020-02-28T00:00:00Z":228,"2020-02-29T00:00:00Z":241,"2020-03-01T00:00:00Z":256,"2020-03-02T00:00:00Z":274,"2020-03-03T00:00:00Z":293,"2020-03-04T00:00:00Z":331,"2020-03-05T00:00:00Z":360,"2020-03-06T00:00:00Z":420,"2020-03-07T00:00:00Z":461,"2020-03-08T00:00:00Z":502,"2020-03-09T00:00:00Z":511,"2020-03-10T00:00:00Z":581,"2020-03-11T00:00:00Z":639,"2020-03-12T00:00:00Z":639,"2020-03-13T00:00:00Z":701,"2020-03-14T00:00:00Z":773,"2020-03-15T00:00:00Z":839}},"recovered":{"latest":839,"timeline":{"2020-01-22T00:00:00Z":2,"2020-01-23T00:00:00Z":1,"2020-01-24T00:00:00Z":2,"2020-01-25T00:00:00Z":2,"2020-01-26T00:00:00Z":4,"2020-01-27T00:00:00Z":4,"2020-01-28T00:00:00Z":7,"2020-01-29T00:00:00Z":7,"2020-01-30T00:00:00Z":11,"2020-01-31T00:00:00Z":15,"2020-02-01T00:00:00Z":20,"2020-02-02T00:00:00Z":20,"2020-02-03T00:00:00Z":20,"2020-02-04T00:00:00Z":22,"2020-02-05T00:00:00Z":22,"2020-02-06T00:00:00Z":45,"2020-02-07T00:00:00Z":25,"2020-02-08T00:00:00Z":25,"2020-02-09T00:00:00Z":26,"2020-02-10T00:00:00Z":26,"2020-02-11T00:00:00Z":26,"2020-02-12T00:00:00Z":28,"2020-02-13T00:00:00Z":28,"2020-02-14T00:00:00Z":29,"2020-02-15T00:00:00Z":43,"2020-02-16T00:00:00Z":59,"2020-02-17T00:00:00Z":66,"2020-02-18T00:00:00Z":74,"2020-02-19T00:00:00Z":84,"2020-02-20T00:00:00Z":94,"2020-02-21T00:00:00Z":105,"2020-02-22T00:00:00Z":122,"2020-02-23T00:00:00Z":147,"2020-02-24T00:00:00Z":159,"2020-02-25T00:00:00Z":170,"2020-02-26T00:00:00Z":189,"2020-02-27T00:00:00Z":214,"2020-02-28T00:00:00Z":228,"2020-02-29T00:00:00Z":241,"2020-03-01T00:00:00Z":256,"2020-03-02T00:00:00Z":274,"2020-03-03T00:00:00Z":293,"2020-03-04T00:00:00Z":331,"2020-03-05T00:00:00Z":360,"2020-03-06T00:00:00Z":420,"2020-03-07T00:00:00Z":461,"2020-03-08T00:00:00Z":502,"2020-03-09T00:00:00Z":511,"2020-03-10T00:00:00Z":581,"2020-03-11T00:00:00Z":639,"2020-03-12T00:00:00Z":639,"2020-03-13T00:00:00Z":701,"2020-03-14T00:00:00Z":773,"2020-03-15T00:00:00Z":839}}}}}

tests/test_coordinates.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from unittest import mock
2+
import pytest
3+
4+
from app import coordinates
5+
6+
@pytest.mark.parametrize("latitude, longitude",
7+
[("1", "2"),
8+
(100, "2"),
9+
(-3, 0),
10+
(-10, -10000000)])
11+
def test_coordinates_class(latitude, longitude):
12+
coord_obj = coordinates.Coordinates(latitude=latitude,
13+
longitude=longitude)
14+
15+
#validate serialize
16+
check_obj = {'latitude' : latitude,
17+
'longitude': longitude}
18+
19+
assert coord_obj.serialize() == check_obj

tests/test_data.py

Lines changed: 0 additions & 71 deletions
This file was deleted.

tests/test_jhu.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
from unittest import mock
2+
import datetime
3+
import pytest
4+
5+
import app
6+
from app.utils import date
7+
from app import location
8+
from app.services.location import jhu
9+
10+
DATETIME_STRING = "2020-03-17T10:23:22.505550"
11+
12+
def mocked_requests_get(*args, **kwargs):
13+
class FakeRequestsGetResponse:
14+
"""
15+
Returns instance of `FakeRequestsGetResponse`
16+
when calling `app.services.location.jhu.requests.get()`
17+
"""
18+
def __init__(self, url, filename, state):
19+
self.url = url
20+
self.filename = filename
21+
self.state = state
22+
self.text = self.read_file(self.state)
23+
24+
25+
def read_file(self, state):
26+
"""
27+
Mock HTTP GET-method and return text from file
28+
"""
29+
filepath = "tests/example_data/time_series_19-covid-{}.csv".format(state)
30+
print("Try to read {}".format(filepath))
31+
with open(filepath, "r") as file:
32+
return file.read()
33+
34+
#get url from `request.get`
35+
url = args[0]
36+
#get filename from url
37+
filename = url.split("/")[-1]
38+
#clean up for id token (e.g. Deaths)
39+
state = filename.split("-")[-1].replace(".csv", "").lower().capitalize()
40+
41+
return FakeRequestsGetResponse(url, filename, state)
42+
43+
def mocked_strptime_isoformat(*args, **kwargs):
44+
class DateTimeStrpTime:
45+
"""
46+
Returns instance of `DateTimeStrpTime`
47+
when calling `app.services.location.jhu.datetime.trptime(date, '%m/%d/%y').isoformat()`
48+
"""
49+
def __init__(self, date, strformat):
50+
self.date = date
51+
self.strformat = strformat
52+
53+
def isoformat(self):
54+
return datetime.datetime.strptime(self.date, self.strformat).isoformat()
55+
56+
date = args[0]
57+
strformat = args[1]
58+
59+
return DateTimeStrpTime(date, strformat)
60+
61+
@pytest.mark.parametrize("category, capitalize_category",
62+
[("deaths", "Deaths"),
63+
("recovered", "Recovered"),
64+
("confirmed", "Confirmed")])
65+
@mock.patch('app.services.location.jhu.requests.get', side_effect=mocked_requests_get)
66+
def test_validate_category(mock_request_get, category, capitalize_category):
67+
base_url = 'https://raw.githubusercontent.com/CSSEGISandData/2019-nCoV/\
68+
master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-%s.csv'
69+
70+
request = app.services.location.jhu.requests.get(base_url % category)
71+
assert request.state == capitalize_category
72+
73+
@pytest.mark.parametrize("category, datetime_str, latest_value, country_name, \
74+
country_code, province, latest_country_value, \
75+
coordinate_lat, coordinate_long",
76+
[("deaths", DATETIME_STRING, 1940, "Thailand", "TH", "",
77+
114, "15", "101"),
78+
("recovered", DATETIME_STRING, 1940, "Thailand", "TH", "",
79+
114, "15", "101"),
80+
("confirmed", DATETIME_STRING, 1940, "Thailand", "TH", "",
81+
114, "15", "101")])
82+
@mock.patch('app.services.location.jhu.datetime')
83+
@mock.patch('app.services.location.jhu.requests.get', side_effect=mocked_requests_get)
84+
def test_get_category(mock_request_get, mock_datetime, category, datetime_str,
85+
latest_value, country_name, country_code, province, latest_country_value,
86+
coordinate_lat, coordinate_long):
87+
#mock app.services.location.jhu.datetime.utcnow().isoformat()
88+
mock_datetime.utcnow.return_value.isoformat.return_value = datetime_str
89+
output = jhu.get_category(category)
90+
91+
#simple schema validation
92+
assert output["source"] == "https://github.com/ExpDev07/coronavirus-tracker-api"
93+
94+
assert isinstance(output["latest"], int)
95+
assert output["latest"] == latest_value #based on example data
96+
97+
#check for valid datestring
98+
assert date.is_date(output["last_updated"]) is True
99+
#ensure date formating
100+
assert output["last_updated"] == datetime_str + "Z" #based on example data
101+
102+
#validate location schema
103+
location_entry = output["locations"][0]
104+
105+
assert isinstance(location_entry["country"], str)
106+
assert location_entry["country"] == country_name #based on example data
107+
108+
assert isinstance(location_entry["country_code"], str)
109+
assert len(location_entry["country_code"]) == 2
110+
assert location_entry["country_code"] == country_code #based on example data
111+
112+
assert isinstance(location_entry["province"], str)
113+
assert location_entry["province"] == province #based on example data
114+
115+
assert isinstance(location_entry["latest"], int)
116+
assert location_entry["latest"] == latest_country_value #based on example data
117+
118+
#validate coordinates in location
119+
coordinates = location_entry["coordinates"]
120+
121+
assert isinstance(coordinates["lat"], str)
122+
assert coordinates["lat"] == coordinate_lat
123+
124+
assert isinstance(coordinates["long"], str)
125+
assert coordinates["long"] == coordinate_long
126+
127+
#validate history in location
128+
history = location_entry["history"]
129+
assert date.is_date(list(history.keys())[0]) is True
130+
assert isinstance(list(history.values())[0], int)
131+
132+
@mock.patch('app.services.location.jhu.datetime')
133+
@mock.patch('app.services.location.jhu.requests.get', side_effect=mocked_requests_get)
134+
def test_get_locations(mock_request_get, mock_datetime):
135+
#mock app.services.location.jhu.datetime.utcnow().isoformat()
136+
mock_datetime.utcnow.return_value.isoformat.return_value = DATETIME_STRING
137+
mock_datetime.strptime.side_effect = mocked_strptime_isoformat
138+
139+
output = jhu.get_locations()
140+
assert isinstance(output, list)
141+
assert isinstance(output[0], location.Location)
142+
143+
#`jhu.get_locations()` creates id based on confirmed list
144+
location_confirmed = jhu.get_category("confirmed")
145+
assert len(output) == len(location_confirmed["locations"])

0 commit comments

Comments
 (0)