mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 14:03:30 +00:00 
			
		
		
		
	This is preparatory work towards adding a Topic model. We plan to use the local variable name as 'topic' for the Topic model objects. Currently, we use *topic as the local variable name for topic names. We rename local variables of the form *topic to *topic_name so that we don't need to think about type collisions in individual code paths where we might want to talk about both Topic objects and strings for the topic name.
		
			
				
	
	
		
			255 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			255 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from unittest.mock import patch
 | 
						||
from urllib.parse import quote, unquote
 | 
						||
 | 
						||
from zerver.lib.test_classes import WebhookTestCase
 | 
						||
from zerver.lib.users import get_api_key
 | 
						||
 | 
						||
 | 
						||
class JiraHookTests(WebhookTestCase):
 | 
						||
    STREAM_NAME = "jira"
 | 
						||
    URL_TEMPLATE = "/api/v1/external/jira?api_key={api_key}&stream={stream}"
 | 
						||
    WEBHOOK_DIR_NAME = "jira"
 | 
						||
 | 
						||
    def test_custom_stream(self) -> None:
 | 
						||
        api_key = get_api_key(self.test_user)
 | 
						||
        self.subscribe(self.test_user, "jira_custom")
 | 
						||
        url = f"/api/v1/external/jira?api_key={api_key}&stream=jira_custom"
 | 
						||
        msg = self.send_webhook_payload(
 | 
						||
            self.test_user,
 | 
						||
            url,
 | 
						||
            self.get_body("created_v2"),
 | 
						||
            content_type="application/json",
 | 
						||
        )
 | 
						||
        expected_content = """
 | 
						||
Leo Franchi created [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15):
 | 
						||
 | 
						||
* **Priority**: Major
 | 
						||
* **Assignee**: no one
 | 
						||
""".strip()
 | 
						||
        self.assert_stream_message(
 | 
						||
            message=msg,
 | 
						||
            stream_name="jira_custom",
 | 
						||
            topic_name="BUG-15: New bug with hook",
 | 
						||
            content=expected_content,
 | 
						||
        )
 | 
						||
 | 
						||
    def test_created(self) -> None:
 | 
						||
        expected_topic_name = "BUG-15: New bug with hook"
 | 
						||
        expected_message = """
 | 
						||
Leo Franchi created [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15):
 | 
						||
 | 
						||
* **Priority**: Major
 | 
						||
* **Assignee**: no one
 | 
						||
""".strip()
 | 
						||
        self.check_webhook("created_v1", expected_topic_name, expected_message)
 | 
						||
        self.check_webhook("created_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_ignored_events(self) -> None:
 | 
						||
        ignored_actions = [
 | 
						||
            "attachment_created",
 | 
						||
            "issuelink_created",
 | 
						||
            "issuelink_deleted",
 | 
						||
            "jira:version_released",
 | 
						||
            "jira:worklog_updated",
 | 
						||
            "sprint_closed",
 | 
						||
            "sprint_started",
 | 
						||
            "worklog_created",
 | 
						||
            "worklog_updated",
 | 
						||
        ]
 | 
						||
        for action in ignored_actions:
 | 
						||
            url = self.build_webhook_url()
 | 
						||
            payload = dict(webhookEvent=action)
 | 
						||
            with patch("zerver.webhooks.jira.view.check_send_webhook_message") as m:
 | 
						||
                result = self.client_post(url, payload, content_type="application/json")
 | 
						||
            self.assertFalse(m.called)
 | 
						||
            self.assert_json_success(result)
 | 
						||
 | 
						||
    def test_created_with_stream_with_spaces_escaped(self) -> None:
 | 
						||
        self.STREAM_NAME = quote("jira alerts")
 | 
						||
        self.url = self.build_webhook_url()
 | 
						||
        self.subscribe(self.test_user, unquote(self.STREAM_NAME))
 | 
						||
 | 
						||
        payload = self.get_body("created_v1")
 | 
						||
        result = self.client_post(self.url, payload, content_type="application/json")
 | 
						||
 | 
						||
        self.assert_json_success(result)
 | 
						||
 | 
						||
        expected_topic_name = "BUG-15: New bug with hook"
 | 
						||
        expected_message = """
 | 
						||
Leo Franchi created [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15):
 | 
						||
 | 
						||
* **Priority**: Major
 | 
						||
* **Assignee**: no one
 | 
						||
""".strip()
 | 
						||
        msg = self.get_last_message()
 | 
						||
        self.assertEqual(msg.content, expected_message)
 | 
						||
        self.assertEqual(msg.topic_name(), expected_topic_name)
 | 
						||
 | 
						||
    def test_created_with_stream_with_spaces_double_escaped(self) -> None:
 | 
						||
        self.STREAM_NAME = quote(quote("jira alerts"))
 | 
						||
        self.url = self.build_webhook_url()
 | 
						||
        self.subscribe(self.test_user, unquote(unquote(self.STREAM_NAME)))
 | 
						||
 | 
						||
        payload = self.get_body("created_v1")
 | 
						||
        result = self.client_post(self.url, payload, content_type="application/json")
 | 
						||
 | 
						||
        self.assert_json_success(result)
 | 
						||
 | 
						||
        expected_topic_name = "BUG-15: New bug with hook"
 | 
						||
        expected_message = """
 | 
						||
Leo Franchi created [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15):
 | 
						||
 | 
						||
* **Priority**: Major
 | 
						||
* **Assignee**: no one
 | 
						||
""".strip()
 | 
						||
        msg = self.get_last_message()
 | 
						||
        self.assertEqual(msg.content, expected_message)
 | 
						||
        self.assertEqual(msg.topic_name(), expected_topic_name)
 | 
						||
 | 
						||
    def test_created_with_topic_with_spaces_double_escaped(self) -> None:
 | 
						||
        self.url = self.build_webhook_url(topic=quote(quote("alerts test")))
 | 
						||
        expected_topic_name = "alerts test"
 | 
						||
        expected_message = """
 | 
						||
Leo Franchi created [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15):
 | 
						||
 | 
						||
* **Priority**: Major
 | 
						||
* **Assignee**: no one
 | 
						||
""".strip()
 | 
						||
        self.check_webhook("created_v1", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_created_with_unicode(self) -> None:
 | 
						||
        expected_topic_name = "BUG-15: New bug with à hook"
 | 
						||
        expected_message = """
 | 
						||
Leo Franchià created [BUG-15: New bug with à hook](http://lfranchi.com:8080/browse/BUG-15):
 | 
						||
 | 
						||
* **Priority**: Major
 | 
						||
* **Assignee**: no one
 | 
						||
""".strip()
 | 
						||
        self.check_webhook("created_with_unicode_v1", expected_topic_name, expected_message)
 | 
						||
        self.check_webhook("created_with_unicode_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_created_assignee(self) -> None:
 | 
						||
        expected_topic_name = "TEST-4: Test Created Assignee"
 | 
						||
        expected_message = """
 | 
						||
Leonardo Franchi [Administrator] created [TEST-4: Test Created Assignee](https://zulipp.atlassian.net/browse/TEST-4):
 | 
						||
 | 
						||
* **Priority**: Major
 | 
						||
* **Assignee**: Leonardo Franchi [Administrator]
 | 
						||
""".strip()
 | 
						||
        self.check_webhook("created_assignee_v1", expected_topic_name, expected_message)
 | 
						||
        self.check_webhook("created_assignee_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_commented(self) -> None:
 | 
						||
        expected_topic_name = "BUG-15: New bug with hook"
 | 
						||
        expected_message = """
 | 
						||
Leo Franchi commented on [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15) (assigned to **Othello, the Moor of Venice**):
 | 
						||
 | 
						||
``` quote
 | 
						||
Adding a comment. Oh, what a comment it is!
 | 
						||
```
 | 
						||
""".strip()
 | 
						||
        self.check_webhook("commented_v1", expected_topic_name, expected_message)
 | 
						||
        self.check_webhook("commented_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_commented_with_two_full_links(self) -> None:
 | 
						||
        expected_topic_name = "BUG-15: New bug with hook"
 | 
						||
        expected_message = """
 | 
						||
Leo Franchi commented on [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15) (assigned to **Othello, the Moor of Venice**):
 | 
						||
 | 
						||
``` quote
 | 
						||
This is the [first link](https://google.com) and this is the [second link](https://google.com) and this is the end.
 | 
						||
```
 | 
						||
""".strip()
 | 
						||
        self.check_webhook(
 | 
						||
            "commented_v2_with_two_full_links", expected_topic_name, expected_message
 | 
						||
        )
 | 
						||
 | 
						||
    def test_comment_edited(self) -> None:
 | 
						||
        expected_topic_name = "BUG-15: New bug with hook"
 | 
						||
        expected_message = """
 | 
						||
Leo Franchi edited a comment on [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15) (assigned to **Othello, the Moor of Venice**):
 | 
						||
 | 
						||
``` quote
 | 
						||
Adding a comment. Oh, what a comment it is!
 | 
						||
```
 | 
						||
""".strip()
 | 
						||
        self.check_webhook("comment_edited_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_comment_deleted(self) -> None:
 | 
						||
        expected_topic_name = "TOM-1: New Issue"
 | 
						||
        expected_message = "Tomasz Kolek deleted a comment from [TOM-1: New Issue](https://zuliptomek.atlassian.net/browse/TOM-1) (assigned to **kolaszek@go2.pl**)."
 | 
						||
        self.check_webhook("comment_deleted_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_commented_markup(self) -> None:
 | 
						||
        expected_topic_name = "TEST-7: Testing of rich text"
 | 
						||
        expected_message = """Leonardo Franchi [Administrator] commented on [TEST-7: Testing of rich text](https://zulipp.atlassian.net/browse/TEST-7):\n\n``` quote\nThis is a comment that likes to **exercise** a lot of _different_ `conventions` that `jira uses`.\r\n\r\n~~~\n\r\nthis code is not highlighted, but monospaced\r\n\n~~~\r\n\r\n~~~\n\r\ndef python():\r\n    print "likes to be formatted"\r\n\n~~~\r\n\r\n[http://www.google.com](http://www.google.com) is a bare link, and [Google](http://www.google.com) is given a title.\r\n\r\nThanks!\r\n\r\n~~~ quote\n\r\nSomeone said somewhere\r\n\n~~~\n```"""
 | 
						||
 | 
						||
        self.check_webhook("commented_markup_v1", expected_topic_name, expected_message)
 | 
						||
        self.check_webhook("commented_markup_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_deleted(self) -> None:
 | 
						||
        expected_topic_name = "BUG-15: New bug with hook"
 | 
						||
        expected_message = "Leo Franchi deleted [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15)."
 | 
						||
        self.check_webhook("deleted_v1", expected_topic_name, expected_message)
 | 
						||
        self.check_webhook("deleted_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_reassigned(self) -> None:
 | 
						||
        expected_topic_name = "BUG-15: New bug with hook"
 | 
						||
        expected_message = """Leo Franchi updated [BUG-15: New bug with hook](http://lfranchi.com:8080/browse/BUG-15) (assigned to **Othello, the Moor of Venice**):
 | 
						||
 | 
						||
* Changed assignee to **Othello, the Moor of Venice**"""
 | 
						||
        self.check_webhook("reassigned_v1", expected_topic_name, expected_message)
 | 
						||
        self.check_webhook("reassigned_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_priority_updated(self) -> None:
 | 
						||
        expected_topic_name = "TEST-1: Fix That"
 | 
						||
        expected_message = """Leonardo Franchi [Administrator] updated [TEST-1: Fix That](https://zulipp.atlassian.net/browse/TEST-1) (assigned to **leo@zulip.com**):
 | 
						||
 | 
						||
* Changed priority from **Critical** to **Major**"""
 | 
						||
        self.check_webhook("updated_priority_v1", expected_topic_name, expected_message)
 | 
						||
        self.check_webhook("updated_priority_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_status_changed(self) -> None:
 | 
						||
        expected_topic_name = "TEST-1: Fix That"
 | 
						||
        expected_message = """Leonardo Franchi [Administrator] updated [TEST-1: Fix That](https://zulipp.atlassian.net/browse/TEST-1):
 | 
						||
 | 
						||
* Changed status from **To Do** to **In Progress**"""
 | 
						||
        self.check_webhook("change_status_v1", expected_topic_name, expected_message)
 | 
						||
        self.check_webhook("change_status_v2", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_comment_event_comment_created(self) -> None:
 | 
						||
        expected_topic_name = "SP-1: Add support for newer format Jira issue comment events"
 | 
						||
        expected_message = """Hemanth V. Alluri commented on issue: *"Add support for newer format Jira issue comment events"*\n``` quote\nSounds like it’s pretty important. I’ll get this fixed ASAP!\n```"""
 | 
						||
        self.check_webhook("comment_created", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_comment_event_comment_created_no_issue_details(self) -> None:
 | 
						||
        expected_topic_name = "10000: Upgrade Jira to get the issue title here."
 | 
						||
        expected_message = """Hemanth V. Alluri commented on issue: *"Upgrade Jira to get the issue title here."*\n``` quote\nSounds like it’s pretty important. I’ll get this fixed ASAP!\n```"""
 | 
						||
        self.check_webhook(
 | 
						||
            "comment_created_no_issue_details", expected_topic_name, expected_message
 | 
						||
        )
 | 
						||
 | 
						||
    def test_comment_event_comment_edited(self) -> None:
 | 
						||
        expected_topic_name = "SP-1: Add support for newer format Jira issue comment events"
 | 
						||
        expected_message = """Hemanth V. Alluri updated their comment on issue: *"Add support for newer format Jira issue comment events"*\n``` quote\nThis is a very important issue! I’m on it!\n```"""
 | 
						||
        self.check_webhook("comment_updated", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_comment_event_comment_deleted(self) -> None:
 | 
						||
        expected_topic_name = "SP-1: Add support for newer format Jira issue comment events"
 | 
						||
        expected_message = """Hemanth V. Alluri deleted their comment on issue: *"Add support for newer format Jira issue comment events"*\n``` quote\n~~This is a very important issue! I’m on it!~~\n```"""
 | 
						||
        self.check_webhook("comment_deleted", expected_topic_name, expected_message)
 | 
						||
 | 
						||
    def test_anomalous_webhook_payload_error(self) -> None:
 | 
						||
        with self.assertRaises(AssertionError) as e:
 | 
						||
            self.check_webhook(
 | 
						||
                fixture_name="example_anomalous_payload",
 | 
						||
                expected_topic="",
 | 
						||
                expected_message="",
 | 
						||
                expect_noop=True,
 | 
						||
            )
 | 
						||
 | 
						||
        self.assertIn(
 | 
						||
            "Unable to parse request: Did Jira generate this event?",
 | 
						||
            e.exception.args[0],
 | 
						||
        )
 |