From 977d47d904ae98d9006d2ea082336c4d3770c5f0 Mon Sep 17 00:00:00 2001 From: Jordan Woods <13803242+jorwoods@users.noreply.github.com> Date: Fri, 29 Aug 2025 20:13:42 -0500 Subject: [PATCH 1/3] chore: pytestify test_custom_view --- test/test_custom_view.py | 614 ++++++++++++++++++++------------------- 1 file changed, 315 insertions(+), 299 deletions(-) diff --git a/test/test_custom_view.py b/test/test_custom_view.py index 6e863a863..525abd0b1 100644 --- a/test/test_custom_view.py +++ b/test/test_custom_view.py @@ -3,8 +3,8 @@ import os from pathlib import Path from tempfile import TemporaryDirectory -import unittest +import pytest import requests_mock import tableauserverclient as TSC @@ -14,307 +14,323 @@ TEST_ASSET_DIR = Path(__file__).parent / "assets" -GET_XML = os.path.join(TEST_ASSET_DIR, "custom_view_get.xml") -GET_XML_ID = os.path.join(TEST_ASSET_DIR, "custom_view_get_id.xml") -POPULATE_PREVIEW_IMAGE = os.path.join(TEST_ASSET_DIR, "Sample View Image.png") -CUSTOM_VIEW_UPDATE_XML = os.path.join(TEST_ASSET_DIR, "custom_view_update.xml") -CUSTOM_VIEW_POPULATE_PDF = os.path.join(TEST_ASSET_DIR, "populate_pdf.pdf") -CUSTOM_VIEW_POPULATE_CSV = os.path.join(TEST_ASSET_DIR, "populate_csv.csv") +GET_XML = TEST_ASSET_DIR / "custom_view_get.xml" +GET_XML_ID = TEST_ASSET_DIR / "custom_view_get_id.xml" +POPULATE_PREVIEW_IMAGE = TEST_ASSET_DIR / "Sample View Image.png" +CUSTOM_VIEW_UPDATE_XML = TEST_ASSET_DIR / "custom_view_update.xml" +CUSTOM_VIEW_POPULATE_PDF = TEST_ASSET_DIR / "populate_pdf.pdf" +CUSTOM_VIEW_POPULATE_CSV = TEST_ASSET_DIR / "populate_csv.csv" CUSTOM_VIEW_DOWNLOAD = TEST_ASSET_DIR / "custom_view_download.json" FILE_UPLOAD_INIT = TEST_ASSET_DIR / "fileupload_initialize.xml" FILE_UPLOAD_APPEND = TEST_ASSET_DIR / "fileupload_append.xml" -class CustomViewTests(unittest.TestCase): - def setUp(self): - self.server = TSC.Server("http://test", False) - self.server.version = "3.21" # custom views only introduced in 3.19 - - # Fake sign in - self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" - self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" - - self.baseurl = self.server.custom_views.baseurl - - def test_get(self) -> None: - with open(GET_XML, "rb") as f: - response_xml = f.read().decode("utf-8") - print(response_xml) - with requests_mock.mock() as m: - m.get(self.baseurl, text=response_xml) - all_views, pagination_item = self.server.custom_views.get() - - self.assertEqual(2, pagination_item.total_available) - self.assertEqual("d79634e1-6063-4ec9-95ff-50acbf609ff5", all_views[0].id) - self.assertEqual("ENDANGERED SAFARI", all_views[0].name) - self.assertEqual("SafariSample/sheets/ENDANGEREDSAFARI", all_views[0].content_url) - self.assertEqual("3cc6cd06-89ce-4fdc-b935-5294135d6d42", all_views[0].workbook.id) - self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_views[0].owner.id) - self.assertIsNone(all_views[0].created_at) - self.assertIsNone(all_views[0].updated_at) - self.assertFalse(all_views[0].shared) - - self.assertEqual("fd252f73-593c-4c4e-8584-c032b8022adc", all_views[1].id) - self.assertEqual("Overview", all_views[1].name) - self.assertEqual("6d13b0ca-043d-4d42-8c9d-3f3313ea3a00", all_views[1].workbook.id) - self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", all_views[1].owner.id) - self.assertEqual("2002-05-30T09:00:00Z", format_datetime(all_views[1].created_at)) - self.assertEqual("2002-06-05T08:00:59Z", format_datetime(all_views[1].updated_at)) - self.assertTrue(all_views[1].shared) - - def test_get_by_id(self) -> None: - with open(GET_XML_ID, "rb") as f: - response_xml = f.read().decode("utf-8") - with requests_mock.mock() as m: - m.get(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5", text=response_xml) - view: TSC.CustomViewItem = self.server.custom_views.get_by_id("d79634e1-6063-4ec9-95ff-50acbf609ff5") - - self.assertEqual("d79634e1-6063-4ec9-95ff-50acbf609ff5", view.id) - self.assertEqual("ENDANGERED SAFARI", view.name) - self.assertEqual("SafariSample/sheets/ENDANGEREDSAFARI", view.content_url) - if view.workbook: - self.assertEqual("3cc6cd06-89ce-4fdc-b935-5294135d6d42", view.workbook.id) - if view.owner: - self.assertEqual("5de011f8-5aa9-4d5b-b991-f462c8dd6bb7", view.owner.id) - if view.view: - self.assertEqual("5241e88d-d384-4fd7-9c2f-648b5247efc5", view.view.id) - self.assertEqual("2002-05-30T09:00:00Z", format_datetime(view.created_at)) - self.assertEqual("2002-06-05T08:00:59Z", format_datetime(view.updated_at)) - - def test_get_by_id_missing_id(self) -> None: - self.assertRaises(TSC.MissingRequiredFieldError, self.server.custom_views.get_by_id, None) - - def test_get_before_signin(self) -> None: - self.server._auth_token = None - self.assertRaises(TSC.NotSignedInError, self.server.custom_views.get) - - def test_populate_image(self) -> None: - with open(POPULATE_PREVIEW_IMAGE, "rb") as f: - response = f.read() - with requests_mock.mock() as m: - m.get(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/image", content=response) - single_view = TSC.CustomViewItem() - single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" - self.server.custom_views.populate_image(single_view) - self.assertEqual(response, single_view.image) - - def test_populate_image_with_options(self) -> None: - with open(POPULATE_PREVIEW_IMAGE, "rb") as f: - response = f.read() - with requests_mock.mock() as m: - m.get( - self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/image?resolution=high&maxAge=10", content=response - ) - single_view = TSC.CustomViewItem() - single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" - req_option = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High, maxage=10) - self.server.custom_views.populate_image(single_view, req_option) - self.assertEqual(response, single_view.image) - - def test_populate_image_missing_id(self) -> None: +@pytest.fixture(scope="function") +def server() -> TSC.Server: + server = TSC.Server("http://test", False) + server.version = "3.21" # custom views only introduced in 3.19 + + # Fake sign in + server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" + server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" + + return server + + +def test_get(server) -> None: + response_xml = GET_XML.read_text() + print(response_xml) + with requests_mock.mock() as m: + m.get(server.custom_views.baseurl, text=response_xml) + all_views, pagination_item = server.custom_views.get() + + assert 2 == pagination_item.total_available + assert "d79634e1-6063-4ec9-95ff-50acbf609ff5" == all_views[0].id + assert "ENDANGERED SAFARI" == all_views[0].name + assert "SafariSample/sheets/ENDANGEREDSAFARI" == all_views[0].content_url + assert "3cc6cd06-89ce-4fdc-b935-5294135d6d42" == all_views[0].workbook.id + assert "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" == all_views[0].owner.id + assert all_views[0].created_at is None + assert all_views[0].updated_at is None + assert not all_views[0].shared + + assert "fd252f73-593c-4c4e-8584-c032b8022adc" == all_views[1].id + assert "Overview" == all_views[1].name + assert "6d13b0ca-043d-4d42-8c9d-3f3313ea3a00" == all_views[1].workbook.id + assert "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" == all_views[1].owner.id + assert "2002-05-30T09:00:00Z" == format_datetime(all_views[1].created_at) + assert "2002-06-05T08:00:59Z" == format_datetime(all_views[1].updated_at) + assert all_views[1].shared + + +def test_get_by_id(server) -> None: + response_xml = GET_XML_ID.read_text() + with requests_mock.mock() as m: + m.get(server.custom_views.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5", text=response_xml) + view: TSC.CustomViewItem = server.custom_views.get_by_id("d79634e1-6063-4ec9-95ff-50acbf609ff5") + + assert "d79634e1-6063-4ec9-95ff-50acbf609ff5" == view.id + assert "ENDANGERED SAFARI" == view.name + assert "SafariSample/sheets/ENDANGEREDSAFARI" == view.content_url + if view.workbook: + assert "3cc6cd06-89ce-4fdc-b935-5294135d6d42" == view.workbook.id + if view.owner: + assert "5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" == view.owner.id + if view.view: + assert "5241e88d-d384-4fd7-9c2f-648b5247efc5" == view.view.id + assert "2002-05-30T09:00:00Z" == format_datetime(view.created_at) + assert "2002-06-05T08:00:59Z" == format_datetime(view.updated_at) + + +def test_get_by_id_missing_id(server) -> None: + with pytest.raises(TSC.MissingRequiredFieldError): + server.custom_views.get_by_id(None) + + +def test_get_before_signin(server) -> None: + server._auth_token = None + with pytest.raises(TSC.NotSignedInError): + server.custom_views.get() + + +def test_populate_image(server) -> None: + response = POPULATE_PREVIEW_IMAGE.read_bytes() + with requests_mock.mock() as m: + m.get(server.custom_views.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/image", content=response) single_view = TSC.CustomViewItem() - single_view._id = None - self.assertRaises(TSC.MissingRequiredFieldError, self.server.custom_views.populate_image, single_view) - - def test_delete(self) -> None: - with requests_mock.mock() as m: - m.delete(self.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42", status_code=204) - self.server.custom_views.delete("3cc6cd06-89ce-4fdc-b935-5294135d6d42") - - def test_delete_missing_id(self) -> None: - self.assertRaises(ValueError, self.server.custom_views.delete, "") - - def test_update(self) -> None: - with open(CUSTOM_VIEW_UPDATE_XML, "rb") as f: - response_xml = f.read().decode("utf-8") - with requests_mock.mock() as m: - m.put(self.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2", text=response_xml) - the_custom_view = TSC.CustomViewItem("1d0304cd-3796-429f-b815-7258370b9b74", name="Best test ever") - the_custom_view._id = "1f951daf-4061-451a-9df1-69a8062664f2" - the_custom_view.owner = TSC.UserItem() - the_custom_view.owner.id = "dd2239f6-ddf1-4107-981a-4cf94e415794" - the_custom_view = self.server.custom_views.update(the_custom_view) - - self.assertEqual("1f951daf-4061-451a-9df1-69a8062664f2", the_custom_view.id) - if the_custom_view.owner: - self.assertEqual("dd2239f6-ddf1-4107-981a-4cf94e415794", the_custom_view.owner.id) - self.assertEqual("Best test ever", the_custom_view.name) - - def test_update_missing_id(self) -> None: - cv = TSC.CustomViewItem(name="test") - self.assertRaises(TSC.MissingRequiredFieldError, self.server.custom_views.update, cv) - - def test_download(self) -> None: - cv = TSC.CustomViewItem(name="test") - cv._id = "1f951daf-4061-451a-9df1-69a8062664f2" - content = CUSTOM_VIEW_DOWNLOAD.read_bytes() - data = io.BytesIO() - with requests_mock.mock() as m: - m.get(f"{self.server.custom_views.expurl}/1f951daf-4061-451a-9df1-69a8062664f2/content", content=content) - self.server.custom_views.download(cv, data) - - assert data.getvalue() == content - - def test_publish_filepath(self) -> None: - cv = TSC.CustomViewItem(name="test") - cv._owner = TSC.UserItem() - cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" - cv._workbook = TSC.WorkbookItem() - cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" - with requests_mock.mock() as m: - m.post(self.server.custom_views.expurl, status_code=201, text=Path(GET_XML).read_text()) - view = self.server.custom_views.publish(cv, CUSTOM_VIEW_DOWNLOAD) - - assert view is not None - assert isinstance(view, TSC.CustomViewItem) - assert view.id is not None - assert view.name is not None - - def test_publish_file_str(self) -> None: - cv = TSC.CustomViewItem(name="test") - cv._owner = TSC.UserItem() - cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" - cv._workbook = TSC.WorkbookItem() - cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" - with requests_mock.mock() as m: - m.post(self.server.custom_views.expurl, status_code=201, text=Path(GET_XML).read_text()) - view = self.server.custom_views.publish(cv, str(CUSTOM_VIEW_DOWNLOAD)) - - assert view is not None - assert isinstance(view, TSC.CustomViewItem) - assert view.id is not None - assert view.name is not None - - def test_publish_file_io(self) -> None: - cv = TSC.CustomViewItem(name="test") - cv._owner = TSC.UserItem() - cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" - cv._workbook = TSC.WorkbookItem() - cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" - data = io.BytesIO(CUSTOM_VIEW_DOWNLOAD.read_bytes()) - with requests_mock.mock() as m: - m.post(self.server.custom_views.expurl, status_code=201, text=Path(GET_XML).read_text()) - view = self.server.custom_views.publish(cv, data) - - assert view is not None - assert isinstance(view, TSC.CustomViewItem) - assert view.id is not None - assert view.name is not None - - def test_publish_missing_owner_id(self) -> None: - cv = TSC.CustomViewItem(name="test") - cv._owner = TSC.UserItem() - cv._workbook = TSC.WorkbookItem() - cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" - with requests_mock.mock() as m: - m.post(self.server.custom_views.expurl, status_code=201, text=Path(GET_XML).read_text()) - with self.assertRaises(ValueError): - self.server.custom_views.publish(cv, CUSTOM_VIEW_DOWNLOAD) - - def test_publish_missing_wb_id(self) -> None: - cv = TSC.CustomViewItem(name="test") - cv._owner = TSC.UserItem() - cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" - cv._workbook = TSC.WorkbookItem() - with requests_mock.mock() as m: - m.post(self.server.custom_views.expurl, status_code=201, text=Path(GET_XML).read_text()) - with self.assertRaises(ValueError): - self.server.custom_views.publish(cv, CUSTOM_VIEW_DOWNLOAD) - - def test_large_publish(self): - cv = TSC.CustomViewItem(name="test") - cv._owner = TSC.UserItem() - cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" - cv._workbook = TSC.WorkbookItem() - cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" - with ExitStack() as stack: - temp_dir = stack.enter_context(TemporaryDirectory()) - file_path = Path(temp_dir) / "test_file" - file_path.write_bytes(os.urandom(65 * BYTES_PER_MB)) - mock = stack.enter_context(requests_mock.mock()) - # Mock initializing upload - mock.post(self.server.fileuploads.baseurl, status_code=201, text=FILE_UPLOAD_INIT.read_text()) - # Mock the upload - mock.put( - f"{self.server.fileuploads.baseurl}/7720:170fe6b1c1c7422dadff20f944d58a52-1:0", - text=FILE_UPLOAD_APPEND.read_text(), - ) - # Mock the publish - mock.post(self.server.custom_views.expurl, status_code=201, text=Path(GET_XML).read_text()) - - view = self.server.custom_views.publish(cv, file_path) - - assert view is not None - assert isinstance(view, TSC.CustomViewItem) - assert view.id is not None - assert view.name is not None - - def test_populate_pdf(self) -> None: - self.server.version = "3.23" - self.baseurl = self.server.custom_views.baseurl - with open(CUSTOM_VIEW_POPULATE_PDF, "rb") as f: - response = f.read() - with requests_mock.mock() as m: - m.get( - self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/pdf?type=letter&orientation=portrait&maxAge=5", - content=response, - ) - custom_view = TSC.CustomViewItem() - custom_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" - - size = TSC.PDFRequestOptions.PageType.Letter - orientation = TSC.PDFRequestOptions.Orientation.Portrait - req_option = TSC.PDFRequestOptions(size, orientation, 5) - - self.server.custom_views.populate_pdf(custom_view, req_option) - self.assertEqual(response, custom_view.pdf) - - def test_populate_csv(self) -> None: - self.server.version = "3.23" - self.baseurl = self.server.custom_views.baseurl - with open(CUSTOM_VIEW_POPULATE_CSV, "rb") as f: - response = f.read() - with requests_mock.mock() as m: - m.get(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/data?maxAge=1", content=response) - custom_view = TSC.CustomViewItem() - custom_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" - request_option = TSC.CSVRequestOptions(maxage=1) - self.server.custom_views.populate_csv(custom_view, request_option) - - csv_file = b"".join(custom_view.csv) - self.assertEqual(response, csv_file) - - def test_populate_csv_default_maxage(self) -> None: - self.server.version = "3.23" - self.baseurl = self.server.custom_views.baseurl - with open(CUSTOM_VIEW_POPULATE_CSV, "rb") as f: - response = f.read() - with requests_mock.mock() as m: - m.get(self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/data", content=response) - custom_view = TSC.CustomViewItem() - custom_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" - self.server.custom_views.populate_csv(custom_view) - - csv_file = b"".join(custom_view.csv) - self.assertEqual(response, csv_file) - - def test_pdf_height(self) -> None: - self.server.version = "3.23" - self.baseurl = self.server.custom_views.baseurl - with open(CUSTOM_VIEW_POPULATE_PDF, "rb") as f: - response = f.read() - with requests_mock.mock() as m: - m.get( - self.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/pdf?vizHeight=1080&vizWidth=1920", - content=response, - ) - custom_view = TSC.CustomViewItem() - custom_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" - - req_option = TSC.PDFRequestOptions( - viz_height=1080, - viz_width=1920, - ) - - self.server.custom_views.populate_pdf(custom_view, req_option) - self.assertEqual(response, custom_view.pdf) + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + server.custom_views.populate_image(single_view) + assert response == single_view.image + + +def test_populate_image_with_options(server) -> None: + response = POPULATE_PREVIEW_IMAGE.read_bytes() + with requests_mock.mock() as m: + m.get( + server.custom_views.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/image?resolution=high&maxAge=10", + content=response, + ) + single_view = TSC.CustomViewItem() + single_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + req_option = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High, maxage=10) + server.custom_views.populate_image(single_view, req_option) + assert response == single_view.image + + +def test_populate_image_missing_id(server) -> None: + single_view = TSC.CustomViewItem() + single_view._id = None + with pytest.raises(TSC.MissingRequiredFieldError): + server.custom_views.populate_image(single_view) + + +def test_delete(server) -> None: + with requests_mock.mock() as m: + m.delete(server.custom_views.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42", status_code=204) + server.custom_views.delete("3cc6cd06-89ce-4fdc-b935-5294135d6d42") + + +def test_delete_missing_id(server) -> None: + with pytest.raises(ValueError): + server.custom_views.delete("") + + +def test_update(server) -> None: + response_xml = CUSTOM_VIEW_UPDATE_XML.read_text() + with requests_mock.mock() as m: + m.put(server.custom_views.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2", text=response_xml) + the_custom_view = TSC.CustomViewItem("1d0304cd-3796-429f-b815-7258370b9b74", name="Best test ever") + the_custom_view._id = "1f951daf-4061-451a-9df1-69a8062664f2" + the_custom_view.owner = TSC.UserItem() + the_custom_view.owner.id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + the_custom_view = server.custom_views.update(the_custom_view) + + assert "1f951daf-4061-451a-9df1-69a8062664f2" == the_custom_view.id + if the_custom_view.owner: + assert "dd2239f6-ddf1-4107-981a-4cf94e415794" == the_custom_view.owner.id + assert "Best test ever" == the_custom_view.name + + +def test_update_missing_id(server) -> None: + cv = TSC.CustomViewItem(name="test") + with pytest.raises(TSC.MissingRequiredFieldError): + server.custom_views.update(cv) + + +def test_download(server) -> None: + cv = TSC.CustomViewItem(name="test") + cv._id = "1f951daf-4061-451a-9df1-69a8062664f2" + content = CUSTOM_VIEW_DOWNLOAD.read_bytes() + data = io.BytesIO() + with requests_mock.mock() as m: + m.get(f"{server.custom_views.expurl}/1f951daf-4061-451a-9df1-69a8062664f2/content", content=content) + server.custom_views.download(cv, data) + + assert data.getvalue() == content + + +def test_publish_filepath(server) -> None: + cv = TSC.CustomViewItem(name="test") + cv._owner = TSC.UserItem() + cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + cv._workbook = TSC.WorkbookItem() + cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" + with requests_mock.mock() as m: + m.post(server.custom_views.expurl, status_code=201, text=GET_XML.read_text()) + view = server.custom_views.publish(cv, CUSTOM_VIEW_DOWNLOAD) + + assert view is not None + assert isinstance(view, TSC.CustomViewItem) + assert view.id is not None + assert view.name is not None + + +def test_publish_file_str(server) -> None: + cv = TSC.CustomViewItem(name="test") + cv._owner = TSC.UserItem() + cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + cv._workbook = TSC.WorkbookItem() + cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" + with requests_mock.mock() as m: + m.post(server.custom_views.expurl, status_code=201, text=GET_XML.read_text()) + view = server.custom_views.publish(cv, str(CUSTOM_VIEW_DOWNLOAD)) + + assert view is not None + assert isinstance(view, TSC.CustomViewItem) + assert view.id is not None + assert view.name is not None + + +def test_publish_file_io(server) -> None: + cv = TSC.CustomViewItem(name="test") + cv._owner = TSC.UserItem() + cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + cv._workbook = TSC.WorkbookItem() + cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" + data = io.BytesIO(CUSTOM_VIEW_DOWNLOAD.read_bytes()) + with requests_mock.mock() as m: + m.post(server.custom_views.expurl, status_code=201, text=GET_XML.read_text()) + view = server.custom_views.publish(cv, data) + + assert view is not None + assert isinstance(view, TSC.CustomViewItem) + assert view.id is not None + assert view.name is not None + + +def test_publish_missing_owner_id(server) -> None: + cv = TSC.CustomViewItem(name="test") + cv._owner = TSC.UserItem() + cv._workbook = TSC.WorkbookItem() + cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" + with requests_mock.mock() as m: + m.post(server.custom_views.expurl, status_code=201, text=GET_XML.read_text()) + with pytest.raises(ValueError): + server.custom_views.publish(cv, CUSTOM_VIEW_DOWNLOAD) + + +def test_publish_missing_wb_id(server) -> None: + cv = TSC.CustomViewItem(name="test") + cv._owner = TSC.UserItem() + cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + cv._workbook = TSC.WorkbookItem() + with requests_mock.mock() as m: + m.post(server.custom_views.expurl, status_code=201, text=GET_XML.read_text()) + with pytest.raises(ValueError): + server.custom_views.publish(cv, CUSTOM_VIEW_DOWNLOAD) + + +def test_large_publish(server): + cv = TSC.CustomViewItem(name="test") + cv._owner = TSC.UserItem() + cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" + cv._workbook = TSC.WorkbookItem() + cv._workbook._id = "1f951daf-4061-451a-9df1-69a8062664f2" + with ExitStack() as stack: + temp_dir = stack.enter_context(TemporaryDirectory()) + file_path = Path(temp_dir) / "test_file" + file_path.write_bytes(os.urandom(65 * BYTES_PER_MB)) + mock = stack.enter_context(requests_mock.mock()) + # Mock initializing upload + mock.post(server.fileuploads.baseurl, status_code=201, text=FILE_UPLOAD_INIT.read_text()) + # Mock the upload + mock.put( + f"{server.fileuploads.baseurl}/7720:170fe6b1c1c7422dadff20f944d58a52-1:0", + text=FILE_UPLOAD_APPEND.read_text(), + ) + # Mock the publish + mock.post(server.custom_views.expurl, status_code=201, text=GET_XML.read_text()) + + view = server.custom_views.publish(cv, file_path) + + assert view is not None + assert isinstance(view, TSC.CustomViewItem) + assert view.id is not None + assert view.name is not None + + +def test_populate_pdf(server) -> None: + server.version = "3.23" + response = CUSTOM_VIEW_POPULATE_PDF.read_bytes() + with requests_mock.mock() as m: + m.get( + server.custom_views.baseurl + + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/pdf?type=letter&orientation=portrait&maxAge=5", + content=response, + ) + custom_view = TSC.CustomViewItem() + custom_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + + size = TSC.PDFRequestOptions.PageType.Letter + orientation = TSC.PDFRequestOptions.Orientation.Portrait + req_option = TSC.PDFRequestOptions(size, orientation, 5) + + server.custom_views.populate_pdf(custom_view, req_option) + assert response == custom_view.pdf + + +def test_populate_csv(server) -> None: + server.version = "3.23" + response = CUSTOM_VIEW_POPULATE_CSV.read_bytes() + with requests_mock.mock() as m: + m.get(server.custom_views.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/data?maxAge=1", content=response) + custom_view = TSC.CustomViewItem() + custom_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + request_option = TSC.CSVRequestOptions(maxage=1) + server.custom_views.populate_csv(custom_view, request_option) + + csv_file = b"".join(custom_view.csv) + assert response == csv_file + + +def test_populate_csv_default_maxage(server) -> None: + server.version = "3.23" + response = CUSTOM_VIEW_POPULATE_CSV.read_bytes() + with requests_mock.mock() as m: + m.get(server.custom_views.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/data", content=response) + custom_view = TSC.CustomViewItem() + custom_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + server.custom_views.populate_csv(custom_view) + + csv_file = b"".join(custom_view.csv) + assert response == csv_file + + +def test_pdf_height(server) -> None: + server.version = "3.23" + response = CUSTOM_VIEW_POPULATE_PDF.read_bytes() + with requests_mock.mock() as m: + m.get( + server.custom_views.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/pdf?vizHeight=1080&vizWidth=1920", + content=response, + ) + custom_view = TSC.CustomViewItem() + custom_view._id = "d79634e1-6063-4ec9-95ff-50acbf609ff5" + + req_option = TSC.PDFRequestOptions( + viz_height=1080, + viz_width=1920, + ) + + server.custom_views.populate_pdf(custom_view, req_option) + assert response == custom_view.pdf From d419a4d4ebd08c725187dc6a960d458363af9007 Mon Sep 17 00:00:00 2001 From: Jordan Woods <13803242+jorwoods@users.noreply.github.com> Date: Sat, 30 Aug 2025 09:03:19 -0500 Subject: [PATCH 2/3] chore: remove unused import --- test/test_custom_view.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_custom_view.py b/test/test_custom_view.py index 525abd0b1..3624f91fb 100644 --- a/test/test_custom_view.py +++ b/test/test_custom_view.py @@ -10,7 +10,6 @@ import tableauserverclient as TSC from tableauserverclient.config import BYTES_PER_MB from tableauserverclient.datetime_helpers import format_datetime -from tableauserverclient.server.endpoint.exceptions import MissingRequiredFieldError TEST_ASSET_DIR = Path(__file__).parent / "assets" From 28182b7cbdbdedf4894253a7d003b46e8746584d Mon Sep 17 00:00:00 2001 From: Jordan Woods <13803242+jorwoods@users.noreply.github.com> Date: Mon, 1 Sep 2025 06:28:01 -0500 Subject: [PATCH 3/3] chore: add server type hints --- test/test_custom_view.py | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/test/test_custom_view.py b/test/test_custom_view.py index 3624f91fb..0df3b849f 100644 --- a/test/test_custom_view.py +++ b/test/test_custom_view.py @@ -36,7 +36,7 @@ def server() -> TSC.Server: return server -def test_get(server) -> None: +def test_get(server: TSC.Server) -> None: response_xml = GET_XML.read_text() print(response_xml) with requests_mock.mock() as m: @@ -62,7 +62,7 @@ def test_get(server) -> None: assert all_views[1].shared -def test_get_by_id(server) -> None: +def test_get_by_id(server: TSC.Server) -> None: response_xml = GET_XML_ID.read_text() with requests_mock.mock() as m: m.get(server.custom_views.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5", text=response_xml) @@ -81,18 +81,18 @@ def test_get_by_id(server) -> None: assert "2002-06-05T08:00:59Z" == format_datetime(view.updated_at) -def test_get_by_id_missing_id(server) -> None: +def test_get_by_id_missing_id(server: TSC.Server) -> None: with pytest.raises(TSC.MissingRequiredFieldError): server.custom_views.get_by_id(None) -def test_get_before_signin(server) -> None: +def test_get_before_signin(server: TSC.Server) -> None: server._auth_token = None with pytest.raises(TSC.NotSignedInError): server.custom_views.get() -def test_populate_image(server) -> None: +def test_populate_image(server: TSC.Server) -> None: response = POPULATE_PREVIEW_IMAGE.read_bytes() with requests_mock.mock() as m: m.get(server.custom_views.baseurl + "/d79634e1-6063-4ec9-95ff-50acbf609ff5/image", content=response) @@ -102,7 +102,7 @@ def test_populate_image(server) -> None: assert response == single_view.image -def test_populate_image_with_options(server) -> None: +def test_populate_image_with_options(server: TSC.Server) -> None: response = POPULATE_PREVIEW_IMAGE.read_bytes() with requests_mock.mock() as m: m.get( @@ -116,25 +116,25 @@ def test_populate_image_with_options(server) -> None: assert response == single_view.image -def test_populate_image_missing_id(server) -> None: +def test_populate_image_missing_id(server: TSC.Server) -> None: single_view = TSC.CustomViewItem() single_view._id = None with pytest.raises(TSC.MissingRequiredFieldError): server.custom_views.populate_image(single_view) -def test_delete(server) -> None: +def test_delete(server: TSC.Server) -> None: with requests_mock.mock() as m: m.delete(server.custom_views.baseurl + "/3cc6cd06-89ce-4fdc-b935-5294135d6d42", status_code=204) server.custom_views.delete("3cc6cd06-89ce-4fdc-b935-5294135d6d42") -def test_delete_missing_id(server) -> None: +def test_delete_missing_id(server: TSC.Server) -> None: with pytest.raises(ValueError): server.custom_views.delete("") -def test_update(server) -> None: +def test_update(server: TSC.Server) -> None: response_xml = CUSTOM_VIEW_UPDATE_XML.read_text() with requests_mock.mock() as m: m.put(server.custom_views.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2", text=response_xml) @@ -150,13 +150,13 @@ def test_update(server) -> None: assert "Best test ever" == the_custom_view.name -def test_update_missing_id(server) -> None: +def test_update_missing_id(server: TSC.Server) -> None: cv = TSC.CustomViewItem(name="test") with pytest.raises(TSC.MissingRequiredFieldError): server.custom_views.update(cv) -def test_download(server) -> None: +def test_download(server: TSC.Server) -> None: cv = TSC.CustomViewItem(name="test") cv._id = "1f951daf-4061-451a-9df1-69a8062664f2" content = CUSTOM_VIEW_DOWNLOAD.read_bytes() @@ -168,7 +168,7 @@ def test_download(server) -> None: assert data.getvalue() == content -def test_publish_filepath(server) -> None: +def test_publish_filepath(server: TSC.Server) -> None: cv = TSC.CustomViewItem(name="test") cv._owner = TSC.UserItem() cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" @@ -184,7 +184,7 @@ def test_publish_filepath(server) -> None: assert view.name is not None -def test_publish_file_str(server) -> None: +def test_publish_file_str(server: TSC.Server) -> None: cv = TSC.CustomViewItem(name="test") cv._owner = TSC.UserItem() cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" @@ -200,7 +200,7 @@ def test_publish_file_str(server) -> None: assert view.name is not None -def test_publish_file_io(server) -> None: +def test_publish_file_io(server: TSC.Server) -> None: cv = TSC.CustomViewItem(name="test") cv._owner = TSC.UserItem() cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" @@ -217,7 +217,7 @@ def test_publish_file_io(server) -> None: assert view.name is not None -def test_publish_missing_owner_id(server) -> None: +def test_publish_missing_owner_id(server: TSC.Server) -> None: cv = TSC.CustomViewItem(name="test") cv._owner = TSC.UserItem() cv._workbook = TSC.WorkbookItem() @@ -228,7 +228,7 @@ def test_publish_missing_owner_id(server) -> None: server.custom_views.publish(cv, CUSTOM_VIEW_DOWNLOAD) -def test_publish_missing_wb_id(server) -> None: +def test_publish_missing_wb_id(server: TSC.Server) -> None: cv = TSC.CustomViewItem(name="test") cv._owner = TSC.UserItem() cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" @@ -239,7 +239,7 @@ def test_publish_missing_wb_id(server) -> None: server.custom_views.publish(cv, CUSTOM_VIEW_DOWNLOAD) -def test_large_publish(server): +def test_large_publish(server: TSC.Server): cv = TSC.CustomViewItem(name="test") cv._owner = TSC.UserItem() cv._owner._id = "dd2239f6-ddf1-4107-981a-4cf94e415794" @@ -268,7 +268,7 @@ def test_large_publish(server): assert view.name is not None -def test_populate_pdf(server) -> None: +def test_populate_pdf(server: TSC.Server) -> None: server.version = "3.23" response = CUSTOM_VIEW_POPULATE_PDF.read_bytes() with requests_mock.mock() as m: @@ -288,7 +288,7 @@ def test_populate_pdf(server) -> None: assert response == custom_view.pdf -def test_populate_csv(server) -> None: +def test_populate_csv(server: TSC.Server) -> None: server.version = "3.23" response = CUSTOM_VIEW_POPULATE_CSV.read_bytes() with requests_mock.mock() as m: @@ -302,7 +302,7 @@ def test_populate_csv(server) -> None: assert response == csv_file -def test_populate_csv_default_maxage(server) -> None: +def test_populate_csv_default_maxage(server: TSC.Server) -> None: server.version = "3.23" response = CUSTOM_VIEW_POPULATE_CSV.read_bytes() with requests_mock.mock() as m: @@ -315,7 +315,7 @@ def test_populate_csv_default_maxage(server) -> None: assert response == csv_file -def test_pdf_height(server) -> None: +def test_pdf_height(server: TSC.Server) -> None: server.version = "3.23" response = CUSTOM_VIEW_POPULATE_PDF.read_bytes() with requests_mock.mock() as m: