fix: Support metric currency as dict during import (#34080)

This commit is contained in:
Vitor Avila
2025-07-07 14:00:56 -03:00
committed by GitHub
parent f55476034b
commit 733f112142
7 changed files with 229 additions and 320 deletions

View File

@@ -16,6 +16,7 @@
# under the License.
from __future__ import annotations
import copy
import unittest
from datetime import timedelta
from io import BytesIO
@@ -61,9 +62,7 @@ from tests.integration_tests.fixtures.energy_dashboard import (
)
from tests.integration_tests.fixtures.importexport import (
database_config,
database_metadata_config,
dataset_config,
dataset_metadata_config,
dataset_ui_export,
)
@@ -79,7 +78,7 @@ class TestDatasetApi(SupersetTestCase):
def tearDown(self):
for item in self.items_to_delete:
db.session.delete(item)
db.session.commit()
db.session.commit()
super().tearDown()
@staticmethod
@@ -193,22 +192,6 @@ class TestDatasetApi(SupersetTestCase):
.one()
)
def create_dataset_import(self) -> BytesIO:
buf = BytesIO()
with ZipFile(buf, "w") as bundle:
with bundle.open("dataset_export/metadata.yaml", "w") as fp:
fp.write(yaml.safe_dump(dataset_metadata_config).encode())
with bundle.open(
"dataset_export/databases/imported_database.yaml", "w"
) as fp:
fp.write(yaml.safe_dump(database_config).encode())
with bundle.open(
"dataset_export/datasets/imported_dataset.yaml", "w"
) as fp:
fp.write(yaml.safe_dump(dataset_config).encode())
buf.seek(0)
return buf
@pytest.mark.usefixtures("load_energy_table_with_slice")
def test_user_gets_all_datasets(self):
# test filtering on datasource_name
@@ -2437,7 +2420,7 @@ class TestDatasetApi(SupersetTestCase):
self.login(ADMIN_USERNAME)
uri = "api/v1/dataset/import/"
buf = self.create_dataset_import()
buf = self.create_import_v1_zip_file("dataset")
form_data = {
"formData": (buf, "dataset_export.zip"),
"sync_columns": "true",
@@ -2460,10 +2443,7 @@ class TestDatasetApi(SupersetTestCase):
assert dataset.table_name == "imported_dataset"
assert str(dataset.uuid) == dataset_config["uuid"]
db.session.delete(dataset)
db.session.commit()
db.session.delete(database)
db.session.commit()
self.items_to_delete = [dataset, database]
def test_import_dataset_v0_export(self):
num_datasets = db.session.query(SqlaTable).count()
@@ -2500,7 +2480,7 @@ class TestDatasetApi(SupersetTestCase):
self.login(ADMIN_USERNAME)
uri = "api/v1/dataset/import/"
buf = self.create_dataset_import()
buf = self.create_import_v1_zip_file("dataset")
form_data = {
"formData": (buf, "dataset_export.zip"),
}
@@ -2511,7 +2491,7 @@ class TestDatasetApi(SupersetTestCase):
assert response == {"message": "OK"}
# import again without overwrite flag
buf = self.create_dataset_import()
buf = self.create_import_v1_zip_file("dataset")
form_data = {
"formData": (buf, "dataset_export.zip"),
}
@@ -2526,7 +2506,7 @@ class TestDatasetApi(SupersetTestCase):
"error_type": "GENERIC_COMMAND_ERROR",
"level": "warning",
"extra": {
"datasets/imported_dataset.yaml": "Dataset already exists and `overwrite=true` was not passed", # noqa: E501
"datasets/dataset.yaml": "Dataset already exists and `overwrite=true` was not passed", # noqa: E501
"issue_codes": [
{
"code": 1010,
@@ -2539,7 +2519,7 @@ class TestDatasetApi(SupersetTestCase):
}
# import with overwrite flag
buf = self.create_dataset_import()
buf = self.create_import_v1_zip_file("dataset")
form_data = {
"formData": (buf, "dataset_export.zip"),
"overwrite": "true",
@@ -2556,10 +2536,7 @@ class TestDatasetApi(SupersetTestCase):
)
dataset = database.tables[0]
db.session.delete(dataset)
db.session.commit()
db.session.delete(database)
db.session.commit()
self.items_to_delete = [dataset, database]
def test_import_dataset_invalid(self):
"""
@@ -2569,20 +2546,7 @@ class TestDatasetApi(SupersetTestCase):
self.login(ADMIN_USERNAME)
uri = "api/v1/dataset/import/"
buf = BytesIO()
with ZipFile(buf, "w") as bundle:
with bundle.open("dataset_export/metadata.yaml", "w") as fp:
fp.write(yaml.safe_dump(database_metadata_config).encode())
with bundle.open(
"dataset_export/databases/imported_database.yaml", "w"
) as fp:
fp.write(yaml.safe_dump(database_config).encode())
with bundle.open(
"dataset_export/datasets/imported_dataset.yaml", "w"
) as fp:
fp.write(yaml.safe_dump(dataset_config).encode())
buf.seek(0)
buf = self.create_import_v1_zip_file("database", datasets=[dataset_config])
form_data = {
"formData": (buf, "dataset_export.zip"),
}
@@ -2657,6 +2621,67 @@ class TestDatasetApi(SupersetTestCase):
]
}
def test_import_dataset_currency_config(self):
"""
Dataset API: Test import metric with currency config.
This test confirms that importing a metric with a currency config
set as either string (for backwards compatibility) or dict works properly.
"""
self.login(ADMIN_USERNAME)
uri = "api/v1/dataset/import/"
dataset_with_currency = copy.deepcopy(dataset_config)
dataset_with_currency["metrics"][0]["currency"] = {
"symbol": "USD",
"symbolPosition": "left",
}
dataset_with_currency["metrics"].append(
{
"metric_name": "count_new",
"verbose_name": "",
"metric_type": None,
"expression": "count(1)",
"description": None,
"d3format": None,
"extra": {},
"warning_text": None,
"currency": '{"symbol": "EUR","symbolPosition": "left"}',
}
)
buf = self.create_import_v1_zip_file(
"dataset", datasets=[dataset_with_currency]
)
form_data = {
"formData": (buf, "dataset_export.zip"),
}
rv = self.client.post(uri, data=form_data, content_type="multipart/form-data")
response = json.loads(rv.data.decode("utf-8"))
assert rv.status_code == 200
assert response == {"message": "OK"}
database = (
db.session.query(Database).filter_by(uuid=database_config["uuid"]).one()
)
assert database.database_name == database_config["database_name"]
assert len(database.tables) == 1
assert len(database.tables[0].metrics) == 2
final_metrics = []
for metric in database.tables[0].metrics:
final_metrics.append(metric.currency)
assert final_metrics == [
{"symbol": "USD", "symbolPosition": "left"},
{"symbol": "EUR", "symbolPosition": "left"},
]
dataset = database.tables[0]
assert dataset.table_name == dataset_with_currency["table_name"]
assert str(dataset.uuid) == dataset_with_currency["uuid"]
self.items_to_delete = [dataset, database]
@pytest.mark.usefixtures("create_datasets")
def test_get_datasets_is_certified_filter(self):
"""