mirror of https://github.com/zulip/zulip.git
Update our pivotal integration to handle v5 of their API
(imported from commit 2deba4ed2f72c7d7ccedafbb8fc4370b2faa5490)
This commit is contained in:
parent
7fa3bdba72
commit
45d3bb4f04
Binary file not shown.
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 53 KiB |
|
@ -1132,6 +1132,9 @@ key = NAGIOS_BOT_API_KEY
|
||||||
and <code>stream</code> is the stream name you want the
|
and <code>stream</code> is the stream name you want the
|
||||||
notifications sent to.</p>
|
notifications sent to.</p>
|
||||||
|
|
||||||
|
<p>Choose version 5 of the API. Zulip supports both version 3 and version 5, but
|
||||||
|
version 5 contains more information that lets Zulip format more useful messages.</p>
|
||||||
|
|
||||||
<img class="screenshot" src="/static/images/integrations/pivotal/001.png" />
|
<img class="screenshot" src="/static/images/integrations/pivotal/001.png" />
|
||||||
|
|
||||||
<p><b>Congratulations! You're done!</b><br /> When you make changes in Pivotal Tracker they will be reflected in Zulip:</p>
|
<p><b>Congratulations! You're done!</b><br /> When you make changes in Pivotal Tracker they will be reflected in Zulip:</p>
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"occurred_at": 1389218398000,
|
||||||
|
"kind": "story_update_activity",
|
||||||
|
"project": {
|
||||||
|
"name": "Hard Code",
|
||||||
|
"kind": "project",
|
||||||
|
"id": 807213
|
||||||
|
},
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"name": "Story of the Year",
|
||||||
|
"story_type": "feature",
|
||||||
|
"change_type": "update",
|
||||||
|
"kind": "story",
|
||||||
|
"new_values": {
|
||||||
|
"current_state": "accepted",
|
||||||
|
"updated_at": 1389218398000,
|
||||||
|
"accepted_at": 1389218397000
|
||||||
|
},
|
||||||
|
"id": 63486316,
|
||||||
|
"original_values": {
|
||||||
|
"current_state": "unstarted",
|
||||||
|
"updated_at": 1389215951000,
|
||||||
|
"accepted_at": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"highlight": "accepted",
|
||||||
|
"project_version": 60,
|
||||||
|
"guid": "807213_60",
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"name": "Story of the Year",
|
||||||
|
"story_type": "feature",
|
||||||
|
"kind": "story",
|
||||||
|
"id": 63486316,
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63486316"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"performed_by": {
|
||||||
|
"name": "Leo Franchi",
|
||||||
|
"initials": "LF",
|
||||||
|
"kind": "person",
|
||||||
|
"id": 981905
|
||||||
|
},
|
||||||
|
"message": "Leo Franchi accepted this feature"
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
{
|
||||||
|
"message": "Leo Franchi added comment: \"A comment on the story\"",
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63486316",
|
||||||
|
"kind": "story",
|
||||||
|
"story_type": "feature",
|
||||||
|
"id": 63486316,
|
||||||
|
"name": "Story of the Year"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"guid": "807213_61",
|
||||||
|
"kind": "comment_create_activity",
|
||||||
|
"project": {
|
||||||
|
"kind": "project",
|
||||||
|
"id": 807213,
|
||||||
|
"name": "Hard Code"
|
||||||
|
},
|
||||||
|
"occurred_at": 1389218474000,
|
||||||
|
"performed_by": {
|
||||||
|
"initials": "LF",
|
||||||
|
"kind": "person",
|
||||||
|
"id": 981905,
|
||||||
|
"name": "Leo Franchi"
|
||||||
|
},
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"kind": "comment",
|
||||||
|
"id": 59124096,
|
||||||
|
"change_type": "create",
|
||||||
|
"new_values": {
|
||||||
|
"story_id": 63486316,
|
||||||
|
"file_attachment_ids": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"google_attachment_ids": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"updated_at": 1389218474000,
|
||||||
|
"created_at": 1389218474000,
|
||||||
|
"google_attachments": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"file_attachments": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"text": "A comment on the story",
|
||||||
|
"id": 59124096,
|
||||||
|
"person_id": 981905
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "story",
|
||||||
|
"story_type": "feature",
|
||||||
|
"change_type": "update",
|
||||||
|
"id": 63486316,
|
||||||
|
"original_values": {
|
||||||
|
"updated_at": 1389218398000
|
||||||
|
},
|
||||||
|
"new_values": {
|
||||||
|
"updated_at": 1389218474000
|
||||||
|
},
|
||||||
|
"name": "Story of the Year"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"project_version": 61,
|
||||||
|
"highlight": "added comment:"
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
{
|
||||||
|
"project": {
|
||||||
|
"id": 807213,
|
||||||
|
"name": "Hard Code",
|
||||||
|
"kind": "project"
|
||||||
|
},
|
||||||
|
"guid": "807213_62",
|
||||||
|
"project_version": 62,
|
||||||
|
"highlight": "added",
|
||||||
|
"occurred_at": 1389218525000,
|
||||||
|
"performed_by": {
|
||||||
|
"id": 981905,
|
||||||
|
"name": "Leo Franchi",
|
||||||
|
"initials": "LF",
|
||||||
|
"kind": "person"
|
||||||
|
},
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"id": 63495662,
|
||||||
|
"story_type": "bug",
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63495662",
|
||||||
|
"name": "Story that I created",
|
||||||
|
"kind": "story"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"message": "Leo Franchi added this bug",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"id": 63495662,
|
||||||
|
"story_type": "bug",
|
||||||
|
"name": "Story that I created",
|
||||||
|
"new_values": {
|
||||||
|
"current_state": "unscheduled",
|
||||||
|
"after_id": 63486316,
|
||||||
|
"id": 63495662,
|
||||||
|
"requested_by_id": 981905,
|
||||||
|
"follower_ids": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"story_type": "bug",
|
||||||
|
"name": "Story that I created",
|
||||||
|
"project_id": 807213,
|
||||||
|
"description": "What a description",
|
||||||
|
"labels": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"created_at": 1389218525000,
|
||||||
|
"updated_at": 1389218525000,
|
||||||
|
"label_ids": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"before_id": 48420109
|
||||||
|
},
|
||||||
|
"change_type": "create",
|
||||||
|
"kind": "story"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kind": "story_create_activity"
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"occurred_at": 1389218976000,
|
||||||
|
"kind": "story_update_activity",
|
||||||
|
"project": {
|
||||||
|
"name": "Hard Code",
|
||||||
|
"kind": "project",
|
||||||
|
"id": 807213
|
||||||
|
},
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"name": "Pivotal Test",
|
||||||
|
"story_type": "feature",
|
||||||
|
"change_type": "update",
|
||||||
|
"kind": "story",
|
||||||
|
"new_values": {
|
||||||
|
"estimate": 3,
|
||||||
|
"updated_at": 1389218976000
|
||||||
|
},
|
||||||
|
"id": 63496066,
|
||||||
|
"original_values": {
|
||||||
|
"estimate": null,
|
||||||
|
"updated_at": 1389218941000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"highlight": "estimated",
|
||||||
|
"project_version": 81,
|
||||||
|
"guid": "807213_81",
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"name": "Pivotal Test",
|
||||||
|
"story_type": "feature",
|
||||||
|
"kind": "story",
|
||||||
|
"id": 63496066,
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63496066"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"performed_by": {
|
||||||
|
"name": "Leo Franchi",
|
||||||
|
"initials": "LF",
|
||||||
|
"kind": "person",
|
||||||
|
"id": 981905
|
||||||
|
},
|
||||||
|
"message": "Leo Franchi estimated this feature as 3 points"
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"message": "Leo Franchi delivered this feature",
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63486316",
|
||||||
|
"kind": "story",
|
||||||
|
"story_type": "feature",
|
||||||
|
"id": 63486316,
|
||||||
|
"name": "Story of the Year"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"guid": "807213_64",
|
||||||
|
"kind": "story_update_activity",
|
||||||
|
"project": {
|
||||||
|
"kind": "project",
|
||||||
|
"id": 807213,
|
||||||
|
"name": "Hard Code"
|
||||||
|
},
|
||||||
|
"occurred_at": 1389218691000,
|
||||||
|
"performed_by": {
|
||||||
|
"initials": "LF",
|
||||||
|
"kind": "person",
|
||||||
|
"id": 981905,
|
||||||
|
"name": "Leo Franchi"
|
||||||
|
},
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"kind": "story",
|
||||||
|
"story_type": "feature",
|
||||||
|
"change_type": "update",
|
||||||
|
"id": 63486316,
|
||||||
|
"original_values": {
|
||||||
|
"current_state": "accepted",
|
||||||
|
"accepted_at": 1389218632000,
|
||||||
|
"updated_at": 1389218645000
|
||||||
|
},
|
||||||
|
"new_values": {
|
||||||
|
"current_state": "delivered",
|
||||||
|
"accepted_at": null,
|
||||||
|
"updated_at": 1389218691000
|
||||||
|
},
|
||||||
|
"name": "Story of the Year"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"project_version": 64,
|
||||||
|
"highlight": "delivered"
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"performed_by": {
|
||||||
|
"name": "Leo Franchi",
|
||||||
|
"id": 981905,
|
||||||
|
"initials": "LF",
|
||||||
|
"kind": "person"
|
||||||
|
},
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"new_values": {
|
||||||
|
"updated_at": 1389218709000,
|
||||||
|
"accepted_at": 1389218708000,
|
||||||
|
"current_state": "accepted"
|
||||||
|
},
|
||||||
|
"story_type": "feature",
|
||||||
|
"name": "Story of the Year",
|
||||||
|
"id": 63486316,
|
||||||
|
"kind": "story",
|
||||||
|
"change_type": "update",
|
||||||
|
"original_values": {
|
||||||
|
"updated_at": 1389218691000,
|
||||||
|
"accepted_at": null,
|
||||||
|
"current_state": "delivered"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"project": {
|
||||||
|
"name": "Hard Code",
|
||||||
|
"id": 807213,
|
||||||
|
"kind": "project"
|
||||||
|
},
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"story_type": "feature",
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63486316",
|
||||||
|
"id": 63486316,
|
||||||
|
"name": "Story of the Year",
|
||||||
|
"kind": "story"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"highlight": "accepted",
|
||||||
|
"project_version": 65,
|
||||||
|
"message": "Leo Franchi accepted this feature",
|
||||||
|
"occurred_at": 1389218709000,
|
||||||
|
"guid": "807213_65",
|
||||||
|
"kind": "story_update_activity"
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"project": {
|
||||||
|
"id": 807213,
|
||||||
|
"name": "Hard Code",
|
||||||
|
"kind": "project"
|
||||||
|
},
|
||||||
|
"guid": "807213_84",
|
||||||
|
"project_version": 84,
|
||||||
|
"highlight": "moved",
|
||||||
|
"occurred_at": 1389282538000,
|
||||||
|
"performed_by": {
|
||||||
|
"id": 981905,
|
||||||
|
"name": "Leo Franchi",
|
||||||
|
"initials": "LF",
|
||||||
|
"kind": "person"
|
||||||
|
},
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"id": 63496066,
|
||||||
|
"story_type": "bug",
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63496066",
|
||||||
|
"name": "Pivotal Test",
|
||||||
|
"kind": "story"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"message": "Leo Franchi moved this story after 'test story'",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"id": 63496066,
|
||||||
|
"story_type": "bug",
|
||||||
|
"name": "Pivotal Test",
|
||||||
|
"new_values": {
|
||||||
|
"current_state": "unscheduled",
|
||||||
|
"after_id": 48326435,
|
||||||
|
"updated_at": 1389282537000,
|
||||||
|
"before_id": null
|
||||||
|
},
|
||||||
|
"change_type": "update",
|
||||||
|
"original_values": {
|
||||||
|
"current_state": "unstarted",
|
||||||
|
"after_id": 63495972,
|
||||||
|
"updated_at": 1389282533000,
|
||||||
|
"before_id": 63495662
|
||||||
|
},
|
||||||
|
"kind": "story"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kind": "story_move_activity"
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
{
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"story_type": "feature",
|
||||||
|
"kind": "story",
|
||||||
|
"id": 63486316,
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63486316",
|
||||||
|
"name": "Story of the Year"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"message": "Leo Franchi rejected this feature with comments: \"Try again next time\"",
|
||||||
|
"guid": "807213_73",
|
||||||
|
"kind": "story_update_activity",
|
||||||
|
"performed_by": {
|
||||||
|
"kind": "person",
|
||||||
|
"id": 981905,
|
||||||
|
"initials": "LF",
|
||||||
|
"name": "Leo Franchi"
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
"kind": "project",
|
||||||
|
"id": 807213,
|
||||||
|
"name": "Hard Code"
|
||||||
|
},
|
||||||
|
"occurred_at": 1389218802000,
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"new_values": {
|
||||||
|
"google_attachments": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"updated_at": 1389218802000,
|
||||||
|
"file_attachment_ids": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"file_attachments": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"person_id": 981905,
|
||||||
|
"id": 59124580,
|
||||||
|
"story_id": 63486316,
|
||||||
|
"google_attachment_ids": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"created_at": 1389218802000,
|
||||||
|
"text": "Try again next time"
|
||||||
|
},
|
||||||
|
"kind": "comment",
|
||||||
|
"id": 59124580,
|
||||||
|
"change_type": "create"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"original_values": {
|
||||||
|
"updated_at": 1389218792000,
|
||||||
|
"current_state": "delivered"
|
||||||
|
},
|
||||||
|
"new_values": {
|
||||||
|
"updated_at": 1389218802000,
|
||||||
|
"current_state": "rejected"
|
||||||
|
},
|
||||||
|
"story_type": "feature",
|
||||||
|
"kind": "story",
|
||||||
|
"id": 63486316,
|
||||||
|
"name": "Story of the Year",
|
||||||
|
"change_type": "update"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"project_version": 73,
|
||||||
|
"highlight": "rejected"
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"performed_by": {
|
||||||
|
"name": "Leo Franchi",
|
||||||
|
"id": 981905,
|
||||||
|
"initials": "LF",
|
||||||
|
"kind": "person"
|
||||||
|
},
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"new_values": {
|
||||||
|
"owned_by_id": 981905,
|
||||||
|
"updated_at": 1389218898000,
|
||||||
|
"current_state": "started"
|
||||||
|
},
|
||||||
|
"story_type": "feature",
|
||||||
|
"name": "Fresh Story",
|
||||||
|
"id": 63495972,
|
||||||
|
"kind": "story",
|
||||||
|
"change_type": "update",
|
||||||
|
"original_values": {
|
||||||
|
"owned_by_id": null,
|
||||||
|
"updated_at": 1389218887000,
|
||||||
|
"current_state": "unstarted"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"project": {
|
||||||
|
"name": "Hard Code",
|
||||||
|
"id": 807213,
|
||||||
|
"kind": "project"
|
||||||
|
},
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"story_type": "feature",
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63495972",
|
||||||
|
"id": 63495972,
|
||||||
|
"name": "Fresh Story",
|
||||||
|
"kind": "story"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"highlight": "started",
|
||||||
|
"project_version": 78,
|
||||||
|
"message": "Leo Franchi started this feature",
|
||||||
|
"occurred_at": 1389218898000,
|
||||||
|
"guid": "807213_78",
|
||||||
|
"kind": "story_update_activity"
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"message": "Leo Franchi edited this bug",
|
||||||
|
"primary_resources": [
|
||||||
|
{
|
||||||
|
"url": "http://www.pivotaltracker.com/story/show/63496066",
|
||||||
|
"kind": "story",
|
||||||
|
"story_type": "bug",
|
||||||
|
"id": 63496066,
|
||||||
|
"name": "Pivotal Test"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"guid": "807213_82",
|
||||||
|
"kind": "story_update_activity",
|
||||||
|
"project": {
|
||||||
|
"kind": "project",
|
||||||
|
"id": 807213,
|
||||||
|
"name": "Hard Code"
|
||||||
|
},
|
||||||
|
"occurred_at": 1389219010000,
|
||||||
|
"performed_by": {
|
||||||
|
"initials": "LF",
|
||||||
|
"kind": "person",
|
||||||
|
"id": 981905,
|
||||||
|
"name": "Leo Franchi"
|
||||||
|
},
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"kind": "story",
|
||||||
|
"story_type": "bug",
|
||||||
|
"change_type": "update",
|
||||||
|
"id": 63496066,
|
||||||
|
"original_values": {
|
||||||
|
"estimate": 3,
|
||||||
|
"updated_at": 1389218976000,
|
||||||
|
"story_type": "feature"
|
||||||
|
},
|
||||||
|
"new_values": {
|
||||||
|
"estimate": null,
|
||||||
|
"updated_at": 1389219010000,
|
||||||
|
"story_type": "bug"
|
||||||
|
},
|
||||||
|
"name": "Pivotal Test"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"project_version": 82,
|
||||||
|
"highlight": "edited"
|
||||||
|
}
|
|
@ -4945,7 +4945,7 @@ class GithubHookTests(AuthedTestCase):
|
||||||
"zulip-test: commit 7c994678d2f98797d299abed852d3ff9d0834533",
|
"zulip-test: commit 7c994678d2f98797d299abed852d3ff9d0834533",
|
||||||
"zbenjamin [commented](https://github.com/zbenjamin/zulip-test/commit/7c994678d2f98797d299abed852d3ff9d0834533#commitcomment-4252307) on `cowbell`, line 13\n\n~~~ quote\nThis line adds /unlucky/ cowbell (because of its line number). We should remove it.\n~~~")
|
"zbenjamin [commented](https://github.com/zbenjamin/zulip-test/commit/7c994678d2f98797d299abed852d3ff9d0834533#commitcomment-4252307) on `cowbell`, line 13\n\n~~~ quote\nThis line adds /unlucky/ cowbell (because of its line number). We should remove it.\n~~~")
|
||||||
|
|
||||||
class PivotalHookTests(AuthedTestCase):
|
class PivotalV3HookTests(AuthedTestCase):
|
||||||
|
|
||||||
def send_pivotal_message(self, name):
|
def send_pivotal_message(self, name):
|
||||||
email = "hamlet@zulip.com"
|
email = "hamlet@zulip.com"
|
||||||
|
@ -5017,6 +5017,91 @@ class PivotalHookTests(AuthedTestCase):
|
||||||
self.assertEqual(msg.content, 'Leo Franchi edited "My new Feature story" \
|
self.assertEqual(msg.content, 'Leo Franchi edited "My new Feature story" \
|
||||||
[(view)](https://www.pivotaltracker.com/s/projects/807213/stories/48276573)')
|
[(view)](https://www.pivotaltracker.com/s/projects/807213/stories/48276573)')
|
||||||
|
|
||||||
|
class PivotalV5HookTests(AuthedTestCase):
|
||||||
|
def send_pivotal_message(self, name):
|
||||||
|
email = "hamlet@zulip.com"
|
||||||
|
api_key = self.get_api_key(email)
|
||||||
|
return self.send_json_payload(email, "/api/v1/external/pivotal?api_key=%s&stream=%s" % (api_key,"pivotal"),
|
||||||
|
self.fixture_data('pivotal', "v5_" + name, file_type='json'),
|
||||||
|
stream_name="pivotal",
|
||||||
|
content_type="application/xml")
|
||||||
|
|
||||||
|
def test_accepted(self):
|
||||||
|
msg = self.send_pivotal_message('accepted')
|
||||||
|
self.assertEqual(msg.subject, '#63486316: Story of the Year')
|
||||||
|
self.assertEqual(msg.content, """[Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Story of the Year](http://www.pivotaltracker.com/story/show/63486316) updated:
|
||||||
|
* state changed from **unstarted** to **accepted**
|
||||||
|
""")
|
||||||
|
|
||||||
|
def test_commented(self):
|
||||||
|
msg = self.send_pivotal_message('commented')
|
||||||
|
self.assertEqual(msg.subject, '#63486316: Story of the Year')
|
||||||
|
self.assertEqual(msg.content, """Leo Franchi added a comment to [Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Story of the Year](http://www.pivotaltracker.com/story/show/63486316):
|
||||||
|
~~~quote
|
||||||
|
A comment on the story
|
||||||
|
~~~""")
|
||||||
|
|
||||||
|
def test_created(self):
|
||||||
|
msg = self.send_pivotal_message('created')
|
||||||
|
self.assertEqual(msg.subject, '#63495662: Story that I created')
|
||||||
|
self.assertEqual(msg.content, """Leo Franchi created bug: [Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Story that I created](http://www.pivotaltracker.com/story/show/63495662)
|
||||||
|
* State is **unscheduled**
|
||||||
|
* Description is
|
||||||
|
|
||||||
|
> What a description""")
|
||||||
|
|
||||||
|
def test_delivered(self):
|
||||||
|
msg = self.send_pivotal_message('delivered')
|
||||||
|
self.assertEqual(msg.subject, '#63486316: Story of the Year')
|
||||||
|
self.assertEqual(msg.content, """[Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Story of the Year](http://www.pivotaltracker.com/story/show/63486316) updated:
|
||||||
|
* state changed from **accepted** to **delivered**
|
||||||
|
""")
|
||||||
|
|
||||||
|
def test_finished(self):
|
||||||
|
msg = self.send_pivotal_message('finished')
|
||||||
|
self.assertEqual(msg.subject, '#63486316: Story of the Year')
|
||||||
|
self.assertEqual(msg.content, """[Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Story of the Year](http://www.pivotaltracker.com/story/show/63486316) updated:
|
||||||
|
* state changed from **delivered** to **accepted**
|
||||||
|
""")
|
||||||
|
|
||||||
|
def test_moved(self):
|
||||||
|
msg = self.send_pivotal_message('moved')
|
||||||
|
self.assertEqual(msg.subject, '#63496066: Pivotal Test')
|
||||||
|
self.assertEqual(msg.content, """Leo Franchi moved [Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Pivotal Test](http://www.pivotaltracker.com/story/show/63496066) from **unstarted** to **unscheduled**""")
|
||||||
|
|
||||||
|
def test_rejected(self):
|
||||||
|
msg = self.send_pivotal_message('rejected')
|
||||||
|
self.assertEqual(msg.subject, '#63486316: Story of the Year')
|
||||||
|
self.assertEqual(msg.content, """[Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Story of the Year](http://www.pivotaltracker.com/story/show/63486316) updated:
|
||||||
|
* Comment added:
|
||||||
|
~~~quote
|
||||||
|
Try again next time
|
||||||
|
~~~
|
||||||
|
* state changed from **delivered** to **rejected**
|
||||||
|
""")
|
||||||
|
|
||||||
|
def test_started(self):
|
||||||
|
msg = self.send_pivotal_message('started')
|
||||||
|
self.assertEqual(msg.subject, '#63495972: Fresh Story')
|
||||||
|
self.assertEqual(msg.content, """[Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Fresh Story](http://www.pivotaltracker.com/story/show/63495972) updated:
|
||||||
|
* state changed from **unstarted** to **started**
|
||||||
|
""")
|
||||||
|
|
||||||
|
def test_created_estimate(self):
|
||||||
|
msg = self.send_pivotal_message('created_estimate')
|
||||||
|
self.assertEqual(msg.subject, '#63496066: Pivotal Test')
|
||||||
|
self.assertEqual(msg.content, """[Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Pivotal Test](http://www.pivotaltracker.com/story/show/63496066) updated:
|
||||||
|
* estimate is now **3 points**
|
||||||
|
""")
|
||||||
|
|
||||||
|
def test_type_changed(self):
|
||||||
|
msg = self.send_pivotal_message('type_changed')
|
||||||
|
self.assertEqual(msg.subject, '#63496066: Pivotal Test')
|
||||||
|
self.assertEqual(msg.content, """[Hard Code](https://www.pivotaltracker.com/s/projects/807213): [Pivotal Test](http://www.pivotaltracker.com/story/show/63496066) updated:
|
||||||
|
* estimate changed from 3 to **0 points**
|
||||||
|
* type changed from **feature** to **bug**
|
||||||
|
""")
|
||||||
|
|
||||||
class NewRelicHookTests(AuthedTestCase):
|
class NewRelicHookTests(AuthedTestCase):
|
||||||
def send_new_relic_message(self, name):
|
def send_new_relic_message(self, name):
|
||||||
email = "hamlet@zulip.com"
|
email = "hamlet@zulip.com"
|
||||||
|
|
|
@ -360,13 +360,7 @@ def api_jira_webhook(request, user_profile):
|
||||||
[stream], subject, content)
|
[stream], subject, content)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
def api_pivotal_webhook_v3(request, user_profile, stream):
|
||||||
def api_pivotal_webhook(request, user_profile):
|
|
||||||
try:
|
|
||||||
stream = request.GET['stream']
|
|
||||||
except (AttributeError, KeyError):
|
|
||||||
return json_error("Missing stream parameter.")
|
|
||||||
|
|
||||||
payload = xml_fromstring(request.body)
|
payload = xml_fromstring(request.body)
|
||||||
|
|
||||||
def get_text(attrs):
|
def get_text(attrs):
|
||||||
|
@ -378,51 +372,144 @@ def api_pivotal_webhook(request, user_profile):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
event_type = payload.find('event_type').text
|
||||||
|
description = payload.find('description').text
|
||||||
|
project_id = payload.find('project_id').text
|
||||||
|
story_id = get_text(['stories', 'story', 'id'])
|
||||||
|
# Ugh, the URL in the XML data is not a clickable url that works for the user
|
||||||
|
# so we try to build one that the user can actually click on
|
||||||
|
url = "https://www.pivotaltracker.com/s/projects/%s/stories/%s" % (project_id, story_id)
|
||||||
|
|
||||||
|
# Pivotal doesn't tell us the name of the story, but it's usually in the
|
||||||
|
# description in quotes as the first quoted string
|
||||||
|
name_re = re.compile(r'[^"]+"([^"]+)".*')
|
||||||
|
match = name_re.match(description)
|
||||||
|
if match and len(match.groups()):
|
||||||
|
name = match.group(1)
|
||||||
|
else:
|
||||||
|
name = "Story changed" # Failed for an unknown reason, show something
|
||||||
|
more_info = " [(view)](%s)" % (url,)
|
||||||
|
|
||||||
|
if event_type == 'story_update':
|
||||||
|
subject = name
|
||||||
|
content = description + more_info
|
||||||
|
elif event_type == 'note_create':
|
||||||
|
subject = "Comment added"
|
||||||
|
content = description + more_info
|
||||||
|
elif event_type == 'story_create':
|
||||||
|
issue_desc = get_text(['stories', 'story', 'description'])
|
||||||
|
issue_type = get_text(['stories', 'story', 'story_type'])
|
||||||
|
issue_status = get_text(['stories', 'story', 'current_state'])
|
||||||
|
estimate = get_text(['stories', 'story', 'estimate'])
|
||||||
|
if estimate != '':
|
||||||
|
estimate = " worth %s story points" % (estimate,)
|
||||||
|
subject = name
|
||||||
|
content = "%s (%s %s%s):\n\n~~~ quote\n%s\n~~~\n\n%s" % (description,
|
||||||
|
issue_status,
|
||||||
|
issue_type,
|
||||||
|
estimate,
|
||||||
|
issue_desc,
|
||||||
|
more_info)
|
||||||
|
return subject, content
|
||||||
|
|
||||||
|
def api_pivotal_webhook_v5(request, user_profile, stream):
|
||||||
|
payload = ujson.loads(request.body)
|
||||||
|
|
||||||
|
event_type = payload["kind"]
|
||||||
|
|
||||||
|
project_name = payload["project"]["name"]
|
||||||
|
project_id = payload["project"]["id"]
|
||||||
|
|
||||||
|
primary_resources = payload["primary_resources"][0]
|
||||||
|
story_url = primary_resources["url"]
|
||||||
|
story_type = primary_resources["story_type"]
|
||||||
|
story_id = primary_resources["id"]
|
||||||
|
story_name = primary_resources["name"]
|
||||||
|
|
||||||
|
performed_by = payload.get("performed_by", {}).get("name", "")
|
||||||
|
|
||||||
|
story_info = "[%s](https://www.pivotaltracker.com/s/projects/%s): [%s](%s)" % (project_name, project_id, story_name, story_url)
|
||||||
|
|
||||||
|
changes = payload.get("changes", [])
|
||||||
|
|
||||||
|
content = ""
|
||||||
|
subject = "#%s: %s" % (story_id, story_name)
|
||||||
|
|
||||||
|
def extract_comment(change):
|
||||||
|
if change.get("kind") == "comment":
|
||||||
|
return change.get("new_values", {}).get("text", None)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if event_type == "story_update_activity":
|
||||||
|
# Find the changed valued and build a message
|
||||||
|
content += "%s updated:\n" % (story_info,)
|
||||||
|
for change in changes:
|
||||||
|
old_values = change.get("original_values", {})
|
||||||
|
new_values = change["new_values"]
|
||||||
|
|
||||||
|
if "current_state" in old_values and "current_state" in new_values:
|
||||||
|
content += "* state changed from **%s** to **%s**\n" % (old_values["current_state"], new_values["current_state"])
|
||||||
|
if "estimate" in old_values and "estimate" in new_values:
|
||||||
|
old_estimate = old_values.get("estimate", None)
|
||||||
|
if old_estimate is None:
|
||||||
|
estimate = "is now"
|
||||||
|
else:
|
||||||
|
estimate = "changed from %s to" % (old_estimate,)
|
||||||
|
new_estimate = new_values["estimate"] if new_values["estimate"] is not None else "0"
|
||||||
|
content += "* estimate %s **%s points**\n" % (estimate, new_estimate)
|
||||||
|
if "story_type" in old_values and "story_type" in new_values:
|
||||||
|
content += "* type changed from **%s** to **%s**\n" % (old_values["story_type"], new_values["story_type"])
|
||||||
|
|
||||||
|
comment = extract_comment(change)
|
||||||
|
if comment is not None:
|
||||||
|
content += "* Comment added:\n~~~quote\n%s\n~~~\n" % (comment,)
|
||||||
|
|
||||||
|
elif event_type == "comment_create_activity":
|
||||||
|
for change in changes:
|
||||||
|
comment = extract_comment(change)
|
||||||
|
if comment is not None:
|
||||||
|
content += "%s added a comment to %s:\n~~~quote\n%s\n~~~" % (performed_by, story_info, comment)
|
||||||
|
elif event_type == "story_create_activity":
|
||||||
|
content += "%s created %s: %s\n" % (performed_by, story_type, story_info)
|
||||||
|
for change in changes:
|
||||||
|
new_values = change.get("new_values", {})
|
||||||
|
if "current_state" in new_values:
|
||||||
|
content += "* State is **%s**\n" % (new_values["current_state"],)
|
||||||
|
if "description" in new_values:
|
||||||
|
content += "* Description is\n\n> %s" % (new_values["description"],)
|
||||||
|
elif event_type == "story_move_activity":
|
||||||
|
content = "%s moved %s" % (performed_by, story_info)
|
||||||
|
for change in changes:
|
||||||
|
old_values = change.get("original_values", {})
|
||||||
|
new_values = change["new_values"]
|
||||||
|
if "current_state" in old_values and "current_state" in new_values:
|
||||||
|
content += " from **%s** to **%s**" % (old_values["current_state"], new_values["current_state"])
|
||||||
|
else:
|
||||||
|
logging.warning("Unknown Pivotal event type: %s" % (event_type,))
|
||||||
|
|
||||||
|
return subject, content
|
||||||
|
|
||||||
|
@api_key_only_webhook_view
|
||||||
|
def api_pivotal_webhook(request, user_profile):
|
||||||
try:
|
try:
|
||||||
event_type = payload.find('event_type').text
|
stream = request.GET['stream']
|
||||||
description = payload.find('description').text
|
except (AttributeError, KeyError):
|
||||||
project_id = payload.find('project_id').text
|
return json_error("Missing stream parameter.")
|
||||||
story_id = get_text(['stories', 'story', 'id'])
|
|
||||||
# Ugh, the URL in the XML data is not a clickable url that works for the user
|
|
||||||
# so we try to build one that the user can actually click on
|
|
||||||
url = "https://www.pivotaltracker.com/s/projects/%s/stories/%s" % (project_id, story_id)
|
|
||||||
|
|
||||||
# Pivotal doesn't tell us the name of the story, but it's usually in the
|
|
||||||
# description in quotes as the first quoted string
|
|
||||||
name_re = re.compile(r'[^"]+"([^"]+)".*')
|
|
||||||
match = name_re.match(description)
|
|
||||||
if match and len(match.groups()):
|
|
||||||
name = match.group(1)
|
|
||||||
else:
|
|
||||||
name = "Story changed" # Failed for an unknown reason, show something
|
|
||||||
more_info = " [(view)](%s)" % (url,)
|
|
||||||
|
|
||||||
if event_type == 'story_update':
|
|
||||||
subject = name
|
|
||||||
content = description + more_info
|
|
||||||
elif event_type == 'note_create':
|
|
||||||
subject = "Comment added"
|
|
||||||
content = description + more_info
|
|
||||||
elif event_type == 'story_create':
|
|
||||||
issue_desc = get_text(['stories', 'story', 'description'])
|
|
||||||
issue_type = get_text(['stories', 'story', 'story_type'])
|
|
||||||
issue_status = get_text(['stories', 'story', 'current_state'])
|
|
||||||
estimate = get_text(['stories', 'story', 'estimate'])
|
|
||||||
if estimate != '':
|
|
||||||
estimate = " worth %s story points" % (estimate,)
|
|
||||||
subject = name
|
|
||||||
content = "%s (%s %s%s):\n\n~~~ quote\n%s\n~~~\n\n%s" % (description,
|
|
||||||
issue_status,
|
|
||||||
issue_type,
|
|
||||||
estimate,
|
|
||||||
issue_desc,
|
|
||||||
more_info)
|
|
||||||
else:
|
|
||||||
logging.warning("Received Pivotal event we did not understand: %s" % (event_type, ))
|
|
||||||
return json_success()
|
|
||||||
|
|
||||||
|
subject = content = None
|
||||||
|
try:
|
||||||
|
subject, content = api_pivotal_webhook_v3(request, user_profile, stream)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return json_error("Failed to extract data from Pivotal XML response")
|
return json_error("Failed to extract data from Pivotal XML response")
|
||||||
|
except:
|
||||||
|
# Attempt to parse v5 JSON payload
|
||||||
|
try:
|
||||||
|
subject, content = api_pivotal_webhook_v5(request, user_profile, stream)
|
||||||
|
except AttributeError:
|
||||||
|
return json_error("Failed to extract data from Pivotal V5 JSON response")
|
||||||
|
|
||||||
|
if subject is None or content is None:
|
||||||
|
return json_error("Unable to handle Pivotal payload")
|
||||||
|
|
||||||
check_send_message(user_profile, get_client("ZulipPivotalWebhook"), "stream",
|
check_send_message(user_profile, get_client("ZulipPivotalWebhook"), "stream",
|
||||||
[stream], subject, content)
|
[stream], subject, content)
|
||||||
|
|
Loading…
Reference in New Issue