mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-16 05:07:55 +08:00
* move common code into server, update tests and makefile remove backend directory, refactor update smoke tests
80 lines
2.6 KiB
Python
80 lines
2.6 KiB
Python
import unittest
|
|
from urllib.parse import parse_qs
|
|
from werkzeug.datastructures import MultiDict
|
|
from server.common.errors import FilterError
|
|
from server.common.rest import _query_parameter_to_filter
|
|
|
|
|
|
def _qsparse(qs):
|
|
""" emulate what Flask/Werkzeug do to our QS """
|
|
return MultiDict(parse_qs(qs))
|
|
|
|
|
|
class FilterParseTests(unittest.TestCase):
|
|
""" Test cases for various filter parsing """
|
|
|
|
def test_queryparam_to_filter_parse(self):
|
|
# categories
|
|
self.assertEqual(
|
|
_query_parameter_to_filter(_qsparse("obs:foo=bar&var:baz=133&var:baz=A&obs:baz=foo")),
|
|
{
|
|
"obs": {"annotation_value": [{"name": "foo", "values": ["bar"]}, {"name": "baz", "values": ["foo"]}]},
|
|
"var": {"annotation_value": [{"name": "baz", "values": ["133", "A"]}]},
|
|
},
|
|
)
|
|
|
|
# ranges
|
|
self.assertEqual(
|
|
_query_parameter_to_filter(_qsparse("obs:A=1,99&obs:B=*,100&obs:C=0,*")),
|
|
{
|
|
"obs": {
|
|
"annotation_value": [
|
|
{"name": "A", "min": 1, "max": 99.0},
|
|
{"name": "B", "max": 100.0},
|
|
{"name": "C", "min": 0.0},
|
|
]
|
|
},
|
|
},
|
|
)
|
|
|
|
# combo
|
|
self.assertEqual(
|
|
_query_parameter_to_filter(_qsparse("var:B=YES&var:A=1,99&var:B=NO")),
|
|
{
|
|
"var": {
|
|
"annotation_value": [
|
|
{"name": "B", "values": ["YES", "NO"]},
|
|
{"name": "A", "min": 1.0, "max": 99.0},
|
|
]
|
|
},
|
|
},
|
|
)
|
|
|
|
def test_queryparam_to_filter_escaping(self):
|
|
self.assertEqual(
|
|
_query_parameter_to_filter(_qsparse("obs:var=%2521%252C%253AOK%253D&obs:A%2521=YO")),
|
|
{"obs": {"annotation_value": [{"name": "var", "values": ["!,:OK="]}, {"name": "A!", "values": ["YO"]}]}},
|
|
)
|
|
|
|
def test_queryparam_to_filter_errors(self):
|
|
|
|
# should raise FilterError
|
|
filter_errors = [
|
|
"foo=bar", # no axis
|
|
"X=&Y=3", # no value
|
|
"X&Y=3", # no value
|
|
"moo:foo=bar", # bad axis
|
|
"obs:x=1,A", # non-numeric range
|
|
"var:X=1,2&var:X=3,4", # duplicate ranges
|
|
"var:Y=,",
|
|
"var:Y=2,",
|
|
"var:Y=,5",
|
|
"var:Y=*,",
|
|
"var:Y=,*",
|
|
"var:Y=*,*",
|
|
]
|
|
|
|
for qs in filter_errors:
|
|
with self.assertRaises(FilterError):
|
|
_query_parameter_to_filter(_qsparse(qs))
|