diff --git a/tableauserverclient/models/property_decorators.py b/tableauserverclient/models/property_decorators.py index 1b3b7ccaa..de8fe8d8c 100644 --- a/tableauserverclient/models/property_decorators.py +++ b/tableauserverclient/models/property_decorators.py @@ -1,3 +1,4 @@ +import re from functools import wraps @@ -84,3 +85,17 @@ def wrapper(self, value): return wrapper return property_type_decorator + + +def property_matches(regex_to_match, error): + + compiled_re = re.compile(regex_to_match) + + def wrapper(func): + @wraps(func) + def validate_regex_decorator(self, value): + if not compiled_re.match(value): + raise ValueError(error) + return func(self, value) + return validate_regex_decorator + return wrapper diff --git a/tableauserverclient/models/site_item.py b/tableauserverclient/models/site_item.py index 283eca192..40a49e453 100644 --- a/tableauserverclient/models/site_item.py +++ b/tableauserverclient/models/site_item.py @@ -1,8 +1,12 @@ import xml.etree.ElementTree as ET -from .property_decorators import property_is_enum, property_is_boolean, property_not_empty, property_not_nullable +from .property_decorators import (property_is_enum, property_is_boolean, property_matches, + property_not_empty, property_not_nullable) from .. import NAMESPACE +VALID_CONTENT_URL_RE = r"^[a-zA-Z0-9_\-]*$" + + class SiteItem(object): class AdminMode: ContentAndUsers = 'ContentAndUsers' @@ -45,6 +49,7 @@ def content_url(self): @content_url.setter @property_not_nullable + @property_matches(VALID_CONTENT_URL_RE, "content_url can contain only letters, numbers, dashes, and underscores") def content_url(self, value): self._content_url = value diff --git a/test/test_site_model.py b/test/test_site_model.py index 02735ed8c..99fa73ce9 100644 --- a/test/test_site_model.py +++ b/test/test_site_model.py @@ -1,3 +1,5 @@ +# coding=utf-8 + import unittest import tableauserverclient as TSC @@ -19,10 +21,21 @@ def test_invalid_admin_mode(self): site.admin_mode = "Hello" def test_invalid_content_url(self): - self.assertRaises(ValueError, TSC.SiteItem, "site", None) - site = TSC.SiteItem("site", "url") + with self.assertRaises(ValueError): - site.content_url = None + site = TSC.SiteItem(name="蚵仔煎", content_url="蚵仔煎") + + with self.assertRaises(ValueError): + site = TSC.SiteItem(name="蚵仔煎", content_url=None) + + def test_set_valid_content_url(self): + # Default Site + site = TSC.SiteItem(name="Default", content_url="") + self.assertEqual(site.content_url, "") + + # Unicode Name and ascii content_url + site = TSC.SiteItem(name="蚵仔煎", content_url="omlette") + self.assertEqual(site.content_url, "omlette") def test_invalid_disable_subscriptions(self): site = TSC.SiteItem("site", "url")