Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tabcmd/commands/group/delete_group_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def run_command(args):
server = session.create_session(args)
try:
logger.info(_("tabcmd.find.group").format(args.name))
group_id = Server.find_group_id(logger, server, args.name)
group_id = Server.find_group(logger, server, args.name).id
logger.info(_("deletegroup.status").format(group_id))
server.groups.delete(group_id)
logger.info(_("common.output.succeeded"))
Expand Down
25 changes: 12 additions & 13 deletions tabcmd/commands/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,26 @@ def find_group(logger, server, group_name):
Errors.exit_with_error(logger, exception=e)

@staticmethod
def find_group_id(logger, server, group_name):
return Server.find_group(logger, server, group_name).id
def find_user(logger, server, username):
return Server.get_items_by_name(logger, server.users, username)[0]

@staticmethod
def find_user_id(logger, server, username):
try:
return Server.get_items_by_name(logger, server.users, username)[0].id
except Exception as e:
Errors.exit_with_error(logger, exception=e)

@staticmethod
def get_items_by_name(logger, item_endpoint, item_name: str, container: TSC.ProjectItem = None):
def get_items_by_name(logger, item_endpoint, item_name: str, container: TSC.ProjectItem = None) -> List:
# TODO: typing should reflect that this returns TSC.TableauItem and item_endpoint is of type TSC.QuerysetEndpoint[same]
item_type = type(item_endpoint).__name__
item_log_name: str = "[" + item_type + "] " + item_name
if container:
item_log_name = str(container) + "/" + item_log_name
logger.debug(_("export.status").format(item_log_name))
req_option = TSC.RequestOptions()
req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, item_name))

