From 05db43f95d468ac1747fd97dbd3a73b9f04b525e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C4=93teris=20Caune?= Date: Mon, 15 Mar 2021 12:52:35 +0200 Subject: [PATCH] Fix the pause action to clear Profile.next_nag_date if all checks up --- CHANGELOG.md | 1 + hc/api/tests/test_pause.py | 51 +++++++++++++++++++++--------------- hc/api/views.py | 5 ++++ hc/front/tests/test_pause.py | 11 ++++++++ hc/front/views.py | 4 +++ 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9131aab..6eacadb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file. - Fix downtime summary to handle months when the check didn't exist yet (#472) - Relax cron expression validation: accept all expressions that croniter accepts - Fix sendalerts to clear Profile.next_nag_date if all checks up +- Fix the pause action to clear Profile.next_nag_date if all checks up ## v1.19.0 - 2021-02-03 diff --git a/hc/api/tests/test_pause.py b/hc/api/tests/test_pause.py index eafbbe4c..4f7e8f58 100644 --- a/hc/api/tests/test_pause.py +++ b/hc/api/tests/test_pause.py @@ -6,31 +6,30 @@ from hc.test import BaseTestCase class PauseTestCase(BaseTestCase): - def test_it_works(self): - check = Check.objects.create(project=self.project, status="up") + def setUp(self): + super().setUp() - url = "/api/v1/checks/%s/pause" % check.code + self.check = Check.objects.create(project=self.project, status="up") + self.url = f"/api/v1/checks/{self.check.code}/pause" + + def test_it_works(self): r = self.client.post( - url, "", content_type="application/json", HTTP_X_API_KEY="X" * 32 + self.url, "", content_type="application/json", HTTP_X_API_KEY="X" * 32 ) self.assertEqual(r.status_code, 200) self.assertEqual(r["Access-Control-Allow-Origin"], "*") - check.refresh_from_db() - self.assertEqual(check.status, "paused") + self.check.refresh_from_db() + self.assertEqual(self.check.status, "paused") def test_it_handles_options(self): - check = Check.objects.create(project=self.project, status="up") - - r = self.client.options("/api/v1/checks/%s/pause" % check.code) + r = self.client.options(self.url) self.assertEqual(r.status_code, 204) self.assertIn("POST", r["Access-Control-Allow-Methods"]) def test_it_only_allows_post(self): - url = "/api/v1/checks/1659718b-21ad-4ed1-8740-43afc6c41524/pause" - - r = self.client.get(url, HTTP_X_API_KEY="X" * 32) + r = self.client.get(self.url, HTTP_X_API_KEY="X" * 32) self.assertEqual(r.status_code, 405) def test_it_validates_ownership(self): @@ -60,19 +59,29 @@ class PauseTestCase(BaseTestCase): self.assertEqual(r.status_code, 404) def test_it_clears_last_start_alert_after(self): - check = Check(project=self.project, status="up") - check.last_start = now() - check.alert_after = check.last_start + td(hours=1) - check.save() + self.check.last_start = now() + self.check.alert_after = self.check.last_start + td(hours=1) + self.check.save() - url = "/api/v1/checks/%s/pause" % check.code r = self.client.post( - url, "", content_type="application/json", HTTP_X_API_KEY="X" * 32 + self.url, "", content_type="application/json", HTTP_X_API_KEY="X" * 32 ) self.assertEqual(r.status_code, 200) self.assertEqual(r["Access-Control-Allow-Origin"], "*") - check.refresh_from_db() - self.assertEqual(check.last_start, None) - self.assertEqual(check.alert_after, None) + self.check.refresh_from_db() + self.assertEqual(self.check.last_start, None) + self.assertEqual(self.check.alert_after, None) + + def test_it_clears_next_nag_date(self): + self.profile.nag_period = td(hours=1) + self.profile.next_nag_date = now() + td(minutes=30) + self.profile.save() + + self.client.post( + self.url, "", content_type="application/json", HTTP_X_API_KEY="X" * 32 + ) + + self.profile.refresh_from_db() + self.assertIsNone(self.profile.next_nag_date) diff --git a/hc/api/views.py b/hc/api/views.py index fbe68b82..d4831549 100644 --- a/hc/api/views.py +++ b/hc/api/views.py @@ -293,6 +293,11 @@ def pause(request, code): check.last_start = None check.alert_after = None check.save() + + # After pausing a check we must check if all checks are up, + # and Profile.next_nag_date needs to be cleared out: + check.project.update_next_nag_dates() + return JsonResponse(check.to_dict()) diff --git a/hc/front/tests/test_pause.py b/hc/front/tests/test_pause.py index 73d7593a..394f3cb1 100644 --- a/hc/front/tests/test_pause.py +++ b/hc/front/tests/test_pause.py @@ -54,3 +54,14 @@ class PauseTestCase(BaseTestCase): self.client.login(username="bob@example.org", password="password") r = self.client.post(self.url) self.assertEqual(r.status_code, 403) + + def test_it_clears_next_nag_date(self): + self.profile.nag_period = td(hours=1) + self.profile.next_nag_date = now() + td(minutes=30) + self.profile.save() + + self.client.login(username="alice@example.org", password="password") + self.client.post(self.url) + + self.profile.refresh_from_db() + self.assertIsNone(self.profile.next_nag_date) diff --git a/hc/front/views.py b/hc/front/views.py index cce79c4f..374f110a 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -535,6 +535,10 @@ def pause(request, code): check.alert_after = None check.save() + # After pausing a check we must check if all checks are up, + # and Profile.next_nag_date needs to be cleared out: + check.project.update_next_nag_dates() + # Don't redirect after an AJAX request: if request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest": return HttpResponse()