Skip to content
52 changes: 52 additions & 0 deletions integrations/server/test_covidcast.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ def _insert_placeholder_set_four(self):
for i in [4, 5, 6]
]
self._insert_rows(rows)
return rows

def _insert_placeholder_set_five(self):
rows = [
self._make_placeholder_row(time_value=2000_01_01, value=i*1., stderr=i*10., sample_size=i*100., issue=2000_01_03+i)[0]
for i in [1, 2, 3]
] + [
# different time_values, same issues
self._make_placeholder_row(time_value=2000_01_01+i-3, value=i*1., stderr=i*10., sample_size=i*100., issue=2000_01_03+i-3)[0]
for i in [4, 5, 6]
]
self._insert_rows(rows)
return rows

def test_round_trip(self):
Expand Down Expand Up @@ -237,6 +249,46 @@ def test_location_wildcard(self):
'message': 'success',
})

def test_time_values_wildcard(self):
"""Select all time_values with a wildcard query."""

# insert placeholder data
rows = self._insert_placeholder_set_three()
expected_time_values = [
self.expected_from_row(r) for r in rows[:3]
]

# make the request
response, _ = self.request_based_on_row(rows[0], time_values="*")

self.maxDiff = None
# assert that the right data came back
self.assertEqual(response, {
'result': 1,
'epidata': expected_time_values,
'message': 'success',
})

def test_issues_wildcard(self):
"""Select all issues with a wildcard query."""

# insert placeholder data
rows = self._insert_placeholder_set_five()
expected_issues = [
self.expected_from_row(r) for r in rows[:3]
]

# make the request
response, _ = self.request_based_on_row(rows[0], issues="*")

self.maxDiff = None
# assert that the right data came back
self.assertEqual(response, {
'result': 1,
'epidata': expected_issues,
'message': 'success',
})

def test_signal_wildcard(self):
"""Select all signals with a wildcard query."""

Expand Down
7 changes: 6 additions & 1 deletion src/server/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,10 @@ def _parse_range(part: str):
def parse_date(s: str) -> int:
# parses a given string in format YYYYMMDD or YYYY-MM-DD to a number in the form YYYYMMDD
try:
return int(s.replace("-", ""))
if s == "*":
return s
else:
return int(s.replace("-", ""))
Comment on lines 383 to +387
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
try:
return int(s.replace("-", ""))
if s == "*":
return s
else:
return int(s.replace("-", ""))
if s == "*":
return s
try:
return int(s.replace("-", ""))

the if "*" doesnt need to be in the try block (which is there to make sure s is made up of numbers (and dashes)), and the else is superfluous since the return happens right above it.

except ValueError:
raise ValidationFailedException(f"not a valid date: {s}")

Expand Down Expand Up @@ -477,6 +480,8 @@ def parse_time_set() -> TimeSet:
# old version
require_all("time_type", "time_values")
time_values = extract_dates("time_values")
if time_values == ["*"]:
return TimeSet(time_type, True)
return TimeSet(time_type, time_values)

if ":" not in request.values.get("time", ""):
Expand Down
7 changes: 5 additions & 2 deletions src/server/_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,8 +474,11 @@ def apply_lag_filter(self, history_table: str, lag: Optional[int]) -> "QueryBuil

def apply_issues_filter(self, history_table: str, issues: Optional[TimeValues]) -> "QueryBuilder":
if issues:
self.retable(history_table)
self.where_integers("issue", issues)
if issues == ["*"]:
self.retable(history_table)
else:
self.retable(history_table)
self.where_integers("issue", issues)
Comment on lines +477 to +481
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if issues == ["*"]:
self.retable(history_table)
else:
self.retable(history_table)
self.where_integers("issue", issues)
self.retable(history_table)
if issues != ["*"]:
self.where_integers("issue", issues)

you dont have to repeat the retable() line, and the where_integers() call is better done under the if instead of the else (by reversing the comparison).

return self

def apply_as_of_filter(self, history_table: str, as_of: Optional[int]) -> "QueryBuilder":
Expand Down