10000 Make sure we are loading the expected filetype (#62) · fossabot/document-api-python@4d6ff51 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4d6ff51

Browse files
authored
Make sure we are loading the expected filetype (tableau#62)
* Proper validation that Workbooks load 'twb(x)' and Datasources load 'tds(x)' files only * Small cleanup, move the try inside the with * Add some tests to make sure I don't break anything and cleanup a few small bits
1 parent 7041c9e commit 4d6ff51

File tree

5 files changed

+46
-12
lines changed

5 files changed

+46
-12
lines changed

tableaudocumentapi/datasource.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def __init__(self, dsxml, filename=None):
113113
def from_file(cls, filename):
114114
"""Initialize datasource from file (.tds)"""
115115

116-
dsxml = xml_open(filename).getroot()
116+
dsxml = xml_open(filename, cls.__name__.lower()).getroot()
117117
return cls(dsxml, filename)
118118

119119
def save(self):

tableaudocumentapi/workbook.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, filename):
3232

3333
self._filename = filename
3434

35-
self._workbookTree = xml_open(self._filename)
35+
self._workbookTree = xml_open(self._filename, self.__class__.__name__.lower())
3636

3737
self._workbookRoot = self._workbookTree.getroot()
3838
# prepare our datasource objects

tableaudocumentapi/xfile.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,28 @@ class TableauVersionNotSupportedException(Exception):
1717
pass
1818

1919

20-
def xml_open(filename):
21-
# Determine if this is a twb or twbx and get the xml root
20+
class TableauInvalidFileException(Exception):
21+
pass
22+
23+
24+
def xml_open(filename, expected_root=None):
25+
2226
if zipfile.is_zipfile(filename):
2327
tree = get_xml_from_archive(filename)
2428
else:
2529
tree = ET.parse(filename)
26-
file_version = Version(tree.getroot().attrib.get('version', '0.0'))
30+
31+
tree_root = tree.getroot()
32+
33+
file_version = Version(tree_root.attrib.get('version', '0.0'))
34+
2735
if file_version < MIN_SUPPORTED_VERSION:
2836
raise TableauVersionNotSupportedException(file_version)
37+
38+
if expected_root and (expected_root != tree_root.tag):
39+
raise TableauInvalidFileException(
40+
"'{}'' is not a valid '{}' file".format(filename, expected_root))
41+
2942
return tree
3043

3144

@@ -40,14 +53,13 @@ def temporary_directory(*args, **kwargs):
4053

4154
def find_file_in_zip(zip_file):
4255
for filename in zip_file.namelist():
43-
try:
44-
with zip_file.open(filename) as xml_candidate:
45-
ET.parse(xml_candidate).getroot().tag in (
46-
'workbook', 'datasource')
56+
with zip_file.open(filename) as xml_candidate:
57+
try:
58+
ET.parse(xml_candidate)
4759
return filename
48-
except ET.ParseError:
49-
# That's not an XML file by gosh
50-
pass
60+
except ET.ParseError:
61+
# That's not an XML file by gosh
62+
pass
5163

5264

5365
def get_xml_from_archive(filename):

test/assets/TABLEAU_82_TWB.twb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?xml version='1.0' encoding='utf-8' ?><workbook source-build='9.3.1 (9300.16.0510.0100)' source-platform='mac' version='8.2' xmlns:user='http://www.tableausoftware.com/xml/user'><datasources><datasource caption='xy (TestV1)' inline='true' name='sqlserver.17u3bqc16tjtxn14e2hxh19tyvpo' version='9.3'><connection authentication='sspi' class='sqlserver' dbname='TestV1' odbc-native-protocol='yes' one-time-sql='' server='mssql2012.test.tsi.lan' username=''></connection></datasource></datasources></workbook>

test/bvt.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
import xml.etree.ElementTree as ET
55

66
from tableaudocumentapi import Workbook, Datasource, Connection, ConnectionParser
7+
from tableaudocumentapi.xfile import TableauInvalidFileException, TableauVersionNotSupportedException
78

89
TEST_DIR = os.path.dirname(__file__)
910

11+
TABLEAU_82_TWB = os.path.join(TEST_DIR, 'assets', 'TABLEAU_82_TWB.twb')
12+
1013
TABLEAU_93_TWB = os.path.join(TEST_DIR, 'assets', 'TABLEAU_93_TWB.twb')
1114

1215
TABLEAU_93_TDS = os.path.join(TEST_DIR, 'assets', 'TABLEAU_93_TDS.tds')
@@ -289,10 +292,28 @@ def test_can_open_twbx_and_save_as_changes(self):
289292

290293

291294
class EmptyWorkbookWillLoad(unittest.TestCase):
295+
292296
def test_no_exceptions_thrown(self):
293297
wb = Workbook(EMPTY_WORKBOOK)
294298
self.assertIsNotNone(wb)
295299

296300

301+
class LoadOnlyValidFileTypes(unittest.TestCase):
302+
303+
def test_exception_when_workbook_given_tdsx(self):
304+
with self.assertRaises(TableauInvalidFileException):
305+
wb = Workbook(TABLEAU_10_TDSX)
306+
307+
def test_exception_when_datasource_given_twbx(self):
308+
with self.assertRaises(TableauInvalidFileException):
309+
ds = Datasource.from_file(TABLEAU_10_TWBX)
310+
311+
312+
class SupportedWorkbookVersions(unittest.TestCase):
313+
314+
def test_82_workbook_throws_exception(self):
315+
with self.assertRaises(TableauVersionNotSupportedException):
316+
wb = Workbook(TABLEAU_82_TWB)
317+
297318
if __name__ == '__main__':
298319
unittest.main()

0 commit comments

Comments
 (0)
0