diff --git a/rd_ui/app/scripts/controllers/alerts.js b/rd_ui/app/scripts/controllers/alerts.js index 342792785..c444e388e 100644 --- a/rd_ui/app/scripts/controllers/alerts.js +++ b/rd_ui/app/scripts/controllers/alerts.js @@ -67,10 +67,12 @@ if ($scope.alertId === "new") { $scope.alert = new Alert({options: {}}); + $scope.canEdit = true; } else { $scope.alert = Alert.get({id: $scope.alertId}, function(alert) { $scope.onQuerySelected(new Query($scope.alert.query)); }); + $scope.canEdit = currentUser.canEdit($scope.alert); } $scope.ops = ['greater than', 'less than', 'equals']; @@ -110,6 +112,15 @@ }); }; + $scope.delete = function() { + $scope.alert.$delete(function() { + $location.path('/alerts'); + growl.addSuccessMessage("Alert deleted."); + }, function() { + growl.addErrorMessage("Failed deleting alert."); + }); + } + }; angular.module('redash.directives').directive('alertSubscriptions', ['$q', '$sce', 'AlertSubscription', 'Destination', 'growl', function ($q, $sce, AlertSubscription, Destination, growl) { diff --git a/rd_ui/app/views/alerts/edit.html b/rd_ui/app/views/alerts/edit.html index 79b439a25..fbc6c5021 100644 --- a/rd_ui/app/views/alerts/edit.html +++ b/rd_ui/app/views/alerts/edit.html @@ -7,10 +7,10 @@
-
+
- + {{$select.selected.name}} - +
@@ -30,7 +30,7 @@
+ class="form-control" ng-disabled="!canEdit">
@@ -40,24 +40,25 @@
- +
-
- +
-
- +
+ +
diff --git a/redash/handlers/alerts.py b/redash/handlers/alerts.py index 8b066d11a..714dc8f73 100644 --- a/redash/handlers/alerts.py +++ b/redash/handlers/alerts.py @@ -34,6 +34,11 @@ class AlertResource(BaseResource): return alert.to_dict() + def delete(self, alert_id): + alert = get_object_or_404(models.Alert.get_by_id_and_org, alert_id, self.current_org) + require_admin_or_owner(alert.user.id) + alert.delete_instance(recursive=True) + class AlertListResource(BaseResource): def post(self): diff --git a/tests/factories.py b/tests/factories.py index c91c58429..b6d7cf305 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -187,7 +187,8 @@ class Factory(object): def create_alert_subscription(self, **kwargs): args = { - 'user': self.user + 'user': self.user, + 'alert': self.create_alert() } args.update(**kwargs) diff --git a/tests/handlers/test_alerts.py b/tests/handlers/test_alerts.py index 46c10e310..0053fbc10 100644 --- a/tests/handlers/test_alerts.py +++ b/tests/handlers/test_alerts.py @@ -1,8 +1,5 @@ from tests import BaseTestCase -from tests.factories import org_factory -from tests.handlers import authenticated_user, json_request -from redash.wsgi import app -from redash.models import AlertSubscription +from redash.models import AlertSubscription, Alert class TestAlertResourceGet(BaseTestCase): @@ -30,6 +27,36 @@ class TestAlertResourceGet(BaseTestCase): self.assertEqual(rv.status_code, 404) +class TestAlertResourceDelete(BaseTestCase): + def test_removes_alert_and_subscriptions(self): + subscription = self.factory.create_alert_subscription() + alert = subscription.alert + + rv = self.make_request('delete', "/api/alerts/{}".format(alert.id)) + self.assertEqual(rv.status_code, 200) + + self.assertRaises(Alert.DoesNotExist, Alert.get_by_id, subscription.alert.id) + self.assertRaises(AlertSubscription.DoesNotExist, AlertSubscription.get_by_id, subscription.id) + + def test_returns_403_if_not_allowed(self): + alert = self.factory.create_alert() + + user = self.factory.create_user() + rv = self.make_request('delete', "/api/alerts/{}".format(alert.id), user=user) + self.assertEqual(rv.status_code, 403) + + rv = self.make_request('delete', "/api/alerts/{}".format(alert.id), user=self.factory.create_admin()) + self.assertEqual(rv.status_code, 200) + + def test_returns_404_for_unauthorized_users(self): + alert = self.factory.create_alert() + + second_org = self.factory.create_org() + second_org_admin = self.factory.create_admin(org=second_org) + rv = self.make_request('delete', "/api/alerts/{}".format(alert.id), user=second_org_admin) + self.assertEqual(rv.status_code, 404) + + class TestAlertListPost(BaseTestCase): def test_returns_200_if_has_access_to_query(self): query = self.factory.create_query()