mirror of
https://github.com/apache/superset.git
synced 2026-04-20 08:34:37 +00:00
fix(report): fix last_eval_dttm sort and more tests (#12121)
* fix(report): fix last_eval_dttm sort and more tests * remove unnecessary permissions and split code path * remove SIP_34_ALERTS_UI * disabling an alert that is working will turn it to not triggered
This commit is contained in:
committed by
GitHub
parent
17769ca96e
commit
8d5dcc5784
@@ -341,7 +341,7 @@ def test_deliver_alert_screenshot(
|
||||
|
||||
# TODO: fix AlertModelView.show url call from test
|
||||
url_mock.side_effect = [
|
||||
f"http://0.0.0.0:8080/alert/show/{alert.id}",
|
||||
f"http://0.0.0.0:8080/alerts/show/{alert.id}",
|
||||
f"http://0.0.0.0:8080/superset/slice/{alert.slice_id}/",
|
||||
]
|
||||
|
||||
@@ -354,7 +354,7 @@ def test_deliver_alert_screenshot(
|
||||
f"*Query*:```{alert.sql}```\n"
|
||||
f"*Result*: {alert.observations[-1].value}\n"
|
||||
f"*Reason*: {alert.observations[-1].value} {alert.pretty_config}\n"
|
||||
f"<http://0.0.0.0:8080/alert/show/{alert.id}"
|
||||
f"<http://0.0.0.0:8080/alerts/show/{alert.id}"
|
||||
f"|View Alert Details>\n<http://0.0.0.0:8080/superset/slice/{alert.slice_id}/"
|
||||
"|*Explore in Superset*>",
|
||||
"title": f"[Alert] {alert.label}",
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
# isort:skip_file
|
||||
"""Unit tests for Superset"""
|
||||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
import json
|
||||
|
||||
from flask_appbuilder.security.sqla.models import User
|
||||
import pytest
|
||||
import prison
|
||||
from sqlalchemy.sql import func
|
||||
@@ -48,6 +46,32 @@ REPORTS_COUNT = 10
|
||||
|
||||
|
||||
class TestReportSchedulesApi(SupersetTestCase):
|
||||
@pytest.fixture()
|
||||
def create_working_report_schedule(self):
|
||||
with self.create_app().app_context():
|
||||
|
||||
admin_user = self.get_user("admin")
|
||||
alpha_user = self.get_user("alpha")
|
||||
chart = db.session.query(Slice).first()
|
||||
example_db = get_example_database()
|
||||
|
||||
report_schedule = insert_report_schedule(
|
||||
type=ReportScheduleType.ALERT,
|
||||
name=f"name_working",
|
||||
crontab=f"* * * * *",
|
||||
sql=f"SELECT value from table",
|
||||
description=f"Report working",
|
||||
chart=chart,
|
||||
database=example_db,
|
||||
owners=[admin_user, alpha_user],
|
||||
last_state=ReportState.WORKING,
|
||||
)
|
||||
|
||||
yield
|
||||
|
||||
db.session.delete(report_schedule)
|
||||
db.session.commit()
|
||||
|
||||
@pytest.fixture()
|
||||
def create_report_schedules(self):
|
||||
with self.create_app().app_context():
|
||||
@@ -260,8 +284,11 @@ class TestReportSchedulesApi(SupersetTestCase):
|
||||
"changed_on",
|
||||
"changed_on_delta_humanized",
|
||||
"created_on",
|
||||
"crontab",
|
||||
"last_eval_dttm",
|
||||
"name",
|
||||
"type",
|
||||
"crontab_humanized",
|
||||
]
|
||||
|
||||
for order_column in order_columns:
|
||||
@@ -578,6 +605,29 @@ class TestReportSchedulesApi(SupersetTestCase):
|
||||
assert updated_model.chart_id == report_schedule_data["chart"]
|
||||
assert updated_model.database_id == report_schedule_data["database"]
|
||||
|
||||
@pytest.mark.usefixtures("create_working_report_schedule")
|
||||
def test_update_report_schedule_state_working(self):
|
||||
"""
|
||||
ReportSchedule Api: Test update state in a working report
|
||||
"""
|
||||
report_schedule = (
|
||||
db.session.query(ReportSchedule)
|
||||
.filter(ReportSchedule.name == "name_working")
|
||||
.one_or_none()
|
||||
)
|
||||
|
||||
self.login(username="admin")
|
||||
report_schedule_data = {"active": False}
|
||||
uri = f"api/v1/report/{report_schedule.id}"
|
||||
rv = self.client.put(uri, json=report_schedule_data)
|
||||
assert rv.status_code == 200
|
||||
report_schedule = (
|
||||
db.session.query(ReportSchedule)
|
||||
.filter(ReportSchedule.name == "name_working")
|
||||
.one_or_none()
|
||||
)
|
||||
assert report_schedule.last_state == ReportState.NOOP
|
||||
|
||||
@pytest.mark.usefixtures("create_report_schedules")
|
||||
def test_update_report_schedule_uniqueness(self):
|
||||
"""
|
||||
@@ -864,12 +914,15 @@ class TestReportSchedulesApi(SupersetTestCase):
|
||||
"error_message",
|
||||
"end_dttm",
|
||||
"start_dttm",
|
||||
"scheduled_dttm",
|
||||
]
|
||||
|
||||
for order_column in order_columns:
|
||||
arguments = {"order_column": order_column, "order_direction": "asc"}
|
||||
uri = f"api/v1/report/{report_schedule.id}/log/?q={prison.dumps(arguments)}"
|
||||
rv = self.get_assert_metric(uri, "get_list")
|
||||
if rv.status_code == 400:
|
||||
raise Exception(json.loads(rv.data.decode("utf-8")))
|
||||
assert rv.status_code == 200
|
||||
|
||||
@pytest.mark.usefixtures("create_report_schedules")
|
||||
|
||||
@@ -38,6 +38,8 @@ from superset.models.reports import (
|
||||
)
|
||||
from superset.models.slice import Slice
|
||||
from superset.reports.commands.exceptions import (
|
||||
AlertQueryError,
|
||||
AlertQueryInvalidTypeError,
|
||||
AlertQueryMultipleColumnsError,
|
||||
AlertQueryMultipleRowsError,
|
||||
ReportScheduleNotFoundError,
|
||||
@@ -397,6 +399,41 @@ def create_mul_alert_email_chart(request):
|
||||
cleanup_report_schedule(report_schedule)
|
||||
|
||||
|
||||
@pytest.yield_fixture(params=["alert1", "alert2"])
|
||||
def create_invalid_sql_alert_email_chart(request):
|
||||
param_config = {
|
||||
"alert1": {
|
||||
"sql": "SELECT 'string' ",
|
||||
"validator_type": ReportScheduleValidatorType.OPERATOR,
|
||||
"validator_config_json": '{"op": "<", "threshold": 10}',
|
||||
},
|
||||
"alert2": {
|
||||
"sql": "SELECT first from foo_table",
|
||||
"validator_type": ReportScheduleValidatorType.OPERATOR,
|
||||
"validator_config_json": '{"op": "<", "threshold": 10}',
|
||||
},
|
||||
}
|
||||
with app.app_context():
|
||||
chart = db.session.query(Slice).first()
|
||||
example_database = get_example_database()
|
||||
with create_test_table_context(example_database):
|
||||
|
||||
report_schedule = create_report_notification(
|
||||
email_target="target@email.com",
|
||||
chart=chart,
|
||||
report_type=ReportScheduleType.ALERT,
|
||||
database=example_database,
|
||||
sql=param_config[request.param]["sql"],
|
||||
validator_type=param_config[request.param]["validator_type"],
|
||||
validator_config_json=param_config[request.param][
|
||||
"validator_config_json"
|
||||
],
|
||||
)
|
||||
yield report_schedule
|
||||
|
||||
cleanup_report_schedule(report_schedule)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("create_report_email_chart")
|
||||
@patch("superset.reports.notifications.email.send_email_smtp")
|
||||
@patch("superset.utils.screenshots.ChartScreenshot.compute_and_cache")
|
||||
@@ -652,3 +689,15 @@ def test_email_mul_alert(create_mul_alert_email_chart):
|
||||
AsyncExecuteReportScheduleCommand(
|
||||
create_mul_alert_email_chart.id, datetime.utcnow()
|
||||
).run()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("create_invalid_sql_alert_email_chart")
|
||||
def test_invalid_sql_alert(create_invalid_sql_alert_email_chart):
|
||||
"""
|
||||
ExecuteReport Command: Test alert with invalid SQL statements
|
||||
"""
|
||||
with freeze_time("2020-01-01T00:00:00Z"):
|
||||
with pytest.raises((AlertQueryError, AlertQueryInvalidTypeError)):
|
||||
AsyncExecuteReportScheduleCommand(
|
||||
create_invalid_sql_alert_email_chart.id, datetime.utcnow()
|
||||
).run()
|
||||
|
||||
@@ -22,7 +22,12 @@ from flask_appbuilder.security.sqla.models import User
|
||||
from superset import db
|
||||
from superset.models.core import Database
|
||||
from superset.models.dashboard import Dashboard
|
||||
from superset.models.reports import ReportExecutionLog, ReportRecipients, ReportSchedule
|
||||
from superset.models.reports import (
|
||||
ReportExecutionLog,
|
||||
ReportRecipients,
|
||||
ReportSchedule,
|
||||
ReportState,
|
||||
)
|
||||
from superset.models.slice import Slice
|
||||
|
||||
|
||||
@@ -39,6 +44,7 @@ def insert_report_schedule(
|
||||
validator_type: Optional[str] = None,
|
||||
validator_config_json: Optional[str] = None,
|
||||
log_retention: Optional[int] = None,
|
||||
last_state: Optional[ReportState] = None,
|
||||
grace_period: Optional[int] = None,
|
||||
recipients: Optional[List[ReportRecipients]] = None,
|
||||
logs: Optional[List[ReportExecutionLog]] = None,
|
||||
@@ -46,6 +52,7 @@ def insert_report_schedule(
|
||||
owners = owners or []
|
||||
recipients = recipients or []
|
||||
logs = logs or []
|
||||
last_state = last_state or ReportState.NOOP
|
||||
report_schedule = ReportSchedule(
|
||||
type=type,
|
||||
name=name,
|
||||
@@ -62,6 +69,7 @@ def insert_report_schedule(
|
||||
grace_period=grace_period,
|
||||
recipients=recipients,
|
||||
logs=logs,
|
||||
last_state=last_state,
|
||||
)
|
||||
db.session.add(report_schedule)
|
||||
db.session.commit()
|
||||
|
||||
Reference in New Issue
Block a user