@ -0,0 +1,53 @@ | |||||
from django.test.utils import override_settings | |||||
from hc.api.models import Channel | |||||
from hc.test import BaseTestCase | |||||
@override_settings(SHELL_ENABLED=True) | |||||
class AddShellTestCase(BaseTestCase): | |||||
url = "/integrations/add_shell/" | |||||
@override_settings(SHELL_ENABLED=False) | |||||
def test_it_is_disabled_by_default(self): | |||||
self.client.login(username="[email protected]", password="password") | |||||
r = self.client.get(self.url) | |||||
self.assertEqual(r.status_code, 404) | |||||
def test_instructions_work(self): | |||||
self.client.login(username="[email protected]", password="password") | |||||
r = self.client.get(self.url) | |||||
self.assertContains(r, "Executes a local shell command") | |||||
def test_it_adds_two_commands_and_redirects(self): | |||||
form = {"cmd_down": "logger down", "cmd_up": "logger up"} | |||||
self.client.login(username="[email protected]", password="password") | |||||
r = self.client.post(self.url, form) | |||||
self.assertRedirects(r, "/integrations/") | |||||
c = Channel.objects.get() | |||||
self.assertEqual(c.project, self.project) | |||||
self.assertEqual(c.cmd_down, "logger down") | |||||
self.assertEqual(c.cmd_up, "logger up") | |||||
def test_it_adds_webhook_using_team_access(self): | |||||
form = {"cmd_down": "logger down", "cmd_up": "logger up"} | |||||
# Logging in as bob, not alice. Bob has team access so this | |||||
# should work. | |||||
self.client.login(username="[email protected]", password="password") | |||||
self.client.post(self.url, form) | |||||
c = Channel.objects.get() | |||||
self.assertEqual(c.project, self.project) | |||||
self.assertEqual(c.cmd_down, "logger down") | |||||
def test_it_handles_empty_down_command(self): | |||||
form = {"cmd_down": "", "cmd_up": "logger up"} | |||||
self.client.login(username="[email protected]", password="password") | |||||
self.client.post(self.url, form) | |||||
c = Channel.objects.get() | |||||
self.assertEqual(c.cmd_down, "") | |||||
self.assertEqual(c.cmd_up, "logger up") |
@ -96,9 +96,9 @@ class ChannelsTestCase(BaseTestCase): | |||||
self.assertEqual(r.status_code, 200) | self.assertEqual(r.status_code, 200) | ||||
self.assertContains(r, "(up only)") | self.assertContains(r, "(up only)") | ||||
def test_it_shows_sms_label(self): | |||||
def test_it_shows_sms_number(self): | |||||
ch = Channel(kind="sms", project=self.project) | ch = Channel(kind="sms", project=self.project) | ||||
ch.value = json.dumps({"value": "+123", "label": "My Phone"}) | |||||
ch.value = json.dumps({"value": "+123"}) | |||||
ch.save() | ch.save() | ||||
self.client.login(username="[email protected]", password="password") | self.client.login(username="[email protected]", password="password") | ||||
@ -0,0 +1,21 @@ | |||||
from django.test import TestCase | |||||
from hc.lib.string import replace | |||||
class StringTestCase(TestCase): | |||||
def test_it_works(self): | |||||
result = replace("$A is $B", {"$A": "aaa", "$B": "bbb"}) | |||||
self.assertEqual(result, "aaa is bbb") | |||||
def test_it_ignores_placeholders_in_values(self): | |||||
result = replace("$A is $B", {"$A": "$B", "$B": "$A"}) | |||||
self.assertEqual(result, "$B is $A") | |||||
def test_it_ignores_overlapping_placeholders(self): | |||||
result = replace("$$AB", {"$A": "", "$B": "text"}) | |||||
self.assertEqual(result, "$B") | |||||
def test_it_preserves_non_placeholder_dollar_signs(self): | |||||
result = replace("$3.50", {"$A": "text"}) | |||||
self.assertEqual(result, "$3.50") |
@ -0,0 +1,121 @@ | |||||
{% extends "base.html" %} | |||||
{% load compress humanize static hc_extras %} | |||||
{% block title %}Add Shell Command - {% site_name %}{% endblock %} | |||||
{% block content %} | |||||
<div class="row"> | |||||
<div class="col-sm-12"> | |||||
<h1>Shell Command</h1> | |||||
<p>Executes a local shell command when a check | |||||
goes up or down.</p> | |||||
<p> | |||||
You can use placeholders <strong>$NAME</strong>, <strong>$STATUS</strong> | |||||
and others | |||||
<a href="#" data-toggle="modal" data-target="#reference-modal">(quick reference)</a>. | |||||
</p> | |||||
<br /> | |||||
<form id="add-shell-form" method="post"> | |||||
{% csrf_token %} | |||||
<div class="row"> | |||||
<div class="col-sm-6"> | |||||
<div class="form-group {{ form.cmd_down.css_classes }}"> | |||||
<label class="control-label">Execute when a check goes <span class="label-down">down</span></label> | |||||
<textarea | |||||
class="form-control" | |||||
rows="3" | |||||
name="cmd_down" | |||||
placeholder='/home/user/notify.sh "$NAME has gone down"'>{{ form.cmd_down.value|default:"" }}</textarea> | |||||
{% if form.cmd_down.errors %} | |||||
<div class="help-block"> | |||||
{{ form.cmd_down.errors|join:"" }} | |||||
</div> | |||||
{% endif %} | |||||
</div> | |||||
</div> | |||||
<div class="col-sm-6"> | |||||
<div class="form-group {{ form.cmd_up.css_classes }}"> | |||||
<label class="control-label">Execute when a check goes <span class="label-up">up</span></label> | |||||
<textarea | |||||
class="form-control" | |||||
rows="3" | |||||
name="cmd_up" | |||||
placeholder='/home/user/notify.sh "$NAME is back up"'>{{ form.cmd_up.value|default:"" }}</textarea> | |||||
{% if form.cmd_up.errors %} | |||||
<div class="help-block"> | |||||
{{ form.cmd_up.errors|join:"" }} | |||||
</div> | |||||
{% endif %} | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="form-group" class="clearfix"> | |||||
<br> | |||||
<br> | |||||
<div class="text-right"> | |||||
<button type="submit" class="btn btn-primary">Save Integration</button> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
<div id="reference-modal" class="modal"> | |||||
<div class="modal-dialog"> | |||||
<div class="modal-content"> | |||||
<div class="modal-header"> | |||||
<h4>Supported Placeholders</h4> | |||||
</div> | |||||
<div class="modal-body"> | |||||
<p> | |||||
You can use the below placeholders in the command. | |||||
{% site_name %} will replace the placeholders | |||||
with the correct values. | |||||
</p> | |||||
<table id="webhook-variables" class="table modal-body"> | |||||
<tr> | |||||
<th><code>$CODE</code></th> | |||||
<td>The UUID code of the check</td> | |||||
</tr> | |||||
<tr> | |||||
<th><code>$NAME</code></th> | |||||
<td>Name of the check</td> | |||||
</tr> | |||||
<tr> | |||||
<th><code>$NOW</code></th> | |||||
<td> | |||||
Current UTC time in ISO8601 format.<br /> | |||||
Example: "{{ now }}" | |||||
</td> | |||||
</tr> | |||||
<tr> | |||||
<th><code>$STATUS</code></th> | |||||
<td>Check's current status ("up" or "down")</td> | |||||
</tr> | |||||
<tr> | |||||
<th><code>$TAGS</code></th> | |||||
<td>Check's tags, separated by spaces</td> | |||||
</tr> | |||||
<tr> | |||||
<th><code>$TAG1, $TAG2, …</code></th> | |||||
<td>Value of the first tag, the second tag, …</td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
<div class="modal-footer"> | |||||
<button type="button" class="btn btn-default" data-dismiss="modal">Got It!</button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{% endblock %} |