diff --git a/hc/api/tests/test_list_checks.py b/hc/api/tests/test_list_checks.py index 1d7b4a41..db060379 100644 --- a/hc/api/tests/test_list_checks.py +++ b/hc/api/tests/test_list_checks.py @@ -20,6 +20,7 @@ class ListChecksTestCase(BaseTestCase): self.a1.last_ping = self.now self.a1.n_pings = 1 self.a1.status = "new" + self.a1.tags = "a1-tag a1-additional-tag" self.a1.save() self.a2 = Check(user=self.alice, name="Alice 2") @@ -27,6 +28,7 @@ class ListChecksTestCase(BaseTestCase): self.a2.grace = td(seconds=3600) self.a2.last_ping = self.now self.a2.status = "up" + self.a2.tags = "a2-tag" self.a2.save() def get(self): @@ -79,3 +81,45 @@ class ListChecksTestCase(BaseTestCase): self.assertEqual(r.status_code, 200) self.assertContains(r, "Alice") + + def test_it_works_with_tags_param(self): + r = self.client.get("/api/v1/checks/?tag=a2-tag", HTTP_X_API_KEY="abc") + self.assertEqual(r.status_code, 200) + + doc = r.json() + self.assertTrue("checks" in doc) + self.assertEqual(len(doc["checks"]), 1) + + check = doc["checks"][0] + + self.assertEqual(check["name"], "Alice 2") + self.assertEqual(check["tags"], "a2-tag") + + def test_it_filters_with_multiple_tags_param(self): + r = self.client.get("/api/v1/checks/?tag=a1-tag&tag=a1-additional-tag", HTTP_X_API_KEY="abc") + self.assertEqual(r.status_code, 200) + + doc = r.json() + self.assertTrue("checks" in doc) + self.assertEqual(len(doc["checks"]), 1) + + check = doc["checks"][0] + + self.assertEqual(check["name"], "Alice 1") + self.assertEqual(check["tags"], "a1-tag a1-additional-tag") + + def test_it_does_not_match_tag_partially(self): + r = self.client.get("/api/v1/checks/?tag=tag", HTTP_X_API_KEY="abc") + self.assertEqual(r.status_code, 200) + + doc = r.json() + self.assertTrue("checks" in doc) + self.assertEqual(len(doc["checks"]), 0) + + def test_non_existing_tags_filter_returns_empty_result(self): + r = self.client.get("/api/v1/checks/?tag=non_existing_tag_with_no_checks", HTTP_X_API_KEY="abc") + self.assertEqual(r.status_code, 200) + + doc = r.json() + self.assertTrue("checks" in doc) + self.assertEqual(len(doc["checks"]), 0) diff --git a/hc/api/views.py b/hc/api/views.py index d351b867..1f7aa27c 100644 --- a/hc/api/views.py +++ b/hc/api/views.py @@ -104,8 +104,23 @@ def _update(check, spec): @validate_json(schemas.check) def checks(request): if request.method == "GET": + tags = request.GET.getlist('tag', []) q = Check.objects.filter(user=request.user) - doc = {"checks": [check.to_dict() for check in q]} + + doc = {"checks": []} + + if len(tags) > 0: + for tag in tags: + q = q.filter(tags__contains=tag.strip()) + + tags_set = set(tags) + + for check in q: + if tags_set.issubset(set(check.tags_list())): + doc["checks"].append(check.to_dict()) + else: + doc["checks"] = [check.to_dict() for check in q] + return JsonResponse(doc) elif request.method == "POST": diff --git a/templates/front/docs_api.html b/templates/front/docs_api.html index a5c9d39b..af5275e6 100644 --- a/templates/front/docs_api.html +++ b/templates/front/docs_api.html @@ -61,8 +61,8 @@ The response may contain a JSON document with additional data.
- Returns a list of checks. This API call takes no parameters and returns - a JSON document with all checks in user's account. + Returns a list of checks. This API call takes only optional tag querystring parameter to filter checks by their tags. + If no parameter provided it returns a JSON document with all checks in user's account.
curl --header "X-Api-Key: your-api-key" {{ SITE_ROOT }}/api/v1/checks/?tag=bar&tag=baz
+
{
+ "checks": [
+ {
+ "last_ping": null,
+ "ping_url": "{{ PING_ENDPOINT }}9d17c61f-5c4f-4cab-b517-11e6b2679ced",
+ "next_ping": null,
+ "grace": 3600,
+ "name": "Api test 2",
+ "n_pings": 0,
+ "tags": "bar baz",
+ "pause_url": "{{ SITE_ROOT }}/api/v1/checks/9d17c61f-5c4f-4cab-b517-11e6b2679ced/pause",
+ "tz": "UTC",
+ "schedule": "0/10 * * * *",
+ "status": "new",
+ "update_url": "{{ SITE_ROOT }}/api/v1/checks/9d17c61f-5c4f-4cab-b517-11e6b2679ced"
+ }
+ ]
+}
+