|
22 | 22 | from werkzeug.utils import secure_filename |
23 | 23 |
|
24 | 24 | from superset import db, security_manager |
25 | | -from superset.commands.dashboard.exceptions import DashboardNotFoundError |
| 25 | +from superset.commands.dashboard.copy import CopyDashboardCommand |
| 26 | +from superset.commands.dashboard.exceptions import ( |
| 27 | + DashboardForbiddenError, |
| 28 | + DashboardInvalidError, |
| 29 | + DashboardNotFoundError, |
| 30 | +) |
26 | 31 | from superset.commands.dashboard.export import ( |
27 | 32 | append_charts, |
28 | 33 | ExportDashboardsCommand, |
|
36 | 41 | from superset.models.dashboard import Dashboard |
37 | 42 | from superset.models.slice import Slice |
38 | 43 | from superset.utils import json |
| 44 | +from superset.utils.core import override_user |
39 | 45 | from tests.integration_tests.base_tests import SupersetTestCase |
40 | 46 | from tests.integration_tests.fixtures.importexport import ( |
41 | 47 | chart_config, |
@@ -660,3 +666,57 @@ def test_import_v1_dashboard_validation(self): |
660 | 666 | "table_name": ["Missing data for required field."], |
661 | 667 | } |
662 | 668 | } |
| 669 | + |
| 670 | + |
| 671 | +class TestCopyDashboardCommand(SupersetTestCase): |
| 672 | + @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") |
| 673 | + def test_copy_dashboard_command(self): |
| 674 | + """Test that an admin user can copy a dashboard""" |
| 675 | + with self.client.application.test_request_context(): |
| 676 | + example_dashboard = ( |
| 677 | + db.session.query(Dashboard).filter_by(slug="world_health").one() |
| 678 | + ) |
| 679 | + copy_data = {"dashboard_title": "Copied Dashboard", "json_metadata": "{}"} |
| 680 | + |
| 681 | + with override_user(security_manager.find_user("admin")): |
| 682 | + command = CopyDashboardCommand(example_dashboard, copy_data) |
| 683 | + copied_dashboard = command.run() |
| 684 | + |
| 685 | + assert copied_dashboard.dashboard_title == "Copied Dashboard" |
| 686 | + assert copied_dashboard.slug != example_dashboard.slug |
| 687 | + assert copied_dashboard.slices == example_dashboard.slices |
| 688 | + |
| 689 | + db.session.delete(copied_dashboard) |
| 690 | + db.session.commit() |
| 691 | + |
| 692 | + @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") |
| 693 | + def test_copy_dashboard_command_no_access(self): |
| 694 | + """Test that a non-owner user cannot copy a dashboard if DASHBOARD_RBAC is enabled""" |
| 695 | + with self.client.application.test_request_context(): |
| 696 | + example_dashboard = ( |
| 697 | + db.session.query(Dashboard).filter_by(slug="world_health").one() |
| 698 | + ) |
| 699 | + copy_data = {"dashboard_title": "Copied Dashboard", "json_metadata": "{}"} |
| 700 | + |
| 701 | + with override_user(security_manager.find_user("gamma")): |
| 702 | + with patch( |
| 703 | + "superset.commands.dashboard.copy.is_feature_enabled", |
| 704 | + return_value=True, |
| 705 | + ): |
| 706 | + command = CopyDashboardCommand(example_dashboard, copy_data) |
| 707 | + with self.assertRaises(DashboardForbiddenError): |
| 708 | + command.run() |
| 709 | + |
| 710 | + @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") |
| 711 | + def test_copy_dashboard_command_invalid_data(self): |
| 712 | + """Test that invalid data raises a DashboardInvalidError""" |
| 713 | + with self.client.application.test_request_context(): |
| 714 | + example_dashboard = ( |
| 715 | + db.session.query(Dashboard).filter_by(slug="world_health").one() |
| 716 | + ) |
| 717 | + invalid_copy_data = {"dashboard_title": "", "json_metadata": "{}"} |
| 718 | + |
| 719 | + with override_user(security_manager.find_user("admin")): |
| 720 | + command = CopyDashboardCommand(example_dashboard, invalid_copy_data) |
| 721 | + with self.assertRaises(DashboardInvalidError): |
| 722 | + command.run() |
0 commit comments