diff --git a/bots/github_detail/fixtures/test_404.json b/bots/github_detail/fixtures/test_404.json new file mode 100644 index 0000000..7a44288 --- /dev/null +++ b/bots/github_detail/fixtures/test_404.json @@ -0,0 +1,11 @@ +{ + "request": { + "api_url": "https://api.github.com/repos/zulip/zulip/issues/0" + }, + "response": {}, + "response-headers": { + "status": 404, + "ok": false, + "content-type": "application/json; charset=utf-8" + } +} diff --git a/bots/github_detail/fixtures/test_issue.json b/bots/github_detail/fixtures/test_issue.json new file mode 100644 index 0000000..bc4b0e6 --- /dev/null +++ b/bots/github_detail/fixtures/test_issue.json @@ -0,0 +1,81 @@ +{ + "request": { + "api_url": "https://api.github.com/repos/zulip/zulip/issues/5365" + }, + "response": { + "url": "https://api.github.com/repos/zulip/zulip/issues/5365", + "repository_url": "https://api.github.com/repos/zulip/zulip", + "labels_url": "https://api.github.com/repos/zulip/zulip/issues/5365/labels{/name}", + "comments_url": "https://api.github.com/repos/zulip/zulip/issues/5365/comments", + "events_url": "https://api.github.com/repos/zulip/zulip/issues/5365/events", + "html_url": "https://github.com/zulip/zulip/issues/5365", + "id": 235630936, + "number": 5365, + "title": "frontend: Enable hot-reloading of CSS in development", + "user": { + "login": "timabbott", + "id": 2746074, + "avatar_url": "https://avatars3.githubusercontent.com/u/2746074?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/timabbott", + "html_url": "https://github.com/timabbott", + "followers_url": "https://api.github.com/users/timabbott/followers", + "following_url": "https://api.github.com/users/timabbott/following{/other_user}", + "gists_url": "https://api.github.com/users/timabbott/gists{/gist_id}", + "starred_url": "https://api.github.com/users/timabbott/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/timabbott/subscriptions", + "organizations_url": "https://api.github.com/users/timabbott/orgs", + "repos_url": "https://api.github.com/users/timabbott/repos", + "events_url": "https://api.github.com/users/timabbott/events{/privacy}", + "received_events_url": "https://api.github.com/users/timabbott/received_events", + "type": "User", + "site_admin": false + }, + "labels": [ + { + "id": 419106932, + "url": "https://api.github.com/repos/zulip/zulip/labels/area:%20tooling", + "name": "area: tooling", + "color": "bfd4f2", + "default": false + }, + { + "id": 265216831, + "url": "https://api.github.com/repos/zulip/zulip/labels/enhancement", + "name": "enhancement", + "color": "84b6eb", + "default": true + }, + { + "id": 265216832, + "url": "https://api.github.com/repos/zulip/zulip/labels/help%20wanted", + "name": "help wanted", + "color": "159818", + "default": true + }, + { + "id": 621149055, + "url": "https://api.github.com/repos/zulip/zulip/labels/priority:%20medium", + "name": "priority: medium", + "color": "5319e7", + "default": false + } + ], + "state": "open", + "locked": false, + "assignee": null, + "assignees": [], + "milestone": null, + "comments": 1, + "created_at": "2017-06-13T17:34:45Z", + "updated_at": "2017-06-13T17:34:46Z", + "closed_at": null, + "body": "There's strong interest among folks working on the frontend in being able to use the hot-reloading feature of webpack for managing our CSS.\r\n\r\nIn order to do this, step 1 is to move our CSS minification pipeline from django-pipeline to Webpack. ", + "closed_by": null + }, + "response-headers": { + "status": 200, + "ok": true, + "content-type": "application/json; charset=utf-8" + } +} diff --git a/bots/github_detail/fixtures/test_pull.json b/bots/github_detail/fixtures/test_pull.json new file mode 100644 index 0000000..9c819c6 --- /dev/null +++ b/bots/github_detail/fixtures/test_pull.json @@ -0,0 +1,66 @@ +{ + "request": { + "api_url": "https://api.github.com/repos/zulip/zulip/issues/5345" + }, + "response": { + "url": "https://api.github.com/repos/zulip/zulip/issues/5345", + "repository_url": "https://api.github.com/repos/zulip/zulip", + "labels_url": "https://api.github.com/repos/zulip/zulip/issues/5345/labels{/name}", + "comments_url": "https://api.github.com/repos/zulip/zulip/issues/5345/comments", + "events_url": "https://api.github.com/repos/zulip/zulip/issues/5345/events", + "html_url": "https://github.com/zulip/zulip/pull/5345", + "id": 235340230, + "number": 5345, + "title": "[WIP] modal: Replace bootstrap modal with custom modal class", + "user": { + "login": "jackrzhang", + "id": 12771126, + "avatar_url": "https://avatars0.githubusercontent.com/u/12771126?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/jackrzhang", + "html_url": "https://github.com/jackrzhang", + "followers_url": "https://api.github.com/users/jackrzhang/followers", + "following_url": "https://api.github.com/users/jackrzhang/following{/other_user}", + "gists_url": "https://api.github.com/users/jackrzhang/gists{/gist_id}", + "starred_url": "https://api.github.com/users/jackrzhang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/jackrzhang/subscriptions", + "organizations_url": "https://api.github.com/users/jackrzhang/orgs", + "repos_url": "https://api.github.com/users/jackrzhang/repos", + "events_url": "https://api.github.com/users/jackrzhang/events{/privacy}", + "received_events_url": "https://api.github.com/users/jackrzhang/received_events", + "type": "User", + "site_admin": false + }, + "labels": [ + { + "id": 561830290, + "url": "https://api.github.com/repos/zulip/zulip/labels/needs%20review", + "name": "needs review", + "color": "fef2c0", + "default": false + } + ], + "state": "open", + "locked": false, + "assignee": null, + "assignees": [], + "milestone": null, + "comments": 3, + "created_at": "2017-06-12T19:27:26Z", + "updated_at": "2017-06-13T18:44:12Z", + "closed_at": null, + "pull_request": { + "url": "https://api.github.com/repos/zulip/zulip/pulls/5345", + "html_url": "https://github.com/zulip/zulip/pull/5345", + "diff_url": "https://github.com/zulip/zulip/pull/5345.diff", + "patch_url": "https://github.com/zulip/zulip/pull/5345.patch" + }, + "body": "An interaction bug (#4811) between our settings UI and the bootstrap modals breaks hotkey support for `Esc` when multiple modals are open.\r\n\r\ntodo:\r\n[x] Create `Modal` class in `modal.js` (drafted by @brockwhittaker)\r\n[x] Reimplement change_email_modal utilizing `Modal` class\r\n[] Dump using bootstrap for the account settings modal and all other modals, replace with `Modal` class\r\n[] Add hotkey support for closing the top modal for `Esc`\r\n\r\nThis should also be a helpful step in removing dependencies from Bootstrap.", + "closed_by": null + }, + "response-headers": { + "status": 200, + "ok": true, + "content-type": "application/json; charset=utf-8" + } +} diff --git a/bots/github_detail/github_detail.py b/bots/github_detail/github_detail.py index c6e29c2..b9fe3c6 100644 --- a/bots/github_detail/github_detail.py +++ b/bots/github_detail/github_detail.py @@ -56,13 +56,6 @@ class GithubHandler(object): except requests.exceptions.RequestException as e: logging.exception(e) return - if r.status_code == 404: - try: - r = requests.get( - self.GITHUB_PULL_URL_TEMPLATE.format(owner=owner, repo=repo, id=number)) - except requests.exceptions.RequestException as e: - logging.exception(e) - return if r.status_code != requests.codes.ok: return return r.json() @@ -79,13 +72,9 @@ class GithubHandler(object): def handle_message(self, message, bot_handler, state_handler): # type: () -> None # Send help message - if message['content'] == '@**{}** help'.format(bot_handler.full_name): - bot_handler.send_message(dict( - type='stream', - to=message['display_recipient'], - subject=message['subject'], - content=self.usage(), - )) + if message['content'] == 'help': + bot_handler.send_reply(message, self.usage()) + return # Capture owner, repo, id issue_prs = re.finditer( diff --git a/bots/github_detail/test_github_detail.py b/bots/github_detail/test_github_detail.py new file mode 100644 index 0000000..124d071 --- /dev/null +++ b/bots/github_detail/test_github_detail.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python + +from __future__ import absolute_import +from __future__ import print_function + +import os +import sys +import json + +our_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, os.path.normpath(os.path.join(our_dir))) +# For dev setups, we can find the API in the repo itself. +if os.path.exists(os.path.join(our_dir, '..')): + sys.path.insert(0, '..') +from bots_test_lib import BotTestCase + +class TestGithubDetailBot(BotTestCase): + bot_name = "github_detail" + + def test_issue(self): + bot_response = '**[zulip/zulip#5365](https://github.com/zulip/zulip/issues/5365)'\ + ' - frontend: Enable hot-reloading of CSS in development**\n'\ + 'Created by **[timabbott](https://github.com/timabbott)**\n'\ + 'Status - **Open**\n'\ + '```quote\n'\ + 'There\'s strong interest among folks working on the frontend in being '\ + 'able to use the hot-reloading feature of webpack for managing our CSS.\r\n\r\n'\ + 'In order to do this, step 1 is to move our CSS minification pipeline '\ + 'from django-pipeline to Webpack. \n```' + # This message calls the `send_reply` function of BotHandlerApi + with self.mock_http_conversation('test_issue'): + self.assert_bot_response( + message = {'content': 'zulip/zulip#5365'}, + response = {'content': bot_response}, + expected_method='send_reply' + ) + + def test_pull_request(self): + bot_response = '**[zulip/zulip#5345](https://github.com/zulip/zulip/pull/5345)'\ + ' - [WIP] modal: Replace bootstrap modal with custom modal class**\n'\ + 'Created by **[jackrzhang](https://github.com/jackrzhang)**\n'\ + 'Status - **Open**\n```quote\nAn interaction bug (#4811) '\ + 'between our settings UI and the bootstrap modals breaks hotkey '\ + 'support for `Esc` when multiple modals are open.\r\n\r\ntodo:\r\n[x]'\ + ' Create `Modal` class in `modal.js` (drafted by @brockwhittaker)\r\n[x]'\ + ' Reimplement change_email_modal utilizing `Modal` class\r\n[] Dump '\ + 'using bootstrap for the account settings modal and all other modals,'\ + ' replace with `Modal` class\r\n[] Add hotkey support for closing the'\ + ' top modal for `Esc`\r\n\r\nThis should also be a helpful step in removing dependencies from Bootstrap.\n```' + # This message calls the `send_reply` function of BotHandlerApi + with self.mock_http_conversation('test_pull'): + self.assert_bot_response( + message = {'content': 'zulip/zulip#5345'}, + response = {'content': bot_response}, + expected_method='send_reply' + ) + + def test_404(self): + bot_response = 'Failed to find issue/pr: zulip/zulip#0' + # This message calls the `send_reply` function of BotHandlerApi + with self.mock_http_conversation('test_404'): + self.assert_bot_response( + message = {'content': 'zulip/zulip#0'}, + response = {'content': bot_response}, + expected_method='send_reply' + ) + + def test_random_text(self): + bot_response = 'Failed to find any issue or PR.' + # This message calls the `send_reply` function of BotHandlerApi + self.assert_bot_response( + message = {'content': 'some random text'}, + response = {'content': bot_response}, + expected_method='send_reply' + ) + + def test_help_text(self): + bot_response = 'This plugin displays details on github issues and pull requests. '\ + 'To reference an issue or pull request usename mention the bot then '\ + 'anytime in the message type its id, for example:\n@**Github detail** '\ + '#3212 zulip#3212 zulip/zulip#3212\nThe default owner is zulip and '\ + 'the default repo is zulip.' + # This message calls the `send_reply` function of BotHandlerApi + + mock_config = {'owner': 'zulip', 'repo': 'zulip'} + with self.mock_config_info(mock_config): + self.initialize_bot() + self.assert_bot_response( + message = {'content': 'help'}, + response = {'content': bot_response}, + expected_method='send_reply' + )