diff --git a/tabcmd/commands/auth/session.py b/tabcmd/commands/auth/session.py index 866efbc8..a380ab73 100644 --- a/tabcmd/commands/auth/session.py +++ b/tabcmd/commands/auth/session.py @@ -45,7 +45,7 @@ def __init__(self): self.logging_level = "info" self._read_from_json() - self.logger = log(__name__, self.logging_level) # instantiate here mostly for tests + self.logger = log(__class__.__name__, self.logging_level) # instantiate here mostly for tests self.tableau_server = None # this one is an object that doesn't get persisted in the file # called before we connect to the server @@ -214,7 +214,7 @@ def create_session(self, args): self._read_existing_state() self._update_session_data(args) self.logging_level = args.logging_level or self.logging_level - self.logger = log(__name__, self.logging_level) + self.logger = log(__class__.__name__, self.logging_level) credentials = None if args.password: diff --git a/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py b/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py index af54d65a..86536550 100644 --- a/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py +++ b/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py @@ -25,7 +25,7 @@ def get_view_by_content_url(logger, server, view_content_url) -> TSC.ViewItem: req_option.filter.add(TSC.Filter("contentUrl", TSC.RequestOptions.Operator.Equals, view_content_url)) matching_views, paging = server.views.get(req_option) except TSC.ServerResponseError as e: - Errors.exit_with_error(logger, _("publish.errors.unexpected_server_response").format("")) + Errors.exit_with_error(logger, _("publish.errors.unexpected_server_response").format(e)) if len(matching_views) < 1: Errors.exit_with_error(logger, message=_("errors.xmlapi.not_found")) return matching_views[0] @@ -42,3 +42,76 @@ def get_wb_by_content_url(logger, server, workbook_content_url) -> TSC.WorkbookI if len(matching_workbooks) < 1: Errors.exit_with_error(logger, message=_("dataalerts.failure.error.workbookNotFound")) return matching_workbooks[0] + + @staticmethod + def apply_values_from_url_params(request_options: TSC.PDFRequestOptions, url, logger) -> None: + # should be able to replace this with request_options._append_view_filters(params) + logger.debug(url) + try: + if "?" in url: + query = url.split("?")[1] + logger.trace("Query parameters: {}".format(query)) + else: + logger.debug("No query parameters present in url") + return + + params = query.split("&") + logger.trace(params) + for value in params: + if value.startswith(":"): + DatasourcesAndWorkbooks.apply_option_value(request_options, value, logger) + else: # it must be a filter + DatasourcesAndWorkbooks.apply_filter_value(request_options, value, logger) + + except BaseException as e: + logger.warn("Error building filter params", e) + # ExportCommand.log_stack(logger) # type: ignore + + @staticmethod + def apply_filter_value(request_options: TSC.PDFRequestOptions, value: str, logger) -> None: + # todo: do we need to strip Parameters.x -> x? + logger.trace("handling filter param {}".format(value)) + data_filter = value.split("=") + request_options.vf(data_filter[0], data_filter[1]) + + @staticmethod + def apply_option_value(request_options: TSC.PDFRequestOptions, value: str, logger) -> None: + logger.trace("handling url option {}".format(value)) + setting = value.split("=") + if ":iid" == setting[0]: + logger.debug(":iid value ignored in url") + elif ":refresh" == setting[0] and DatasourcesAndWorkbooks.is_truthy(setting[1]): + # mypy is worried that this is readonly + request_options.max_age = 0 # type:ignore + logger.debug("Set max age to {} from {}".format(request_options.max_age, value)) + elif ":size" == setting[0]: + height, width = setting[1].split(",") + logger.warn("Height/weight parameters not yet implemented ({})".format(value)) + else: + logger.debug("Parameter[s] not recognized: {}".format(value)) + + @staticmethod + def is_truthy(value: str): + return value.lower() in ["yes", "y", "1", "true"] + + @staticmethod + def apply_png_options(request_options: TSC.ImageRequestOptions, args, logger): + if args.height or args.width: + # only applicable for png + logger.warn("Height/width arguments not yet implemented in export") + if args.image_resolution: + request_options.image_resolution = args.image_resolution + + @staticmethod + def save_to_data_file(logger, output, filename): + logger.info(_("httputils.found_attachment").format(filename)) + with open(filename, "wb") as f: + f.writelines(output) + logger.info(_("export.success").format("", filename)) + + @staticmethod + def save_to_file(logger, output, filename): + logger.info(_("httputils.found_attachment").format(filename)) + with open(filename, "wb") as f: + f.write(output) + logger.info(_("export.success").format("", filename)) diff --git a/tabcmd/commands/datasources_and_workbooks/export_command.py b/tabcmd/commands/datasources_and_workbooks/export_command.py index f05a88ce..2e714543 100644 --- a/tabcmd/commands/datasources_and_workbooks/export_command.py +++ b/tabcmd/commands/datasources_and_workbooks/export_command.py @@ -28,12 +28,17 @@ def define_args(export_parser): help="page orientation (landscape or portrait) of the exported PDF", ) export_parser.add_argument("--pagesize", default="letter", help="Set the page size of the exported PDF") - export_parser.add_argument("--width", default=800, help="Set the width in pixels. Default is 800 px") + export_parser.add_argument( + "--image-resolution", default="High", help="Set the image resolution of the exported image" + ) + + export_parser.add_argument( + "--width", default=800, help="Set the width of the image in pixels. Default is 800 px" + ) export_parser.add_argument("--filename", "-f", help="filename to store the exported data") export_parser.add_argument("--height", default=600, help=_("export.options.height")) export_parser.add_argument( "--filter", - "-vf", metavar="COLUMN:VALUE", help="View filter to apply to the view", ) @@ -52,29 +57,29 @@ def run_command(args): view_content_url, wb_content_url = ExportCommand.parse_export_url_to_workbook_and_view(logger, args.url) logger.debug([view_content_url, wb_content_url]) if not view_content_url and not wb_content_url: - Errors.exit_with_error(logger, _("export.errors.requires_workbook_view_param").format(ExportCommand)) - - logger.debug(args.pagelayout, args.pagesize, args.filename, args.width, args.height, args.filter) + view_example = "/workbook_name/view_name" + message = "{} [{}]".format( + _("export.errors.requires_workbook_view_param").format(__class__.__name__), view_example + ) + Errors.exit_with_error(logger, message) try: if args.fullpdf: # it's a workbook workbook_item = ExportCommand.get_wb_by_content_url(logger, server, wb_content_url) - output = ExportCommand.download_wb_pdf(server, workbook_item, args.url, logger) - + output = ExportCommand.download_wb_pdf(server, workbook_item, args, logger) default_filename = "{}.pdf".format(workbook_item.name) elif args.pdf or args.png or args.csv: # it's a view view_item = ExportCommand.get_view_by_content_url(logger, server, view_content_url) if args.pdf: - output = ExportCommand.download_view_pdf(server, view_item, args.url, logger) + output = ExportCommand.download_view_pdf(server, view_item, args, logger) default_filename = "{}.pdf".format(view_item.name) elif args.csv: - output = ExportCommand.download_csv(server, view_item, args.url, logger) + output = ExportCommand.download_csv(server, view_item, args, logger) default_filename = "{}.csv".format(view_item.name) elif args.png: - output = ExportCommand.download_png(server, view_item, args.url, logger) - + output = ExportCommand.download_png(server, view_item, args, logger) default_filename = "{}.png".format(view_item.name) except Exception as e: @@ -87,63 +92,62 @@ def run_command(args): else: ExportCommand.save_to_file(logger, output, save_name) - except Exception as e: Errors.exit_with_error(logger, "Error saving to file", e) @staticmethod - def extract_filter_values_from_url_params(request_options: TSC.PDFRequestOptions, url, logger=None) -> None: - try: - # todo make logging better - logger = logger or log(ExportCommand.__class__.__name__, "DEBUG") - logger.debug(url) - - if "?" in url: - query = url.split("?")[1] - else: - return - - params = query.split("&") - logger.trace(params) + def apply_values_from_args(request_options: TSC.PDFRequestOptions, args, logger=None) -> None: + logger.debug( + "Args: {}, {}, {}, {}, {}".format(args.pagelayout, args.pagesize, args.width, args.height, args.filter) + ) + if args.pagelayout: + request_options.orientation = args.pagelayout + if args.pagesize: + request_options.page_type = args.pagesize + if args.filter: + params = args.filter.split("&") for value in params: - data_filter = value.split("=") - request_options.vf(data_filter[0], data_filter[1]) - except BaseException as e: - logger.error("Error building filter params", e) - ExportCommand.log_stack(logger) # type: ignore + ExportCommand.apply_filter_value(request_options, value, logger) @staticmethod - def download_wb_pdf(server, workbook_item, url, logger): - logger.trace(url) - pdf = TSC.PDFRequestOptions(maxage=1) - ExportCommand.extract_filter_values_from_url_params(pdf, url) - - server.workbooks.populate_pdf(workbook_item, pdf) + def download_wb_pdf(server, workbook_item, args, logger): + logger.trace(args.url) + pdf_options = TSC.PDFRequestOptions(maxage=1) + ExportCommand.apply_values_from_url_params(pdf_options, args.url, logger) + ExportCommand.apply_values_from_args(pdf_options, args, logger) + logger.trace(pdf_options) + server.workbooks.populate_pdf(workbook_item, pdf_options) return workbook_item.pdf @staticmethod - def download_view_pdf(server, view_item, url, logger): - logger.trace(url) - pdf = TSC.PDFRequestOptions(maxage=1) - ExportCommand.extract_filter_values_from_url_params(pdf, url) - logger.trace(pdf.view_filters) - server.views.populate_pdf(view_item, pdf) + def download_view_pdf(server, view_item, args, logger): + logger.trace(args.url) + pdf_options = TSC.PDFRequestOptions(maxage=1) + ExportCommand.apply_values_from_url_params(pdf_options, args.url, logger) + ExportCommand.apply_values_from_args(pdf_options, args, logger) + logger.trace(pdf_options) + server.views.populate_pdf(view_item, pdf_options) return view_item.pdf @staticmethod - def download_csv(server, view_item, url, logger): - logger.trace(url) - csv = TSC.CSVRequestOptions(maxage=1) - ExportCommand.extract_filter_values_from_url_params(csv, url) - server.views.populate_csv(view_item, csv) + def download_csv(server, view_item, args, logger): + logger.trace(args.url) + csv_options = TSC.CSVRequestOptions(maxage=1) + ExportCommand.apply_values_from_url_params(csv_options, args.url, logger) + ExportCommand.apply_values_from_args(csv_options, args, logger) + logger.trace(csv_options) + server.views.populate_csv(view_item, csv_options) return view_item.csv @staticmethod - def download_png(server, view_item, url, logger): - logger.trace(url) - req_option_image = TSC.ImageRequestOptions(maxage=1) - ExportCommand.extract_filter_values_from_url_params(req_option_image, url) - server.views.populate_image(view_item, req_option_image) + def download_png(server, view_item, args, logger): + logger.trace(args.url) + image_options = TSC.ImageRequestOptions(maxage=1) + ExportCommand.apply_values_from_url_params(image_options, args.url, logger) + ExportCommand.apply_values_from_args(image_options, args, logger) + DatasourcesAndWorkbooks.apply_png_options(image_options, args, logger) + logger.trace(image_options) + server.views.populate_image(view_item, image_options) return view_item.png @staticmethod @@ -163,17 +167,3 @@ def parse_export_url_to_workbook_and_view(logger, url): workbook = name_parts[0] view = "{}/sheets/{}".format(workbook, name_parts[1]) return view, workbook - - @staticmethod - def save_to_data_file(logger, output, filename): - logger.info(_("httputils.found_attachment").format(filename)) - with open(filename, "wb") as f: - f.writelines(output) - logger.info(_("export.success").format("", filename)) - - @staticmethod - def save_to_file(logger, output, filename): - logger.info(_("httputils.found_attachment").format(filename)) - with open(filename, "wb") as f: - f.write(output) - logger.info(_("export.success").format("", filename)) diff --git a/tabcmd/commands/datasources_and_workbooks/get_url_command.py b/tabcmd/commands/datasources_and_workbooks/get_url_command.py index 4e1ba4b8..96d9cee1 100644 --- a/tabcmd/commands/datasources_and_workbooks/get_url_command.py +++ b/tabcmd/commands/datasources_and_workbooks/get_url_command.py @@ -37,48 +37,49 @@ def run_command(args): if " " in args.url: Errors.exit_with_error(logger, _("export.errors.white_space_workbook_view")) - if not args.url.startswith("/"): - args.url = "/" + args.url - logger.trace("helpfully fix format of url: " + args.url) + url = args.url.lstrip("/") # strip opening / if present - file_type = GetUrl.get_file_type_from_filename(logger, args.filename, args.url) - content_type = GetUrl.evaluate_content_type(logger, args.url) + file_type = GetUrl.get_file_type_from_filename(logger, args.filename, url) + content_type = GetUrl.evaluate_content_type(logger, url) if content_type == "workbook": - if file_type == "twbx" or file_type == "twb": - GetUrl.generate_twb(logger, server, args, file_type) + if file_type in ["twbx", "twb"]: + GetUrl.generate_twb(logger, server, args, file_type, url) else: Errors.exit_with_error( logger, message=_("publish.errors.mutually_exclusive_option").format("twb", "twbx") ) else: # content type = view + view_url = GetUrl.get_view_url(url, logger) if file_type == "pdf": - GetUrl.generate_pdf(logger, server, args) + GetUrl.generate_pdf(logger, server, args, view_url) elif file_type == "png": - GetUrl.generate_png(logger, server, args) + GetUrl.generate_png(logger, server, args, view_url) elif file_type == "csv": - GetUrl.generate_csv(logger, server, args) + GetUrl.generate_csv(logger, server, args, view_url) else: Errors.exit_with_error(logger, message=_("tabcmd.get.extension.not_found")) @staticmethod def evaluate_content_type(logger, url): - # specify a view to get using "/views//." - # specify a workbook to get using "/workbooks/.". - if url.find("/views/") == 0: + # specify a view to get using "views//." + # specify a workbook to get using "workbooks/.". + if url.startswith("views/"): return "view" - elif url.find("/workbooks/") == 0: + elif url.startswith("workbooks/"): return "workbook" else: - view_example = "/views//." - message = "{} [{}]".format( - _("export.errors.requires_workbook_view_param").format(__class__.__name__), view_example - ) - Errors.exit_with_error(logger, message) + GetUrl.explain_expected_url(logger) + @staticmethod + def explain_expected_url(logger): + view_example = "/views//." + message = "{} [{}]".format( + _("export.errors.requires_workbook_view_param").format(__class__.__name__), view_example + ) + Errors.exit_with_error(logger, message) @staticmethod def get_file_type_from_filename(logger, file_name, url): - type_of_file = None file_name = file_name or url logger.debug(_("get.options.file") + ": {}".format(file_name)) type_of_file = GetUrl.get_file_extension(file_name) @@ -114,24 +115,24 @@ def get_name_without_possible_extension(filename): return filename @staticmethod - def get_workbook_name(logger, url): # /workbooks/wb-name" -> "wb-name" + def get_workbook_name(url, logger): # workbooks/wb-name" -> "wb-name" name_parts = url.split("/") - if len(name_parts) != 3: - raise ValueError(_("export.errors.requires_workbook_view_param").format(GetUrl.name)) + if len(name_parts) != 2: + GetUrl.explain_expected_url(logger) workbook_name = name_parts[::-1][0] # last part workbook_name = GetUrl.strip_query_params(workbook_name) workbook_name = GetUrl.get_name_without_possible_extension(workbook_name) return workbook_name @staticmethod - def get_view_url(url): # "/views/wb-name/view-name" -> wb-name/sheets/view-name - name_parts = url.split("/") # ['', 'views', 'wb-name', 'view-name'] - if len(name_parts) != 4: - raise ValueError(_("export.errors.requires_workbook_view_param").format(GetUrl.name)) + def get_view_url(url, logger): # "views/wb-name/view-name" -> wb-name/sheets/view-name + name_parts = url.split("/") # ['views', 'wb-name', 'view-name'] + if len(name_parts) != 3: + GetUrl.explain_expected_url(logger) + workbook_name = name_parts[1] view_name = name_parts[::-1][0] view_name = GetUrl.strip_query_params(view_name) view_name = GetUrl.get_name_without_possible_extension(view_name) - workbook_name = name_parts[2] return DatasourcesAndWorkbooks.get_view_url_from_names(workbook_name, view_name) @staticmethod @@ -141,55 +142,49 @@ def filename_from_args(file_argument, item_name, filetype): return file_argument @staticmethod - def generate_pdf(logger, server, args): - view_url = GetUrl.get_view_url(args.url) + def generate_pdf(logger, server, args, view_url): try: view_item: TSC.ViewItem = GetUrl.get_view_by_content_url(logger, server, view_url) logger.debug(_("content_type.view") + ": {}".format(view_item.name)) req_option_pdf = TSC.PDFRequestOptions(maxage=1) + DatasourcesAndWorkbooks.apply_values_from_url_params(req_option_pdf, args.url, logger) server.views.populate_pdf(view_item, req_option_pdf) filename = GetUrl.filename_from_args(args.filename, view_item.name, "pdf") - with open(filename, "wb") as f: - f.write(view_item.pdf) - logger.info(_("export.success").format(view_item.name, filename)) + DatasourcesAndWorkbooks.save_to_file(logger, view_item.pdf, filename) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, _("publish.errors.unexpected_server_response"), e) @staticmethod - def generate_png(logger, server, args): - view = GetUrl.get_view_url(args.url) + def generate_png(logger, server, args, view_url): try: - view_item: TSC.ViewItem = GetUrl.get_view_by_content_url(logger, server, view) + view_item: TSC.ViewItem = GetUrl.get_view_by_content_url(logger, server, view_url) logger.debug(_("content_type.view") + ": {}".format(view_item.name)) - req_option_csv = TSC.CSVRequestOptions(maxage=1) # same as png + req_option_csv = TSC.ImageRequestOptions(maxage=1) + DatasourcesAndWorkbooks.apply_values_from_url_params(req_option_csv, args.url, logger) server.views.populate_image(view_item, req_option_csv) filename = GetUrl.filename_from_args(args.filename, view_item.name, "png") - with open(filename, "wb") as f: - f.write(view_item.image) - logger.info(_("export.success").format(view_item.name, filename)) + DatasourcesAndWorkbooks.save_to_file(logger, view_item.image, filename) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, _("publish.errors.unexpected_server_response"), e) @staticmethod - def generate_csv(logger, server, args): - view_url = GetUrl.get_view_url(args.url) + def generate_csv(logger, server, args, view_url): try: view_item: TSC.ViewItem = GetUrl.get_view_by_content_url(logger, server, view_url) logger.debug(_("content_type.view") + ": {}".format(view_item.name)) req_option_csv = TSC.CSVRequestOptions(maxage=1) + DatasourcesAndWorkbooks.apply_values_from_url_params(req_option_csv, args.url, logger) server.views.populate_csv(view_item, req_option_csv) file_name_with_path = GetUrl.filename_from_args(args.filename, view_item.name, "csv") - with open(file_name_with_path, "wb") as f: - f.writelines(view_item.csv) - logger.info(_("export.success").format(view_item.name, file_name_with_path)) + DatasourcesAndWorkbooks.save_to_data_file(logger, view_item.csv, file_name_with_path) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, _("publish.errors.unexpected_server_response"), e) except Exception as e: Errors.exit_with_error(logger, exception=e) @staticmethod - def generate_twb(logger, server, args, file_extension): - workbook_name = GetUrl.get_workbook_name(logger, args.url) + def generate_twb(logger, server, args, file_extension, url): + workbook_name = GetUrl.get_workbook_name(url, logger) try: target_workbook = GetUrl.get_wb_by_content_url(logger, server, workbook_name) diff --git a/tabcmd/commands/user/user_data.py b/tabcmd/commands/user/user_data.py index 8e4caaeb..f8c088f7 100644 --- a/tabcmd/commands/user/user_data.py +++ b/tabcmd/commands/user/user_data.py @@ -273,4 +273,3 @@ def act_on_users( if number_of_errors > max_printing: logger.info(_("importcsvsummary.error.too_many_errors")) logger.info(_("importcsvsummary.remainingerrors")) - diff --git a/tabcmd/execution/logger_config.py b/tabcmd/execution/logger_config.py index c57de868..96f7f067 100644 --- a/tabcmd/execution/logger_config.py +++ b/tabcmd/execution/logger_config.py @@ -5,9 +5,9 @@ FORMATS = { logging.ERROR: "%(asctime)s %(levelname)-5s:(%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", - logging.WARN: "%(asctime)s %(levelname)s : (%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", + logging.WARN: "%(asctime)s %(levelname)-5s: (%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", logging.INFO: "%(message)-30s", - logging.DEBUG: "%(asctime)s %(levelname)s : (%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", + logging.DEBUG: "%(asctime)s %(levelname)-5s: (%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", } # https://stackoverflow.com/questions/2183233/how-to-add-a-custom-loglevel-to-pythons-logging-facility @@ -41,7 +41,6 @@ def add_trace_level(): FORMATS[trace_level] = FORMATS[logging.ERROR] - def configure_log(name: str, logging_level_input: str): """function for logging statements to console and logfile""" logging_level = getattr(logging, logging_level_input.upper()) diff --git a/tests/commands/test_geturl_utils.py b/tests/commands/test_geturl_utils.py index 0bdb4555..77d21309 100644 --- a/tests/commands/test_geturl_utils.py +++ b/tests/commands/test_geturl_utils.py @@ -8,6 +8,15 @@ from tabcmd.commands.datasources_and_workbooks.export_command import * from tabcmd.commands.server import Server +mock_args = argparse.Namespace() +mock_args.pagelayout = None +mock_args.pagesize = None +mock_args.image_resolution = None +mock_args.width = None +mock_args.height = None +mock_args.filename = None +mock_args.filter = None + mock_logger = mock.MagicMock() fake_item = mock.MagicMock(TSC.ViewItem) @@ -51,10 +60,13 @@ def test_get_view_without_extension_that_doesnt_have_one(self): assert GetUrl.get_name_without_possible_extension(filename) == filename def test_get_workbook_name(self): - assert GetUrl.get_workbook_name(mock_logger, "/workbooks/wbname") == "wbname" + assert GetUrl.get_workbook_name("workbooks/wbname", mock_logger) == "wbname" def test_view_name(self): - assert GetUrl.get_view_url("/views/wb-name/view-name") == "wb-name/sheets/view-name" + assert GetUrl.get_view_url("views/wb-name/view-name", None) == "wb-name/sheets/view-name" + + def test_view_name_with_url_params(self): + assert GetUrl.get_view_url("views/wb-name/view-name?:refresh=y", None) == "wb-name/sheets/view-name" """ GetUrl.get_view_without_extension(view_name) @@ -93,22 +105,14 @@ def test_parse_export_url_to_workbook_and_view_bad_url(self): assert view is None assert wb is None - def test_extract_query_params(self): - url = "wb-name/view-name?param1=value1" - options = TSC.PDFRequestOptions() - assert options.view_filters is not None - assert len(options.view_filters) is 0 - ExportCommand.extract_filter_values_from_url_params(options, url) - assert len(options.view_filters) == 1 - assert options.view_filters[0] == ("param1", "value1") - @mock.patch("tableauserverclient.Server") def test_download_csv(self, mock_server): mock_server.views = mock.MagicMock() mock_server.views.csv = mock.MagicMock() mock_view = tableauserverclient.ViewItem() url = "wb-name/view-name?param1=value1" - ExportCommand.download_csv(mock_server, mock_view, url, mock_logger) + mock_args.url = url + ExportCommand.download_csv(mock_server, mock_view, mock_args, mock_logger) @mock.patch("tableauserverclient.Server") def test_download_image(self, mock_server): @@ -116,7 +120,8 @@ def test_download_image(self, mock_server): mock_server.views.png = mock.MagicMock() mock_view = tableauserverclient.ViewItem() url = "wb-name/view-name?param1=value1" - ExportCommand.download_png(mock_server, mock_view, url, mock_logger) + mock_args.url = url + ExportCommand.download_png(mock_server, mock_view, mock_args, mock_logger) @mock.patch("tableauserverclient.Server") def test_download_view_pdf(self, mock_server): @@ -124,7 +129,8 @@ def test_download_view_pdf(self, mock_server): mock_server.views.pdf = mock.MagicMock() mock_view = tableauserverclient.ViewItem() url = "wb-name/view-name?param1=value1" - ExportCommand.download_view_pdf(mock_server, mock_view, url, mock_logger) + mock_args.url = url + ExportCommand.download_view_pdf(mock_server, mock_view, mock_args, mock_logger) @mock.patch("tableauserverclient.Server") def test_download_wb_pdf(self, mock_server): @@ -132,7 +138,50 @@ def test_download_wb_pdf(self, mock_server): mock_server.workbooks.pdf = mock.MagicMock() mock_view = tableauserverclient.ViewItem() url = "wb-name/view-name?param1=value1" - ExportCommand.download_wb_pdf(mock_server, mock_view, url, mock_logger) + mock_args.url = url + ExportCommand.download_wb_pdf(mock_server, mock_view, mock_args, mock_logger) + + +@mock.patch("tableauserverclient.ViewItem", fake_item) +class DS_WB_Tests(unittest.TestCase): + def test_apply_filter(self): + url = "wb-name/view-name?param1=value1" + options = TSC.PDFRequestOptions() + assert options.view_filters is not None + assert len(options.view_filters) is 0 + ExportCommand.apply_filter_value(options, "param1=value1", mock_logger) + assert len(options.view_filters) == 1 + assert options.view_filters[0] == ("param1", "value1") + + def test_extract_query_params(self): + url = "wb-name/view-name?param1=value1" + options = TSC.PDFRequestOptions() + assert options.view_filters is not None + assert len(options.view_filters) is 0 + ExportCommand.apply_values_from_url_params(options, url, mock_logger) + assert len(options.view_filters) == 1 + assert options.view_filters[0] == ("param1", "value1") + + def test_refresh_true(self): + url = "wb-name/view-name?:refresh=TRUE" + options = TSC.PDFRequestOptions() + assert options.max_age == -1 + ExportCommand.apply_values_from_url_params(options, url, mock_logger) + assert options.max_age == 0 + + def test_refresh_yes(self): + url = "wb-name/view-name?:refresh=yes" + options = TSC.PDFRequestOptions() + assert options.max_age == -1 + ExportCommand.apply_values_from_url_params(options, url, mock_logger) + assert options.max_age == 0 + + def test_refresh_y(self): + url = "wb-name/view-name?:refresh=y" + options = TSC.PDFRequestOptions() + assert options.max_age == -1 + ExportCommand.apply_values_from_url_params(options, url, mock_logger) + assert options.max_age == 0 def test_save_to_binary_file(self): mock_content = bytes() diff --git a/tests/e2e/online_tests.py b/tests/e2e/online_tests.py index bce557ef..f7da3677 100644 --- a/tests/e2e/online_tests.py +++ b/tests/e2e/online_tests.py @@ -51,7 +51,7 @@ def setup_class(cls): def _create_project(self, project_name, parent_path=None): command = "createproject" arguments = [command, "--name", project_name] - if parent_path or parent_location: + if parent_path: arguments.append("--parent-project-path") arguments.append(parent_path) _test_command(arguments) @@ -59,9 +59,9 @@ def _create_project(self, project_name, parent_path=None): def _delete_project(self, project_name, parent_path=None): command = "deleteproject" arguments = [command, project_name] - if parent_path or parent_location: + if parent_path: arguments.append("--parent-project-path") - arguments.append(parent_path or parent_location) + arguments.append(parent_path) _test_command(arguments) def _publish_samples(self, project_name):