diff --git a/python/tk_multi_publish2/__init__.py b/python/tk_multi_publish2/__init__.py index cebbc847..7788c64b 100644 --- a/python/tk_multi_publish2/__init__.py +++ b/python/tk_multi_publish2/__init__.py @@ -13,6 +13,7 @@ from .api import PublishManager # noqa from . import base_hooks # noqa from . import util # noqa +from . import publish_tree_widget # noqa def show_dialog(app): diff --git a/python/tk_multi_publish2/publish_tree_widget/publish_tree_widget.py b/python/tk_multi_publish2/publish_tree_widget/publish_tree_widget.py index 891c8adb..582e8ef7 100644 --- a/python/tk_multi_publish2/publish_tree_widget/publish_tree_widget.py +++ b/python/tk_multi_publish2/publish_tree_widget/publish_tree_widget.py @@ -165,6 +165,13 @@ def _build_item_tree_r(self, item, checked, level, tree_parent): if not item.checked: ui_item.set_check_state(QtCore.Qt.Unchecked) + # If we have a bunch of active tasks followed by a bunch of inactive tasks, the addition + # of the inactive tasks does not trigger an update of the parent's checkbox (because the update + # relies on the checkbox.state_changed and the default is unchecked, so inactive tasks do not + # trigger a state change). Force a recalculation to keep the parent's check_state + # correct in all situation + ui_item.recompute_check_state() + return ui_item def build_tree(self): diff --git a/tests/README.md b/tests/README.md index 8e36f9bf..f54a260f 100644 --- a/tests/README.md +++ b/tests/README.md @@ -13,3 +13,5 @@ Shotgun site. You can use any site. The app itself has a few plugins that pretend to operate on items found in a scene. + +Install tk-toolchain and use pytest to run the tests diff --git a/tests/python/publish_api_test_base.py b/tests/python/publish_api_test_base.py index 6d325603..8b06a771 100644 --- a/tests/python/publish_api_test_base.py +++ b/tests/python/publish_api_test_base.py @@ -74,6 +74,11 @@ def setUp(self): self.PublishManager = self.api.PublishManager self.PublishPluginInstance = self.api.plugins.PublishPluginInstance + publish_tree_widget = self.app.import_module( + "tk_multi_publish2" + ).publish_tree_widget + self.PublishTreeWidget = publish_tree_widget.PublishTreeWidget + self.image_path = os.path.join(repo_root, "icon_256.png") self.dark_image_path = os.path.join(repo_root, "icon_256_dark.png") diff --git a/tests/run_tests.sh b/tests/run_tests.sh deleted file mode 100755 index 7394afa5..00000000 --- a/tests/run_tests.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2017 Shotgun Software Inc. -# -# CONFIDENTIAL AND PROPRIETARY -# -# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit -# Source Code License included in this distribution package. See LICENSE. -# By accessing, using, copying or modifying this work you indicate your -# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights -# not expressly granted therein are reserved by Shotgun Software Inc. - - -# If the SHOTGUN_EXTERNAL_REPOS_ROOT is not set, we're going to assume every repo -# needed is a sibling of the publish 2 repo. -if [ -z ${SHOTGUN_EXTERNAL_REPOS_ROOT+x} ]; then - export SHOTGUN_EXTERNAL_REPOS_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../.." -fi - -${SHOTGUN_EXTERNAL_REPOS_ROOT}/tk-core/tests/run_tests.sh --test-root "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" $* diff --git a/tests/test_tree_widget.py b/tests/test_tree_widget.py new file mode 100644 index 00000000..b940cb08 --- /dev/null +++ b/tests/test_tree_widget.py @@ -0,0 +1,64 @@ +# Copyright (c) 2018 Shotgun Software Inc. +# +# CONFIDENTIAL AND PROPRIETARY +# +# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit +# Source Code License included in this distribution package. See LICENSE. +# By accessing, using, copying or modifying this work you indicate your +# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights +# not expressly granted therein are reserved by Shotgun Software Inc. + +from publish_api_test_base import PublishApiTestBase +from tank_test.tank_test_base import setUpModule # noqa + + +class TestPublishTreeWidget(PublishApiTestBase): + def test_parent_partially_checked(self): + """ + If we have a bunch of active tasks followed by a bunch of inactive tasks, the addition + of the inactive tasks does not trigger an update of the parent's checkbox (because the update + relies on the checkbox.state_changed and the default is unchecked, so inactive tasks do not + trigger a state change). Test that we are forcing a recalculation to keep the parent's check_state + correct in all situations + """ + tree = self.manager.tree + item = tree.root_item.create_item("item.parent", "Parent", "Parent") + publish_plugins = self.manager._load_publish_plugins(item.context) + + item.add_task(publish_plugins[0]) + item.add_task(publish_plugins[0]) + + item.tasks[0]._active = True + item.tasks[1]._active = False + + tree_widget = self.PublishTreeWidget(None) + tree_widget.set_publish_manager(self.manager) + tree_widget.build_tree() + + project_item = tree_widget.topLevelItem(1) + parent_item = project_item.child(0) + self.assertEqual(parent_item.check_state, self.QtCore.Qt.PartiallyChecked) + + def test_parent_checked_children_unchecked(self): + """ + If a parent item is active and only has inactive tasks, make sure that when the + tree is built the parent item's check_state is valid and is set to unchecked + """ + tree = self.manager.tree + item = tree.root_item.create_item("item.parent", "Parent", "Parent") + publish_plugins = self.manager._load_publish_plugins(item.context) + + item.add_task(publish_plugins[0]) + item.add_task(publish_plugins[0]) + + item._active = True + item.tasks[0]._active = False + item.tasks[1]._active = False + + tree_widget = self.PublishTreeWidget(None) + tree_widget.set_publish_manager(self.manager) + tree_widget.build_tree() + + project_item = tree_widget.topLevelItem(1) + parent_item = project_item.child(0) + self.assertEqual(parent_item.check_state, self.QtCore.Qt.Unchecked)