diff --git a/tableauserverclient/server/filter.py b/tableauserverclient/server/filter.py index 8802321fd..b936ceb92 100644 --- a/tableauserverclient/server/filter.py +++ b/tableauserverclient/server/filter.py @@ -11,7 +11,11 @@ def __init__(self, field, operator, value): def __str__(self): value_string = str(self._value) if isinstance(self._value, list): - value_string = value_string.replace(" ", "").replace("'", "") + # this should turn the string representation of the list + # from ['', '', ...] + # to [,] + # so effectively, remove any spaces between "," and "'" and then remove all "'" + value_string = value_string.replace(", '", ",'").replace("'", "") return "{0}:{1}:{2}".format(self.field, self.operator, value_string) @property diff --git a/test/assets/request_option_filter_name_in.xml b/test/assets/request_option_filter_name_in.xml new file mode 100644 index 000000000..9ec42b8ab --- /dev/null +++ b/test/assets/request_option_filter_name_in.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test/test_filter.py b/test/test_filter.py new file mode 100644 index 000000000..e2121307f --- /dev/null +++ b/test/test_filter.py @@ -0,0 +1,22 @@ +import os +import unittest + +import tableauserverclient as TSC + + +class FilterTests(unittest.TestCase): + def setUp(self): + pass + + def test_filter_equal(self): + filter = TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, "Superstore") + + self.assertEqual(str(filter), "name:eq:Superstore") + + def test_filter_in(self): + # create a IN filter condition with project names that + # contain spaces and "special" characters + projects_to_find = ["default", "Salesforce Sales Projeśt"] + filter = TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.In, projects_to_find) + + self.assertEqual(str(filter), "name:in:[default,Salesforce Sales Projeśt]") diff --git a/test/test_request_option.py b/test/test_request_option.py index 5d8bdf05e..32526d1e6 100644 --- a/test/test_request_option.py +++ b/test/test_request_option.py @@ -13,6 +13,7 @@ PAGE_NUMBER_XML = os.path.join(TEST_ASSET_DIR, "request_option_page_number.xml") PAGE_SIZE_XML = os.path.join(TEST_ASSET_DIR, "request_option_page_size.xml") FILTER_EQUALS = os.path.join(TEST_ASSET_DIR, "request_option_filter_equals.xml") +FILTER_NAME_IN = os.path.join(TEST_ASSET_DIR, "request_option_filter_name_in.xml") FILTER_TAGS_IN = os.path.join(TEST_ASSET_DIR, "request_option_filter_tags_in.xml") FILTER_MULTIPLE = os.path.join(TEST_ASSET_DIR, "request_option_filter_tags_in.xml") SLICING_QUERYSET = os.path.join(TEST_ASSET_DIR, "request_option_slicing_queryset.xml") @@ -114,6 +115,30 @@ def test_filter_tags_in(self) -> None: self.assertEqual(set(["safari"]), matching_workbooks[1].tags) self.assertEqual(set(["sample"]), matching_workbooks[2].tags) + # check if filtered projects with spaces & special characters + # get correctly returned + def test_filter_name_in(self) -> None: + with open(FILTER_NAME_IN, "rb") as f: + response_xml = f.read().decode("utf-8") + with requests_mock.mock() as m: + m.get( + self.baseurl + "/projects?filter=name%3Ain%3A%5Bdefault%2CSalesforce+Sales+Proje%C5%9Bt%5D", + text=response_xml, + ) + req_option = TSC.RequestOptions() + req_option.filter.add( + TSC.Filter( + TSC.RequestOptions.Field.Name, + TSC.RequestOptions.Operator.In, + ["default", "Salesforce Sales Projeśt"], + ) + ) + matching_projects, pagination_item = self.server.projects.get(req_option) + + self.assertEqual(2, pagination_item.total_available) + self.assertEqual("default", matching_projects[0].name) + self.assertEqual("Salesforce Sales Projeśt", matching_projects[1].name) + def test_filter_tags_in_shorthand(self) -> None: with open(FILTER_TAGS_IN, "rb") as f: response_xml = f.read().decode("utf-8")