@ -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.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.value = json.dumps({"value": "+123", "label": "My Phone"}) | |||
ch.value = json.dumps({"value": "+123"}) | |||
ch.save() | |||
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 %} |