Browse Source

Fix a crash when adding an integration for an empty Trello account

pull/474/head
Pēteris Caune 4 years ago
parent
commit
ae976a38b6
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
7 changed files with 65 additions and 22 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +10
    -0
      hc/front/forms.py
  3. +18
    -9
      hc/front/tests/test_add_trello.py
  4. +9
    -0
      hc/front/tests/test_trello_settings.py
  5. +10
    -3
      hc/front/views.py
  6. +3
    -6
      static/js/add_trello.js
  7. +14
    -4
      templates/integrations/trello_settings.html

+ 1
- 0
CHANGELOG.md View File

@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
## Bug Fixes
- Fix unwanted HTML escaping in SMS and WhatsApp notifications
- Fix a crash when adding an integration for an empty Trello account
## v1.18.0 - 2020-12-09


+ 10
- 0
hc/front/forms.py View File

@ -280,3 +280,13 @@ class AddZulipForm(forms.Form):
def get_value(self):
return json.dumps(dict(self.cleaned_data), sort_keys=True)
class AddTrelloForm(forms.Form):
token = forms.RegexField(regex=r"^[0-9a-fA-F]{64}$")
board_name = forms.CharField(max_length=100)
list_name = forms.CharField(max_length=100)
list_id = forms.RegexField(regex=r"^[0-9a-fA-F]{16,32}$")
def get_value(self):
return json.dumps(dict(self.cleaned_data), sort_keys=True)

+ 18
- 9
hc/front/tests/test_add_trello.py View File

@ -18,14 +18,10 @@ class AddTrelloTestCase(BaseTestCase):
def test_it_works(self):
form = {
"settings": json.dumps(
{
"token": "fake-token",
"board_name": "My Board",
"list_name": "My List",
"list_id": "fake-list-id",
}
)
"token": "0" * 64,
"board_name": "My Board",
"list_name": "My List",
"list_id": "1" * 32,
}
self.client.login(username="[email protected]", password="password")
@ -34,7 +30,7 @@ class AddTrelloTestCase(BaseTestCase):
c = Channel.objects.get()
self.assertEqual(c.kind, "trello")
self.assertEqual(c.trello_token, "fake-token")
self.assertEqual(c.trello_token, "0" * 64)
self.assertEqual(c.project, self.project)
@override_settings(TRELLO_APP_KEY=None)
@ -50,3 +46,16 @@ class AddTrelloTestCase(BaseTestCase):
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url)
self.assertEqual(r.status_code, 403)
def test_it_requires_board_name(self):
self.client.login(username="[email protected]", password="password")
form = {
"token": "0" * 64,
"board_name": "",
"list_name": "My List",
"list_id": "1" * 32,
}
r = self.client.post(self.url, form)
self.assertEqual(r.status_code, 400)

+ 9
- 0
hc/front/tests/test_trello_settings.py View File

@ -24,3 +24,12 @@ class AddTrelloTestCase(BaseTestCase):
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url)
self.assertEqual(r.status_code, 404)
@patch("hc.front.views.requests.get")
def test_it_handles_no_lists(self, mock_get):
mock_get.return_value.json.return_value = []
self.client.login(username="[email protected]", password="password")
r = self.client.post(self.url)
self.assertNotContains(r, "Please select the Trello list")
self.assertContains(r, "Could not find any boards with lists")

+ 10
- 3
hc/front/views.py View File

@ -1661,8 +1661,12 @@ def add_signal(request, code):
def add_trello(request, code):
project = _get_rw_project_for_user(request, code)
if request.method == "POST":
form = forms.AddTrelloForm(request.POST)
if not form.is_valid():
return HttpResponseBadRequest()
channel = Channel(project=project, kind="trello")
channel.value = request.POST["settings"]
channel.value = form.get_value()
channel.save()
channel.assign_all_checks()
@ -1753,14 +1757,17 @@ def trello_settings(request):
{
"key": settings.TRELLO_APP_KEY,
"token": token,
"filter": "open",
"fields": "id,name",
"lists": "open",
"list_fields": "id,name",
}
)
r = requests.get(url)
ctx = {"token": token, "data": r.json()}
boards = requests.get(url).json()
num_lists = sum(len(board["lists"]) for board in boards)
ctx = {"token": token, "boards": boards, "num_lists": num_lists}
return render(request, "integrations/trello_settings.html", ctx)


+ 3
- 6
static/js/add_trello.js View File

@ -1,12 +1,9 @@
$(function() {
function updateSettings() {
var opt = $('#list-selector').find(":selected");
$("#settings").val(JSON.stringify({
"token": $("#settings").data("token"),
"list_id": opt.data("listId"),
"board_name": opt.data("boardName"),
"list_name": opt.data("listName")
}));
$("#board-name").val(opt.data("boardName"));
$("#list-name").val(opt.data("listName"));
$("#list-id").val(opt.data("listId"));
}
var tokenMatch = window.location.hash.match(/token=(\w+)/);


+ 14
- 4
templates/integrations/trello_settings.html View File

@ -1,15 +1,19 @@
<p class="text-success">Authentication successful!</p>
{% if num_lists %}
<p class="alert alert-success">Authentication successful!</p>
<p>Please select the Trello list to post notifications to:</p>
<form method="post" class="form-horizontal">
{% csrf_token %}
<input type="hidden" id="settings" name="settings" data-token="{{ token }}"/>
<input type="hidden" name="token" value="{{ token }}" />
<input id="board-name" type="hidden" name="board_name" value="" />
<input id="list-name" type="hidden" name="list_name" value="" />
<input id="list-id" type="hidden" name="list_id" value="" />
<div class="form-group {{ form.value.css_classes }}">
<label for="list-selector" class="col-sm-3 control-label">Post Notifications to</label>
<div class="col-sm-3">
<select id="list-selector" name="board_list_id" class="form-control">
{% for board in data %}
{% for board in boards %}
<optgroup label="{{ board.name }}">
{% for list in board.lists %}
<option
@ -34,4 +38,10 @@
<button type="submit" class="btn btn-primary">Save Integration</button>
</div>
</div>
</form>
</form>
{% else %}
<p class="alert alert-warning">
Could not find any boards with lists in your Trello account.
Are you logged in the correct Trello account?
</p>
{% endif %}

Loading…
Cancel
Save