def test_creates_issue(self): event = self.get_event() jira_rule = self.get_rule( data={ "issuetype": "1", "labels": "bunnies", "customfield_10200": "sad", "customfield_10300": ["Feature 1", "Feature 2"], "project": "10000", "jira_integration": self.integration.id, "jira_project": "10000", "issue_type": "Bug", "fixVersions": "[10000]", }) jira_rule.rule = Rule.objects.create( project=self.project, label="test rule", ) responses.add( responses.GET, "https://example.atlassian.net/rest/api/2/issue/createmeta", body=StubService.get_stub_json("jira", "createmeta_response.json"), content_type="json", match_querystring=False, ) jira_rule.data["key"] = "APP-123" responses.add( method=responses.POST, url="https://example.atlassian.net/rest/api/2/issue", json=jira_rule.data, status=202, content_type="application/json", ) responses.add( responses.GET, "https://example.atlassian.net/rest/api/2/issue/APP-123", body=StubService.get_stub_json("jira", "get_issue_response.json"), content_type="json", match_querystring=False, ) results = list(jira_rule.after(event=event, state=self.get_state())) assert len(results) == 1 # Trigger rule callback results[0].callback(event, futures=[]) # Make assertions about what would be sent. data = json.loads(responses.calls[2].request.body) assert data["fields"]["summary"] == event.title assert event.message in data["fields"]["description"] assert data["fields"]["issuetype"]["id"] == "1" external_issue = ExternalIssue.objects.get(key="APP-123") assert external_issue
def test_jira_server(self): user_response = StubService.get_stub_data("jira", "jira_server_user.json") assert build_user_choice(user_response, user_id_field="name") == ( "bob", "Bobby - [email protected] (bob)", )
def responder(request): query = parse_qs(urlparse(request.url).query) assert "HSP" == query["project"][0] assert "bob" == query["query"][0] data = StubService.get_stub_json("jira", "user_search_response.json") return 200, {}, data
def test_simple_status_sync_inbound(self, mock_sync_status_inbound): org = self.organization integration = Integration.objects.create(provider="jira", name="Example Jira") integration.add_organization(org, self.user) path = reverse("sentry-extensions-jira-issue-updated") with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=integration ) as mock_get_integration_from_jwt: data = StubService.get_stub_data("jira", "edit_issue_status_payload.json") resp = self.client.post(path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200 mock_get_integration_from_jwt.assert_called_with( "anexampletoken", "/extensions/jira/issue-updated/", "jira", {}, method="POST" ) mock_sync_status_inbound.assert_called_with( "APP-123", { "changelog": { "from": "10101", "field": "status", "fromString": "Done", "to": "3", "toString": "In Progress", "fieldtype": "jira", "fieldId": "status", }, "issue": { "fields": {"project": {"id": "10000", "key": "APP"}}, "key": "APP-123", }, }, )
def test_assign_use_email_api(self, mock_sync_group_assignee_inbound): org = self.organization integration = Integration.objects.create( provider="jira", name="Example Jira", metadata={ "oauth_client_id": "oauth-client-id", "shared_secret": "a-super-secret-key-from-atlassian", "base_url": "https://example.atlassian.net", "domain_name": "example.atlassian.net", }, ) integration.add_organization(org, self.user) path = reverse("sentry-extensions-jira-issue-updated") responses.add( responses.GET, "https://example.atlassian.net/rest/api/3/user/email", json={"accountId": "deadbeef123", "email": self.user.email}, match_querystring=False, ) with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=integration ): data = StubService.get_stub_data("jira", "edit_issue_assignee_payload.json") data["issue"]["fields"]["assignee"]["emailAddress"] = "" resp = self.client.post(path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200 assert mock_sync_group_assignee_inbound.called assert len(responses.calls) == 1
def test_missing_changelog(self): with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=self.integration, ): data = StubService.get_stub_data("jira", "changelog_missing.json") resp = self.client.post(self.path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200
def test_simple_deassign(self, mock_sync_group_assignee_inbound): with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=self.integration, ): data = StubService.get_stub_data( "jira", "edit_issue_no_assignee_payload.json") resp = self.client.post(self.path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200 mock_sync_group_assignee_inbound.assert_called_with( self.integration, None, "APP-123", assign=False)
def test_assign_missing_email(self, mock_sync_group_assignee_inbound): with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=self.integration, ): data = StubService.get_stub_data( "jira", "edit_issue_assignee_payload.json") data["issue"]["fields"]["assignee"]["emailAddress"] = "" resp = self.client.post(self.path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200 assert not mock_sync_group_assignee_inbound.called
def test_missing_changelog(self): org = self.organization integration = Integration.objects.create(provider="jira", name="Example Jira") integration.add_organization(org, self.user) path = reverse("sentry-extensions-jira-issue-updated") with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=integration ): data = StubService.get_stub_data("jira", "changelog_missing.json") resp = self.client.post(path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200
def test_issue_search_text(self): responses.add( responses.GET, "https://example.atlassian.net/rest/api/2/search/", body=StubService.get_stub_json("jira", "search_response.json"), content_type="json", match_querystring=False, ) org = self.organization self.login_as(self.user) path = reverse("sentry-extensions-jira-search", args=[org.slug, self.integration.id]) resp = self.client.get("%s?field=externalIssue&query=test" % (path,)) assert resp.status_code == 200 assert resp.data == [{"label": "(HSP-1) this is a test issue summary", "value": "HSP-1"}]
def test_assign_missing_email(self, mock_sync_group_assignee_inbound): org = self.organization integration = Integration.objects.create(provider="jira", name="Example Jira") integration.add_organization(org, self.user) path = reverse("sentry-extensions-jira-issue-updated") with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=integration ): data = StubService.get_stub_data("jira", "edit_issue_assignee_payload.json") data["issue"]["fields"]["assignee"]["emailAddress"] = "" resp = self.client.post(path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200 assert not mock_sync_group_assignee_inbound.called
def test_simple_deassign(self, mock_sync_group_assignee_inbound): org = self.organization integration = Integration.objects.create(provider="jira", name="Example Jira") integration.add_organization(org, self.user) path = reverse("sentry-extensions-jira-issue-updated") with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=integration ): data = StubService.get_stub_data("jira", "edit_issue_no_assignee_payload.json") resp = self.client.post(path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200 mock_sync_group_assignee_inbound.assert_called_with( integration, None, "APP-123", assign=False )
def test_simple_status_sync_inbound(self, mock_sync_status_inbound): with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=self.integration, ) as mock_get_integration_from_jwt: data = StubService.get_stub_data("jira", "edit_issue_status_payload.json") resp = self.client.post(self.path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200 mock_get_integration_from_jwt.assert_called_with( "anexampletoken", "/extensions/jira/issue-updated/", "jira", {}, method="POST") mock_sync_status_inbound.assert_called_with( "APP-123", { "changelog": { "from": "10101", "field": "status", "fromString": "Done", "to": "3", "toString": "In Progress", "fieldtype": "jira", "fieldId": "status", }, "issue": { "fields": { "project": { "id": "10000", "key": "APP" } }, "key": "APP-123", }, }, )
def test_assign_use_email_api(self, mock_sync_group_assignee_inbound): responses.add( responses.GET, "https://example.atlassian.net/rest/api/3/user/email", json={ "accountId": "deadbeef123", "email": self.user.email }, match_querystring=False, ) with patch( "sentry.integrations.jira.webhooks.get_integration_from_jwt", return_value=self.integration, ): data = StubService.get_stub_data( "jira", "edit_issue_assignee_payload.json") data["issue"]["fields"]["assignee"]["emailAddress"] = "" resp = self.client.post(self.path, data=data, HTTP_AUTHORIZATION="JWT anexampletoken") assert resp.status_code == 200 assert mock_sync_group_assignee_inbound.called assert len(responses.calls) == 1
def test_unexpected_id(self): user_response = StubService.get_stub_data("jira", "user.json") assert build_user_choice(user_response, user_id_field="name") is None
def test_jira_cloud(self): user_response = StubService.get_stub_data("jira", "user.json") assert build_user_choice(user_response, user_id_field="accountId") == ( "012345:00000000-1111-2222-3333-444444444444", "Saif Hakim", )
def responder(request): query = parse_qs(urlparse(request.url).query) assert 'id="hsp-1"' == query["jql"][0] data = StubService.get_stub_json("jira", "search_response.json") return 200, {}, data