2020-10-22 15:06:58 -04:00
|
|
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
|
|
# or more contributor license agreements. See the NOTICE file
|
|
|
|
# distributed with this work for additional information
|
|
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
|
|
# to you under the Apache License, Version 2.0 (the
|
|
|
|
# "License"); you may not use this file except in compliance
|
|
|
|
# with the License. You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing,
|
|
|
|
# software distributed under the License is distributed on an
|
|
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
# KIND, either express or implied. See the License for the
|
|
|
|
# specific language governing permissions and limitations
|
|
|
|
# under the License.
|
2020-11-20 17:20:13 -05:00
|
|
|
import json
|
2020-10-22 15:06:58 -04:00
|
|
|
from unittest.mock import patch
|
|
|
|
|
2020-11-20 17:20:13 -05:00
|
|
|
import pytest
|
2020-10-22 15:06:58 -04:00
|
|
|
import yaml
|
2021-08-10 12:29:49 -04:00
|
|
|
from flask import g
|
2020-10-22 15:06:58 -04:00
|
|
|
|
|
|
|
from superset import db, security_manager
|
2022-03-02 00:44:36 -05:00
|
|
|
from superset.charts.commands.create import CreateChartCommand
|
2023-06-20 07:08:29 -04:00
|
|
|
from superset.charts.commands.exceptions import (
|
|
|
|
ChartNotFoundError,
|
|
|
|
WarmUpCacheChartNotFoundError,
|
|
|
|
)
|
2020-10-22 15:06:58 -04:00
|
|
|
from superset.charts.commands.export import ExportChartsCommand
|
2020-11-20 17:20:13 -05:00
|
|
|
from superset.charts.commands.importers.v1 import ImportChartsCommand
|
2021-08-10 12:29:49 -04:00
|
|
|
from superset.charts.commands.update import UpdateChartCommand
|
2023-06-20 07:08:29 -04:00
|
|
|
from superset.charts.commands.warm_up_cache import ChartWarmUpCacheCommand
|
2020-11-20 17:20:13 -05:00
|
|
|
from superset.commands.exceptions import CommandInvalidError
|
|
|
|
from superset.commands.importers.exceptions import IncorrectVersionError
|
|
|
|
from superset.connectors.sqla.models import SqlaTable
|
|
|
|
from superset.models.core import Database
|
2020-10-22 15:06:58 -04:00
|
|
|
from superset.models.slice import Slice
|
2021-07-01 11:03:07 -04:00
|
|
|
from tests.integration_tests.base_tests import SupersetTestCase
|
2023-06-20 07:08:29 -04:00
|
|
|
from tests.integration_tests.fixtures.birth_names_dashboard import (
|
|
|
|
load_birth_names_dashboard_with_slices,
|
|
|
|
load_birth_names_data,
|
|
|
|
)
|
2021-07-01 11:03:07 -04:00
|
|
|
from tests.integration_tests.fixtures.energy_dashboard import (
|
2021-12-16 19:11:47 -05:00
|
|
|
load_energy_table_data,
|
2021-07-01 11:03:07 -04:00
|
|
|
load_energy_table_with_slice,
|
|
|
|
)
|
|
|
|
from tests.integration_tests.fixtures.importexport import (
|
2020-11-20 17:20:13 -05:00
|
|
|
chart_config,
|
|
|
|
chart_metadata_config,
|
|
|
|
database_config,
|
|
|
|
database_metadata_config,
|
|
|
|
dataset_config,
|
|
|
|
)
|
2020-10-22 15:06:58 -04:00
|
|
|
|
|
|
|
|
|
|
|
class TestExportChartsCommand(SupersetTestCase):
|
|
|
|
@patch("superset.security.manager.g")
|
2020-12-09 15:02:29 -05:00
|
|
|
@pytest.mark.usefixtures("load_energy_table_with_slice")
|
2020-10-22 15:06:58 -04:00
|
|
|
def test_export_chart_command(self, mock_g):
|
|
|
|
mock_g.user = security_manager.find_user("admin")
|
|
|
|
|
2020-12-09 15:02:29 -05:00
|
|
|
example_chart = (
|
2020-12-22 17:19:05 -05:00
|
|
|
db.session.query(Slice).filter_by(slice_name="Energy Sankey").one()
|
2020-12-09 15:02:29 -05:00
|
|
|
)
|
2020-10-30 14:52:11 -04:00
|
|
|
command = ExportChartsCommand([example_chart.id])
|
2020-10-22 15:06:58 -04:00
|
|
|
contents = dict(command.run())
|
|
|
|
|
|
|
|
expected = [
|
2020-10-30 14:52:11 -04:00
|
|
|
"metadata.yaml",
|
2020-12-22 17:19:05 -05:00
|
|
|
f"charts/Energy_Sankey_{example_chart.id}.yaml",
|
2020-10-22 15:06:58 -04:00
|
|
|
"datasets/examples/energy_usage.yaml",
|
|
|
|
"databases/examples.yaml",
|
|
|
|
]
|
|
|
|
assert expected == list(contents.keys())
|
|
|
|
|
2020-12-22 17:19:05 -05:00
|
|
|
metadata = yaml.safe_load(
|
|
|
|
contents[f"charts/Energy_Sankey_{example_chart.id}.yaml"]
|
|
|
|
)
|
2021-12-02 11:46:25 -05:00
|
|
|
|
2020-10-22 15:06:58 -04:00
|
|
|
assert metadata == {
|
|
|
|
"slice_name": "Energy Sankey",
|
2023-02-06 18:30:22 -05:00
|
|
|
"description": None,
|
|
|
|
"certified_by": None,
|
|
|
|
"certification_details": None,
|
2020-10-22 15:06:58 -04:00
|
|
|
"viz_type": "sankey",
|
|
|
|
"params": {
|
|
|
|
"collapsed_fieldsets": "",
|
2020-11-20 17:20:13 -05:00
|
|
|
"groupby": ["source", "target"],
|
2020-10-22 15:06:58 -04:00
|
|
|
"metric": "sum__value",
|
|
|
|
"row_limit": "5000",
|
|
|
|
"slice_name": "Energy Sankey",
|
|
|
|
"viz_type": "sankey",
|
|
|
|
},
|
|
|
|
"cache_timeout": None,
|
|
|
|
"dataset_uuid": str(example_chart.table.uuid),
|
|
|
|
"uuid": str(example_chart.uuid),
|
|
|
|
"version": "1.0.0",
|
2023-04-05 14:16:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@patch("superset.security.manager.g")
|
|
|
|
@pytest.mark.usefixtures("load_energy_table_with_slice")
|
|
|
|
def test_export_chart_with_query_context(self, mock_g):
|
|
|
|
"""Test that charts that have a query_context are exported correctly"""
|
|
|
|
|
|
|
|
mock_g.user = security_manager.find_user("alpha")
|
|
|
|
example_chart = db.session.query(Slice).filter_by(slice_name="Heatmap").one()
|
|
|
|
command = ExportChartsCommand([example_chart.id])
|
|
|
|
|
|
|
|
contents = dict(command.run())
|
|
|
|
|
|
|
|
expected = [
|
|
|
|
"metadata.yaml",
|
|
|
|
f"charts/Heatmap_{example_chart.id}.yaml",
|
|
|
|
"datasets/examples/energy_usage.yaml",
|
|
|
|
"databases/examples.yaml",
|
|
|
|
]
|
|
|
|
assert expected == list(contents.keys())
|
|
|
|
|
|
|
|
metadata = yaml.safe_load(contents[f"charts/Heatmap_{example_chart.id}.yaml"])
|
|
|
|
|
|
|
|
assert metadata == {
|
|
|
|
"slice_name": "Heatmap",
|
|
|
|
"description": None,
|
|
|
|
"certified_by": None,
|
|
|
|
"certification_details": None,
|
|
|
|
"viz_type": "heatmap",
|
|
|
|
"params": {
|
|
|
|
"all_columns_x": "source",
|
|
|
|
"all_columns_y": "target",
|
|
|
|
"canvas_image_rendering": "pixelated",
|
|
|
|
"collapsed_fieldsets": "",
|
|
|
|
"linear_color_scheme": "blue_white_yellow",
|
|
|
|
"metric": "sum__value",
|
|
|
|
"normalize_across": "heatmap",
|
|
|
|
"slice_name": "Heatmap",
|
|
|
|
"viz_type": "heatmap",
|
|
|
|
"xscale_interval": "1",
|
|
|
|
"yscale_interval": "1",
|
|
|
|
},
|
|
|
|
"cache_timeout": None,
|
|
|
|
"dataset_uuid": str(example_chart.table.uuid),
|
|
|
|
"uuid": str(example_chart.uuid),
|
|
|
|
"version": "1.0.0",
|
2021-12-02 11:46:25 -05:00
|
|
|
}
|
|
|
|
|
2020-10-22 15:06:58 -04:00
|
|
|
@patch("superset.security.manager.g")
|
2021-11-30 19:51:00 -05:00
|
|
|
@pytest.mark.usefixtures("load_energy_table_with_slice")
|
2020-10-22 15:06:58 -04:00
|
|
|
def test_export_chart_command_no_access(self, mock_g):
|
|
|
|
"""Test that users can't export datasets they don't have access to"""
|
|
|
|
mock_g.user = security_manager.find_user("gamma")
|
|
|
|
|
|
|
|
example_chart = db.session.query(Slice).all()[0]
|
2020-10-30 14:52:11 -04:00
|
|
|
command = ExportChartsCommand([example_chart.id])
|
2020-10-22 15:06:58 -04:00
|
|
|
contents = command.run()
|
|
|
|
with self.assertRaises(ChartNotFoundError):
|
|
|
|
next(contents)
|
|
|
|
|
|
|
|
@patch("superset.security.manager.g")
|
|
|
|
def test_export_chart_command_invalid_dataset(self, mock_g):
|
|
|
|
"""Test that an error is raised when exporting an invalid dataset"""
|
|
|
|
mock_g.user = security_manager.find_user("admin")
|
2020-10-30 14:52:11 -04:00
|
|
|
command = ExportChartsCommand([-1])
|
2020-10-22 15:06:58 -04:00
|
|
|
contents = command.run()
|
|
|
|
with self.assertRaises(ChartNotFoundError):
|
|
|
|
next(contents)
|
|
|
|
|
|
|
|
@patch("superset.security.manager.g")
|
2020-12-09 15:02:29 -05:00
|
|
|
@pytest.mark.usefixtures("load_energy_table_with_slice")
|
2020-10-22 15:06:58 -04:00
|
|
|
def test_export_chart_command_key_order(self, mock_g):
|
|
|
|
"""Test that they keys in the YAML have the same order as export_fields"""
|
|
|
|
mock_g.user = security_manager.find_user("admin")
|
|
|
|
|
2020-12-09 15:02:29 -05:00
|
|
|
example_chart = (
|
2020-12-22 17:19:05 -05:00
|
|
|
db.session.query(Slice).filter_by(slice_name="Energy Sankey").one()
|
2020-12-09 15:02:29 -05:00
|
|
|
)
|
2020-10-30 14:52:11 -04:00
|
|
|
command = ExportChartsCommand([example_chart.id])
|
2020-10-22 15:06:58 -04:00
|
|
|
contents = dict(command.run())
|
|
|
|
|
2020-12-22 17:19:05 -05:00
|
|
|
metadata = yaml.safe_load(
|
|
|
|
contents[f"charts/Energy_Sankey_{example_chart.id}.yaml"]
|
|
|
|
)
|
2020-10-22 15:06:58 -04:00
|
|
|
assert list(metadata.keys()) == [
|
|
|
|
"slice_name",
|
2023-02-06 18:30:22 -05:00
|
|
|
"description",
|
|
|
|
"certified_by",
|
|
|
|
"certification_details",
|
2020-10-22 15:06:58 -04:00
|
|
|
"viz_type",
|
|
|
|
"params",
|
|
|
|
"cache_timeout",
|
|
|
|
"uuid",
|
|
|
|
"version",
|
|
|
|
"dataset_uuid",
|
|
|
|
]
|
2020-11-20 17:20:13 -05:00
|
|
|
|
2022-03-16 19:03:06 -04:00
|
|
|
@patch("superset.security.manager.g")
|
|
|
|
@pytest.mark.usefixtures("load_energy_table_with_slice")
|
|
|
|
def test_export_chart_command_no_related(self, mock_g):
|
|
|
|
"""
|
|
|
|
Test that only the chart is exported when export_related=False.
|
|
|
|
"""
|
|
|
|
mock_g.user = security_manager.find_user("admin")
|
|
|
|
|
|
|
|
example_chart = (
|
|
|
|
db.session.query(Slice).filter_by(slice_name="Energy Sankey").one()
|
|
|
|
)
|
|
|
|
command = ExportChartsCommand([example_chart.id], export_related=False)
|
|
|
|
contents = dict(command.run())
|
|
|
|
|
|
|
|
expected = [
|
|
|
|
"metadata.yaml",
|
|
|
|
f"charts/Energy_Sankey_{example_chart.id}.yaml",
|
|
|
|
]
|
|
|
|
assert expected == list(contents.keys())
|
|
|
|
|
2020-11-23 19:28:26 -05:00
|
|
|
|
|
|
|
class TestImportChartsCommand(SupersetTestCase):
|
2021-09-15 15:27:02 -04:00
|
|
|
@patch("superset.charts.commands.importers.v1.utils.g")
|
2023-03-15 11:31:09 -04:00
|
|
|
@patch("superset.security.manager.g")
|
|
|
|
def test_import_v1_chart(self, sm_g, utils_g):
|
2020-11-20 17:20:13 -05:00
|
|
|
"""Test that we can import a chart"""
|
2023-03-15 11:31:09 -04:00
|
|
|
admin = sm_g.user = utils_g.user = security_manager.find_user("admin")
|
2020-11-20 17:20:13 -05:00
|
|
|
contents = {
|
|
|
|
"metadata.yaml": yaml.safe_dump(chart_metadata_config),
|
|
|
|
"databases/imported_database.yaml": yaml.safe_dump(database_config),
|
|
|
|
"datasets/imported_dataset.yaml": yaml.safe_dump(dataset_config),
|
|
|
|
"charts/imported_chart.yaml": yaml.safe_dump(chart_config),
|
|
|
|
}
|
|
|
|
command = ImportChartsCommand(contents)
|
|
|
|
command.run()
|
|
|
|
|
2021-07-21 16:54:39 -04:00
|
|
|
chart: Slice = (
|
|
|
|
db.session.query(Slice).filter_by(uuid=chart_config["uuid"]).one()
|
|
|
|
)
|
2021-01-13 11:49:51 -05:00
|
|
|
dataset = chart.datasource
|
2020-11-20 17:20:13 -05:00
|
|
|
assert json.loads(chart.params) == {
|
|
|
|
"color_picker": {"a": 1, "b": 135, "g": 122, "r": 0},
|
2021-01-13 11:49:51 -05:00
|
|
|
"datasource": dataset.uid,
|
2020-11-20 17:20:13 -05:00
|
|
|
"js_columns": ["color"],
|
|
|
|
"js_data_mutator": "data => data.map(d => ({\\n ...d,\\n color: colors.hexToRGB(d.extraProps.color)\\n}));",
|
|
|
|
"js_onclick_href": "",
|
|
|
|
"js_tooltip": "",
|
|
|
|
"line_column": "path_json",
|
|
|
|
"line_type": "json",
|
|
|
|
"line_width": 150,
|
|
|
|
"mapbox_style": "mapbox://styles/mapbox/light-v9",
|
|
|
|
"reverse_long_lat": False,
|
|
|
|
"row_limit": 5000,
|
|
|
|
"slice_id": 43,
|
|
|
|
"time_grain_sqla": None,
|
|
|
|
"time_range": " : ",
|
|
|
|
"viewport": {
|
|
|
|
"altitude": 1.5,
|
|
|
|
"bearing": 0,
|
|
|
|
"height": 1094,
|
|
|
|
"latitude": 37.73671752604488,
|
|
|
|
"longitude": -122.18885402582598,
|
|
|
|
"maxLatitude": 85.05113,
|
|
|
|
"maxPitch": 60,
|
|
|
|
"maxZoom": 20,
|
|
|
|
"minLatitude": -85.05113,
|
|
|
|
"minPitch": 0,
|
|
|
|
"minZoom": 0,
|
|
|
|
"pitch": 0,
|
|
|
|
"width": 669,
|
|
|
|
"zoom": 9.51847667620428,
|
|
|
|
},
|
|
|
|
"viz_type": "deck_path",
|
|
|
|
}
|
|
|
|
|
|
|
|
dataset = (
|
|
|
|
db.session.query(SqlaTable).filter_by(uuid=dataset_config["uuid"]).one()
|
|
|
|
)
|
|
|
|
assert dataset.table_name == "imported_dataset"
|
|
|
|
assert chart.table == dataset
|
|
|
|
|
|
|
|
database = (
|
|
|
|
db.session.query(Database).filter_by(uuid=database_config["uuid"]).one()
|
|
|
|
)
|
|
|
|
assert database.database_name == "imported_database"
|
|
|
|
assert chart.table.database == database
|
|
|
|
|
2023-03-15 11:31:09 -04:00
|
|
|
assert chart.owners == [admin]
|
2021-09-15 15:27:02 -04:00
|
|
|
|
|
|
|
chart.owners = []
|
|
|
|
database.owners = []
|
2020-11-20 17:20:13 -05:00
|
|
|
db.session.delete(chart)
|
|
|
|
db.session.delete(dataset)
|
|
|
|
db.session.delete(database)
|
|
|
|
db.session.commit()
|
|
|
|
|
2023-03-15 11:31:09 -04:00
|
|
|
@patch("superset.security.manager.g")
|
|
|
|
def test_import_v1_chart_multiple(self, sm_g):
|
2021-04-08 14:20:11 -04:00
|
|
|
"""Test that a chart can be imported multiple times"""
|
2023-03-15 11:31:09 -04:00
|
|
|
sm_g.user = security_manager.find_user("admin")
|
2020-11-20 17:20:13 -05:00
|
|
|
contents = {
|
|
|
|
"metadata.yaml": yaml.safe_dump(chart_metadata_config),
|
|
|
|
"databases/imported_database.yaml": yaml.safe_dump(database_config),
|
|
|
|
"datasets/imported_dataset.yaml": yaml.safe_dump(dataset_config),
|
|
|
|
"charts/imported_chart.yaml": yaml.safe_dump(chart_config),
|
|
|
|
}
|
2020-12-10 17:50:10 -05:00
|
|
|
command = ImportChartsCommand(contents, overwrite=True)
|
2020-11-20 17:20:13 -05:00
|
|
|
command.run()
|
|
|
|
command.run()
|
|
|
|
|
|
|
|
dataset = (
|
|
|
|
db.session.query(SqlaTable).filter_by(uuid=dataset_config["uuid"]).one()
|
|
|
|
)
|
|
|
|
charts = db.session.query(Slice).filter_by(datasource_id=dataset.id).all()
|
|
|
|
assert len(charts) == 1
|
|
|
|
|
|
|
|
database = dataset.database
|
|
|
|
|
|
|
|
db.session.delete(charts[0])
|
|
|
|
db.session.delete(dataset)
|
|
|
|
db.session.delete(database)
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
def test_import_v1_chart_validation(self):
|
|
|
|
"""Test different validations applied when importing a chart"""
|
|
|
|
# metadata.yaml must be present
|
|
|
|
contents = {
|
|
|
|
"databases/imported_database.yaml": yaml.safe_dump(database_config),
|
|
|
|
"datasets/imported_dataset.yaml": yaml.safe_dump(dataset_config),
|
|
|
|
"charts/imported_chart.yaml": yaml.safe_dump(chart_config),
|
|
|
|
}
|
|
|
|
command = ImportChartsCommand(contents)
|
|
|
|
with pytest.raises(IncorrectVersionError) as excinfo:
|
|
|
|
command.run()
|
|
|
|
assert str(excinfo.value) == "Missing metadata.yaml"
|
|
|
|
|
|
|
|
# version should be 1.0.0
|
|
|
|
contents["metadata.yaml"] = yaml.safe_dump(
|
|
|
|
{
|
|
|
|
"version": "2.0.0",
|
|
|
|
"type": "SqlaTable",
|
|
|
|
"timestamp": "2020-11-04T21:27:44.423819+00:00",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
command = ImportChartsCommand(contents)
|
|
|
|
with pytest.raises(IncorrectVersionError) as excinfo:
|
|
|
|
command.run()
|
|
|
|
assert str(excinfo.value) == "Must be equal to 1.0.0."
|
|
|
|
|
|
|
|
# type should be Slice
|
|
|
|
contents["metadata.yaml"] = yaml.safe_dump(database_metadata_config)
|
|
|
|
command = ImportChartsCommand(contents)
|
|
|
|
with pytest.raises(CommandInvalidError) as excinfo:
|
|
|
|
command.run()
|
|
|
|
assert str(excinfo.value) == "Error importing chart"
|
|
|
|
assert excinfo.value.normalized_messages() == {
|
|
|
|
"metadata.yaml": {"type": ["Must be equal to Slice."]}
|
|
|
|
}
|
|
|
|
|
|
|
|
# must also validate datasets and databases
|
|
|
|
broken_config = database_config.copy()
|
|
|
|
del broken_config["database_name"]
|
|
|
|
contents["metadata.yaml"] = yaml.safe_dump(chart_metadata_config)
|
|
|
|
contents["databases/imported_database.yaml"] = yaml.safe_dump(broken_config)
|
|
|
|
command = ImportChartsCommand(contents)
|
|
|
|
with pytest.raises(CommandInvalidError) as excinfo:
|
|
|
|
command.run()
|
|
|
|
assert str(excinfo.value) == "Error importing chart"
|
|
|
|
assert excinfo.value.normalized_messages() == {
|
|
|
|
"databases/imported_database.yaml": {
|
|
|
|
"database_name": ["Missing data for required field."],
|
|
|
|
}
|
|
|
|
}
|
2021-08-10 12:29:49 -04:00
|
|
|
|
|
|
|
|
2022-03-02 00:44:36 -05:00
|
|
|
class TestChartsCreateCommand(SupersetTestCase):
|
2022-07-07 14:04:27 -04:00
|
|
|
@patch("superset.utils.core.g")
|
|
|
|
@patch("superset.charts.commands.create.g")
|
2022-03-02 00:44:36 -05:00
|
|
|
@patch("superset.security.manager.g")
|
|
|
|
@pytest.mark.usefixtures("load_energy_table_with_slice")
|
2022-07-07 14:04:27 -04:00
|
|
|
def test_create_v1_response(self, mock_sm_g, mock_c_g, mock_u_g):
|
2022-03-02 00:44:36 -05:00
|
|
|
"""Test that the create chart command creates a chart"""
|
2022-07-07 14:04:27 -04:00
|
|
|
user = security_manager.find_user(username="admin")
|
|
|
|
mock_u_g.user = mock_c_g.user = mock_sm_g.user = user
|
2022-03-02 00:44:36 -05:00
|
|
|
chart_data = {
|
|
|
|
"slice_name": "new chart",
|
|
|
|
"description": "new description",
|
2022-07-07 14:04:27 -04:00
|
|
|
"owners": [user.id],
|
2022-03-02 00:44:36 -05:00
|
|
|
"viz_type": "new_viz_type",
|
|
|
|
"params": json.dumps({"viz_type": "new_viz_type"}),
|
|
|
|
"cache_timeout": 1000,
|
|
|
|
"datasource_id": 1,
|
|
|
|
"datasource_type": "table",
|
|
|
|
}
|
2022-07-07 14:04:27 -04:00
|
|
|
command = CreateChartCommand(chart_data)
|
2022-03-02 00:44:36 -05:00
|
|
|
chart = command.run()
|
|
|
|
chart = db.session.query(Slice).get(chart.id)
|
|
|
|
assert chart.viz_type == "new_viz_type"
|
|
|
|
json_params = json.loads(chart.params)
|
|
|
|
assert json_params == {"viz_type": "new_viz_type"}
|
|
|
|
assert chart.slice_name == "new chart"
|
2022-07-07 14:04:27 -04:00
|
|
|
assert chart.owners == [user]
|
2022-03-02 00:44:36 -05:00
|
|
|
db.session.delete(chart)
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
|
2021-08-10 12:29:49 -04:00
|
|
|
class TestChartsUpdateCommand(SupersetTestCase):
|
2022-07-07 14:04:27 -04:00
|
|
|
@patch("superset.charts.commands.update.g")
|
|
|
|
@patch("superset.utils.core.g")
|
2021-08-10 12:29:49 -04:00
|
|
|
@patch("superset.security.manager.g")
|
|
|
|
@pytest.mark.usefixtures("load_energy_table_with_slice")
|
2022-07-07 14:04:27 -04:00
|
|
|
def test_update_v1_response(self, mock_sm_g, mock_c_g, mock_u_g):
|
2021-09-15 12:30:23 -04:00
|
|
|
"""Test that a chart command updates properties"""
|
2021-08-10 12:29:49 -04:00
|
|
|
pk = db.session.query(Slice).all()[0].id
|
2022-07-07 14:04:27 -04:00
|
|
|
user = security_manager.find_user(username="admin")
|
|
|
|
mock_u_g.user = mock_c_g.user = mock_sm_g.user = user
|
2021-08-10 12:29:49 -04:00
|
|
|
model_id = pk
|
|
|
|
json_obj = {
|
|
|
|
"description": "test for update",
|
|
|
|
"cache_timeout": None,
|
2022-07-07 14:04:27 -04:00
|
|
|
"owners": [user.id],
|
2021-08-10 12:29:49 -04:00
|
|
|
}
|
2022-07-07 14:04:27 -04:00
|
|
|
command = UpdateChartCommand(model_id, json_obj)
|
2021-08-10 12:29:49 -04:00
|
|
|
last_saved_before = db.session.query(Slice).get(pk).last_saved_at
|
|
|
|
command.run()
|
|
|
|
chart = db.session.query(Slice).get(pk)
|
|
|
|
assert chart.last_saved_at != last_saved_before
|
2022-07-07 14:04:27 -04:00
|
|
|
assert chart.last_saved_by == user
|
2021-08-24 11:37:34 -04:00
|
|
|
|
2022-07-07 14:04:27 -04:00
|
|
|
@patch("superset.utils.core.g")
|
2021-08-24 11:37:34 -04:00
|
|
|
@patch("superset.security.manager.g")
|
|
|
|
@pytest.mark.usefixtures("load_energy_table_with_slice")
|
|
|
|
def test_query_context_update_command(self, mock_sm_g, mock_g):
|
2021-09-15 15:27:02 -04:00
|
|
|
"""
|
2021-08-24 11:37:34 -04:00
|
|
|
Test that a user can generate the chart query context
|
2023-04-03 13:29:02 -04:00
|
|
|
payload without affecting owners
|
2021-08-24 11:37:34 -04:00
|
|
|
"""
|
|
|
|
chart = db.session.query(Slice).all()[0]
|
|
|
|
pk = chart.id
|
|
|
|
admin = security_manager.find_user(username="admin")
|
|
|
|
chart.owners = [admin]
|
|
|
|
db.session.commit()
|
|
|
|
|
2022-07-07 14:04:27 -04:00
|
|
|
user = security_manager.find_user(username="alpha")
|
|
|
|
mock_g.user = mock_sm_g.user = user
|
2021-08-24 11:37:34 -04:00
|
|
|
query_context = json.dumps({"foo": "bar"})
|
|
|
|
json_obj = {
|
|
|
|
"query_context_generation": True,
|
|
|
|
"query_context": query_context,
|
|
|
|
}
|
2022-07-07 14:04:27 -04:00
|
|
|
command = UpdateChartCommand(pk, json_obj)
|
2021-08-24 11:37:34 -04:00
|
|
|
command.run()
|
|
|
|
chart = db.session.query(Slice).get(pk)
|
|
|
|
assert chart.query_context == query_context
|
|
|
|
assert len(chart.owners) == 1
|
|
|
|
assert chart.owners[0] == admin
|
2023-06-20 07:08:29 -04:00
|
|
|
|
|
|
|
|
|
|
|
class TestChartWarmUpCacheCommand(SupersetTestCase):
|
|
|
|
def test_warm_up_cache_command_chart_not_found(self):
|
|
|
|
with self.assertRaises(WarmUpCacheChartNotFoundError):
|
|
|
|
ChartWarmUpCacheCommand(99999, None, None).run()
|
|
|
|
|
|
|
|
@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
|
|
|
|
def test_warm_up_cache(self):
|
|
|
|
slc = self.get_slice("Girls", db.session)
|
|
|
|
result = ChartWarmUpCacheCommand(slc.id, None, None).run()
|
|
|
|
self.assertEqual(
|
|
|
|
result, {"chart_id": slc.id, "viz_error": None, "viz_status": "success"}
|
|
|
|
)
|
|
|
|
|
|
|
|
# can just pass in chart as well
|
|
|
|
result = ChartWarmUpCacheCommand(slc, None, None).run()
|
|
|
|
self.assertEqual(
|
|
|
|
result, {"chart_id": slc.id, "viz_error": None, "viz_status": "success"}
|
|
|
|
)
|