all_items, pagination_item = item_endpoint.get(req_option)
if all_items is None or all_items == []:
raise ValueError("[" + item_type + "] " + _("errors.xmlapi.not_found"))
raise TSC.ServerResponseError(
code=404,
summary=_("errors.xmlapi.not_found"),
detail=_("errors.xmlapi.not_found") + ": " + item_log_name,
)
if len(all_items) == 1:
logger.debug("Exactly one result found")
result = all_items
Expand Down Expand Up @@ -120,7 +117,7 @@ def get_project_by_name_and_parent_path(logger, server, project_name: str, paren
if not parent_path:
if not project_name:
project_name = "Default"
project: TSC.ProjectItem = Server.get_items_by_name(logger, server.projects, project_name, None)
project: TSC.ProjectItem = Server.get_items_by_name(logger, server.projects, project_name, None)[0]
return project

project_tree: List[str] = Server._parse_project_path_to_list(parent_path)
Expand All @@ -129,7 +126,9 @@ def get_project_by_name_and_parent_path(logger, server, project_name: str, paren
return project

parent = Server._get_parent_project_from_tree(logger, server, project_tree)
logger.debug(parent)
project = Server._get_project_by_name_and_parent(logger, server, project_name, parent)
logger.debug(project)
if not project:
Errors.exit_with_error(logger, message=_("publish.errors.server_resource_not_found"))
return project
Expand Down
2 changes: 1 addition & 1 deletion tabcmd/commands/user/delete_site_users_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def run_command(args):
for user_obj in user_obj_list:
logger.info(_("importcsvsummary.line.processed").format(number_of_users_deleted))
try:
user_id = UserCommand.find_user_id(logger, server, user_obj.name)
user_id = UserCommand.find_user(logger, server, user_obj.name).id
server.users.remove(user_id)
logger.debug(_("tabcmd.result.success.delete_user").format(user_obj.name, user_id))
number_of_users_deleted += 1
Expand Down
31 changes: 24 additions & 7 deletions tabcmd/commands/user/user_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,17 +229,25 @@ def act_on_users(
logger.debug(_("importcsvsummary.line.processed").format(n_users_listed))

error_list = []
line_no = 0
user_obj_list: List[TSC.UserItem] = UserCommand.get_users_from_file(args.users)
logger.debug(_("tabcmd.result.success.parsed_users").format(len(user_obj_list)))
for user_obj in user_obj_list:
username: str = user_obj.name or "unknown user"
line_no += 1
if not user_obj.name:
number_of_errors += 1
error_list.append(_("importcsvsummary.error.line").format(line_no, "No username", ""))
continue

try:
user_id: str = UserCommand.find_user_id(logger, server, username)
username: str = user_obj.name
user_id: str = UserCommand.find_user(logger, server, username).id
logger.debug("{} user {} ({})".format(action_name, username, user_id))
except TSC.ServerResponseError as e:
Errors.check_common_error_codes_and_explain(logger, e)
number_of_errors += 1
error_list.append(e)
error_list.append(
_("importcsvsummary.error.line").format(line_no, username, "{}: {}".format(e.code, e.detail))
)
logger.debug(_("tabcmd.result.failure.user").format(username))
continue

Expand All @@ -248,11 +256,20 @@ def act_on_users(
n_users_handled += 1
logger.info(_("tabcmd.result.success.user_actions").format(action_name, username, group))
except TSC.ServerResponseError as e:
Errors.check_common_error_codes_and_explain(logger, e)
number_of_errors += 1
error_list.append(e)
error_list.append(
_("importcsvsummary.error.line").format(line_no, username, "{}: {}".format(e.code, e.detail))
)

logger.info(_("session.monitorjob.percent_complete").format(100))
logger.info(_("importcsvsummary.errors.count").format(number_of_errors))
if number_of_errors > 0:
logger.info(_("importcsvsummary.error.details").format(error_list))
i = 0
max_printing = 5
logger.info(_("importcsvsummary.error.details"))
while i < number_of_errors and i < max_printing:
logger.info(error_list[i])
i += 1
if number_of_errors > max_printing:
logger.info(_("importcsvsummary.error.too_many_errors"))
logger.info(_("importcsvsummary.remainingerrors"))
82 changes: 37 additions & 45 deletions tests/e2e/online_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,9 @@ 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 or parent_location)
print(arguments)
arguments.append(parent_path)
_test_command(arguments)

def _delete_project(self, project_name, parent_path=None):
Expand Down Expand Up @@ -136,7 +135,7 @@ def test_login(self):

@pytest.mark.order(1)
def test_version(self):
command = ""
command = "-v"
arguments = [command]
_test_command(arguments)

Expand All @@ -147,7 +146,7 @@ def test_help(self):
_test_command(arguments)

@pytest.mark.order(2)
def test_create_site_users(self):
def test_users_create_site_users(self):
if not server_admin and not site_admin:
pytest.skip("Must be server or site administrator to create site users")
command = "createsiteusers"
Expand All @@ -156,7 +155,7 @@ def test_create_site_users(self):
_test_command(arguments)

@pytest.mark.order(3)
def test_creategroup(self):
def test_group_creategroup(self):
if not server_admin and not site_admin:
pytest.skip("Must be server or site administrator to create groups")
groupname = group_name
Expand All @@ -165,7 +164,7 @@ def test_creategroup(self):
_test_command(arguments)

@pytest.mark.order(4)
def test_add_users_to_group(self):
def test_users_add_to_group(self):
if not server_admin and not site_admin:
pytest.skip("Must be server or site administrator to add to groups")

Expand All @@ -176,7 +175,7 @@ def test_add_users_to_group(self):
_test_command(arguments)

@pytest.mark.order(5)
def test_remove_users_to_group(self):
def test_users_remove_from_group(self):
if not server_admin and not site_admin:
pytest.skip("Must be server or site administrator to remove from groups")

Expand All @@ -187,7 +186,7 @@ def test_remove_users_to_group(self):
_test_command(arguments)

@pytest.mark.order(6)
def test_deletegroup(self):
def test_group_deletegroup(self):
if not server_admin and not site_admin:
pytest.skip("Must be server or site administrator to delete groups")

Expand All @@ -198,9 +197,12 @@ def test_deletegroup(self):

@pytest.mark.order(8)
def test_create_projects(self):

if not project_admin:
pytest.skip("Must be project administrator to create projects")

# project 1
self._create_project(parent_location)
time.sleep(indexing_sleep_time)
# project 1
self._create_project(project_name)
time.sleep(indexing_sleep_time)
Expand All @@ -216,89 +218,79 @@ def test_create_projects(self):
def test_list_projects(self):
self._list("projects")

@pytest.mark.order(9)
"""
@pytest.mark.order(9)
def test_publish_samples(self):
self._publish_samples(project_name)
"""

@pytest.mark.order(10)
def test_delete_projects(self):
if not project_admin:
pytest.skip("Must be project administrator to create projects")
self._delete_project("project_name_2", project_name) # project 2
self._delete_project(project_name)

@pytest.mark.order(9)
def test_publish_samples(self):
self._publish_samples(project_name)

@pytest.mark.order(10)
def test_publish(self):
def test_wb_publish(self):
name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
file = os.path.join("tests", "assets", OnlineCommandTest.TWBX_FILE_WITH_EXTRACT)
self._publish_wb(file, name_on_server)

@pytest.mark.order(10)
def test__get_wb(self):
wb_name_on_server = OnlineCommandTest.TWBX_WITHOUT_EXTRACT_NAME
self._get_workbook(wb_name_on_server + ".twbx")
def test_wb_get(self):
self._get_workbook(OnlineCommandTest.TWBX_WITH_EXTRACT_NAME + ".twbx")

@pytest.mark.order(10)
def test__get_wb(self):
def test_view_get_pdf(self):
wb_name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
self._get_workbook(wb_name_on_server + ".twbx")

@pytest.mark.order(10)
def test__get_view(self):
wb_name_on_server = OnlineCommandTest.TWBX_WITHOUT_EXTRACT_NAME
sheet_name = OnlineCommandTest.TWBX_WITHOUT_EXTRACT_SHEET
sheet_name = OnlineCommandTest.TWBX_WITH_EXTRACT_SHEET
self._get_view(wb_name_on_server, sheet_name + ".pdf")

@pytest.mark.order(10)
def test__get_view_csv(self):
def test_view_get_csv(self):
wb_name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
sheet_name = OnlineCommandTest.TWBX_WITH_EXTRACT_SHEET
self._get_view(wb_name_on_server, sheet_name + ".csv")

@pytest.mark.order(10)
def test__get_view_png(self):
def test_view_get_png(self):
wb_name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
sheet_name = OnlineCommandTest.TWBX_WITH_EXTRACT_SHEET
self._get_view(wb_name_on_server, sheet_name + ".png")

@pytest.mark.order(11)
def test__delete_wb(self):
def test_wb_delete(self):
name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
self._delete_wb(name_on_server)

@pytest.mark.order(12)
def test_delete_extract(self):
def test_extract_delete(self):
# fails because the extract has a bad data connection :/
name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
file = os.path.join("tests", "assets", OnlineCommandTest.TWBX_FILE_WITH_EXTRACT)
self._publish_wb(file, name_on_server)
self._delete_extract(name_on_server)

@pytest.mark.order(13)
def test_create_extract(self):
def test_extract_create(self):
# Fails because it 'already has an extract' :/
name_on_server = OnlineCommandTest.TWBX_WITHOUT_EXTRACT_NAME
self._create_extract(name_on_server)

@pytest.mark.order(14)
def test_refresh_extract(self):
def test_extract_refresh(self):
# must be a datasource owned by the test user
name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
file = os.path.join("tests", "assets", OnlineCommandTest.TWBX_FILE_WITH_EXTRACT)
self._publish_wb(file, name_on_server)

name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
self._refresh_extract(name_on_server)
self._delete_wb(name_on_server)

def test_version(self):
_test_command(["-v"])

def test_help(self):
_test_command(["help"])

# this just gets in the way :(
# def test_logout(self):
# _test_command(["logout"])

@pytest.mark.order(15)
def test_export_wb(self):
def test_export_wb_pdf(self):
name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
file = os.path.join("tests", "assets", OnlineCommandTest.TWBX_FILE_WITH_EXTRACT)
self._publish_wb(file, name_on_server)
Expand All @@ -308,7 +300,7 @@ def test_export_wb(self):
_test_command(arguments)

@pytest.mark.order(15)
def test_export_view(self):
def test_export_view_pdf(self):
name_on_server = OnlineCommandTest.TWBX_WITH_EXTRACT_NAME
file = os.path.join("tests", "assets", OnlineCommandTest.TWBX_FILE_WITH_EXTRACT)
self._publish_wb(file, name_on_server)
Expand All @@ -318,7 +310,7 @@ def test_export_view(self):
_test_command(arguments)

@pytest.mark.order(16)
def test_delete_site_users(self):
def test_users_delete_site_users(self):
if not server_admin and not site_admin:
pytest.skip("Must be server or site administrator to delete site users")

Expand Down