webhooks/taiga: Support Epic events.

This commit is contained in:
Eeshan Garg 2017-10-22 01:00:45 -02:30 committed by Tim Abbott
parent 4db99196e9
commit f8b5976335
13 changed files with 874 additions and 0 deletions

View File

@ -0,0 +1,76 @@
{
"change":{
"comment":"",
"comment_html":"",
"delete_comment_date":null,
"comment_versions":null,
"edit_comment_date":null,
"diff":{
"assigned_to":{
"from":null,
"to":"Eeshan Garg"
}
}
},
"type":"epic",
"data":{
"watchers":[
],
"description":"This Epic has details on why Zulip is awesome!",
"color":"#729fcf",
"custom_attributes_values":{
},
"team_requirement":false,
"project":{
"logo_big_url":null,
"name":"Zulip",
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"id":229096
},
"owner":{
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"username":"eeshangarg",
"full_name":"Eeshan Garg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d",
"photo":null
},
"subject":"Zulip is awesome!",
"assigned_to":{
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"username":"eeshangarg",
"full_name":"Eeshan Garg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d",
"photo":null
},
"ref":5,
"epics_order":1508641159928,
"id":50266,
"status":{
"is_closed":false,
"name":"New",
"color":"#999999",
"slug":"new",
"id":1004969
},
"modified_date":"2017-10-22T03:30:43.440Z",
"created_date":"2017-10-22T02:59:19.958Z",
"tags":[
],
"client_requirement":false
},
"date":"2017-10-22T03:30:43.553Z",
"action":"change",
"by":{
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"username":"eeshangarg",
"full_name":"Eeshan Garg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d",
"photo":null
}
}

View File

@ -0,0 +1,84 @@
{
"date":"2017-10-22T04:01:13.943Z",
"by":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"action":"change",
"change":{
"comment_versions":null,
"delete_comment_date":null,
"edit_comment_date":null,
"diff":{
"blocked_note_diff":{
"from":null,
"to":"<ins style=\"background:#e6ffe6;\">Just 'cause I can!</ins>"
},
"blocked_note_html":{
"from":"",
"to":"<p>Just 'cause I can!</p>"
},
"is_blocked":{
"from":false,
"to":true
}
},
"comment_html":"",
"comment":""
},
"type":"epic",
"data":{
"assigned_to":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/angelajohnson",
"full_name":"Angela Johnson",
"username":"angelajohnson",
"id":258683,
"gravatar_id":"36cf0dc28c5302bcd68119fcaaf4d4f3"
},
"description":"This Epic has details on why Zulip is awesome!",
"custom_attributes_values":{
},
"status":{
"slug":"new",
"id":1004969,
"color":"#999999",
"name":"New",
"is_closed":false
},
"project":{
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"logo_big_url":null,
"id":229096,
"name":"Zulip"
},
"epics_order":1508641159928,
"created_date":"2017-10-22T02:59:19.958Z",
"team_requirement":false,
"tags":[
],
"id":50266,
"subject":"Zulip is awesome!",
"owner":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"ref":5,
"client_requirement":false,
"modified_date":"2017-10-22T04:01:13.848Z",
"color":"#729fcf",
"watchers":[
]
}
}

View File

@ -0,0 +1,73 @@
{
"date":"2017-10-22T23:57:14.011Z",
"by":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"action":"change",
"change":{
"comment_versions":null,
"delete_comment_date":null,
"edit_comment_date":null,
"diff":{
},
"comment_html":"<p>I love contributing to Zulip</p>",
"comment":"I love contributing to Zulip"
},
"type":"epic",
"data":{
"assigned_to":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/angelajohnson",
"full_name":"Angela Johnson",
"username":"angelajohnson",
"id":258683,
"gravatar_id":"36cf0dc28c5302bcd68119fcaaf4d4f3"
},
"description":"This Epic has details on why Zulip is awesome! Firstly, Zulip is open source!",
"custom_attributes_values":{
},
"status":{
"slug":"in-progress",
"id":1004971,
"color":"#ff9900",
"name":"In progress",
"is_closed":false
},
"project":{
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"logo_big_url":null,
"id":229096,
"name":"Zulip"
},
"epics_order":1508641159928,
"created_date":"2017-10-22T02:59:19.958Z",
"team_requirement":false,
"tags":[
],
"id":50266,
"subject":"Zulip is great!",
"owner":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"ref":5,
"client_requirement":false,
"modified_date":"2017-10-22T23:57:13.871Z",
"color":"#729fcf",
"watchers":[
258659
]
}
}

View File

@ -0,0 +1,73 @@
{
"change":{
"comment":"",
"comment_html":"",
"delete_comment_date":null,
"comment_versions":null,
"edit_comment_date":null,
"diff":{
"description_diff":"Check the history API for the exact diff"
}
},
"type":"epic",
"data":{
"watchers":[
],
"description":"This Epic has details on why Zulip is awesome! Firstly, Zulip is open source!",
"color":"#729fcf",
"custom_attributes_values":{
},
"team_requirement":false,
"project":{
"logo_big_url":null,
"name":"Zulip",
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"id":229096
},
"owner":{
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"username":"eeshangarg",
"full_name":"Eeshan Garg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d",
"photo":null
},
"subject":"Zulip is great!",
"assigned_to":{
"permalink":"https://tree.taiga.io/profile/angelajohnson",
"username":"angelajohnson",
"full_name":"Angela Johnson",
"id":258683,
"gravatar_id":"36cf0dc28c5302bcd68119fcaaf4d4f3",
"photo":null
},
"ref":5,
"epics_order":1508641159928,
"id":50266,
"status":{
"is_closed":false,
"name":"In progress",
"color":"#ff9900",
"slug":"in-progress",
"id":1004971
},
"modified_date":"2017-10-22T23:51:02.968Z",
"created_date":"2017-10-22T02:59:19.958Z",
"tags":[
],
"client_requirement":false
},
"date":"2017-10-22T23:51:03.067Z",
"action":"change",
"by":{
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"username":"eeshangarg",
"full_name":"Eeshan Garg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d",
"photo":null
}
}

View File

@ -0,0 +1,76 @@
{
"date":"2017-10-22T03:54:15.829Z",
"by":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"action":"change",
"change":{
"comment_versions":null,
"delete_comment_date":null,
"edit_comment_date":null,
"diff":{
"assigned_to":{
"from":"Eeshan Garg",
"to":"Angela Johnson"
}
},
"comment_html":"",
"comment":""
},
"type":"epic",
"data":{
"assigned_to":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/angelajohnson",
"full_name":"Angela Johnson",
"username":"angelajohnson",
"id":258683,
"gravatar_id":"36cf0dc28c5302bcd68119fcaaf4d4f3"
},
"description":"This Epic has details on why Zulip is awesome!",
"custom_attributes_values":{
},
"status":{
"slug":"new",
"id":1004969,
"color":"#999999",
"name":"New",
"is_closed":false
},
"project":{
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"logo_big_url":null,
"id":229096,
"name":"Zulip"
},
"epics_order":1508641159928,
"created_date":"2017-10-22T02:59:19.958Z",
"team_requirement":false,
"tags":[
],
"id":50266,
"subject":"Zulip is awesome!",
"owner":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"ref":5,
"client_requirement":false,
"modified_date":"2017-10-22T03:54:15.748Z",
"color":"#729fcf",
"watchers":[
]
}
}

View File

@ -0,0 +1,76 @@
{
"change":{
"comment":"",
"comment_html":"",
"delete_comment_date":null,
"comment_versions":null,
"edit_comment_date":null,
"diff":{
"subject":{
"from":"Zulip is awesome!",
"to":"Zulip is great!"
}
}
},
"type":"epic",
"data":{
"watchers":[
],
"description":"This Epic has details on why Zulip is awesome!",
"color":"#729fcf",
"custom_attributes_values":{
},
"team_requirement":false,
"project":{
"logo_big_url":null,
"name":"Zulip",
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"id":229096
},
"owner":{
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"username":"eeshangarg",
"full_name":"Eeshan Garg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d",
"photo":null
},
"subject":"Zulip is great!",
"assigned_to":{
"permalink":"https://tree.taiga.io/profile/angelajohnson",
"username":"angelajohnson",
"full_name":"Angela Johnson",
"id":258683,
"gravatar_id":"36cf0dc28c5302bcd68119fcaaf4d4f3",
"photo":null
},
"ref":5,
"epics_order":1508641159928,
"id":50266,
"status":{
"is_closed":false,
"name":"In progress",
"color":"#ff9900",
"slug":"in-progress",
"id":1004971
},
"modified_date":"2017-10-22T23:46:22.779Z",
"created_date":"2017-10-22T02:59:19.958Z",
"tags":[
],
"client_requirement":false
},
"date":"2017-10-22T23:46:22.859Z",
"action":"change",
"by":{
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"username":"eeshangarg",
"full_name":"Eeshan Garg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d",
"photo":null
}
}

View File

@ -0,0 +1,76 @@
{
"change":{
"comment":"",
"comment_html":"",
"delete_comment_date":null,
"comment_versions":null,
"edit_comment_date":null,
"diff":{
"status":{
"from":"New",
"to":"In progress"
}
}
},
"type":"epic",
"data":{
"watchers":[
],
"description":"This Epic has details on why Zulip is awesome!",
"color":"#729fcf",
"custom_attributes_values":{
},
"team_requirement":false,
"project":{
"logo_big_url":null,
"name":"Zulip",
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"id":229096
},
"owner":{
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"username":"eeshangarg",
"full_name":"Eeshan Garg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d",
"photo":null
},
"subject":"Zulip is awesome!",
"assigned_to":{
"permalink":"https://tree.taiga.io/profile/angelajohnson",
"username":"angelajohnson",
"full_name":"Angela Johnson",
"id":258683,
"gravatar_id":"36cf0dc28c5302bcd68119fcaaf4d4f3",
"photo":null
},
"ref":5,
"epics_order":1508641159928,
"id":50266,
"status":{
"is_closed":false,
"name":"In progress",
"color":"#ff9900",
"slug":"in-progress",
"id":1004971
},
"modified_date":"2017-10-22T23:22:42.512Z",
"created_date":"2017-10-22T02:59:19.958Z",
"tags":[
],
"client_requirement":false
},
"date":"2017-10-22T23:22:42.602Z",
"action":"change",
"by":{
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"username":"eeshangarg",
"full_name":"Eeshan Garg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d",
"photo":null
}
}

View File

@ -0,0 +1,69 @@
{
"date":"2017-10-22T03:37:36.566Z",
"by":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"action":"change",
"change":{
"comment_versions":null,
"delete_comment_date":null,
"edit_comment_date":null,
"diff":{
"assigned_to":{
"from":"Eeshan Garg",
"to":null
}
},
"comment_html":"",
"comment":""
},
"type":"epic",
"data":{
"assigned_to":null,
"description":"This Epic has details on why Zulip is awesome!",
"custom_attributes_values":{
},
"status":{
"slug":"new",
"id":1004969,
"color":"#999999",
"name":"New",
"is_closed":false
},
"project":{
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"logo_big_url":null,
"id":229096,
"name":"Zulip"
},
"epics_order":1508641159928,
"created_date":"2017-10-22T02:59:19.958Z",
"team_requirement":false,
"tags":[
],
"id":50266,
"subject":"Zulip is awesome!",
"owner":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"ref":5,
"client_requirement":false,
"modified_date":"2017-10-22T03:37:36.472Z",
"color":"#729fcf",
"watchers":[
]
}
}

View File

@ -0,0 +1,84 @@
{
"date":"2017-10-22T04:06:42.244Z",
"by":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"action":"change",
"change":{
"comment_versions":null,
"delete_comment_date":null,
"edit_comment_date":null,
"diff":{
"blocked_note_diff":{
"from":null,
"to":"<del style=\"background:#ffe6e6;\">Just 'cause I can!</del>"
},
"blocked_note_html":{
"from":"<p>Just 'cause I can!</p>",
"to":""
},
"is_blocked":{
"from":true,
"to":false
}
},
"comment_html":"",
"comment":""
},
"type":"epic",
"data":{
"assigned_to":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/angelajohnson",
"full_name":"Angela Johnson",
"username":"angelajohnson",
"id":258683,
"gravatar_id":"36cf0dc28c5302bcd68119fcaaf4d4f3"
},
"description":"This Epic has details on why Zulip is awesome!",
"custom_attributes_values":{
},
"status":{
"slug":"new",
"id":1004969,
"color":"#999999",
"name":"New",
"is_closed":false
},
"project":{
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"logo_big_url":null,
"id":229096,
"name":"Zulip"
},
"epics_order":1508641159928,
"created_date":"2017-10-22T02:59:19.958Z",
"team_requirement":false,
"tags":[
],
"id":50266,
"subject":"Zulip is awesome!",
"owner":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"ref":5,
"client_requirement":false,
"modified_date":"2017-10-22T04:06:42.168Z",
"color":"#729fcf",
"watchers":[
]
}
}

View File

@ -0,0 +1,56 @@
{
"date":"2017-10-22T02:59:20.117Z",
"by":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"action":"create",
"type":"epic",
"data":{
"assigned_to":null,
"description":"This Epic has details on why Zulip is awesome!",
"custom_attributes_values":{
},
"status":{
"slug":"new",
"id":1004969,
"color":"#999999",
"name":"New",
"is_closed":false
},
"project":{
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"logo_big_url":null,
"id":229096,
"name":"Zulip"
},
"epics_order":1508641159928,
"created_date":"2017-10-22T02:59:19.958Z",
"team_requirement":false,
"tags":[
],
"id":50266,
"subject":"Zulip is awesome!",
"owner":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"ref":5,
"client_requirement":false,
"modified_date":"2017-10-22T02:59:19.975Z",
"color":"#729fcf",
"watchers":[
]
}
}

View File

@ -0,0 +1,61 @@
{
"date":"2017-10-23T00:02:01.239Z",
"by":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"action":"delete",
"type":"epic",
"data":{
"assigned_to":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/angelajohnson",
"full_name":"Angela Johnson",
"username":"angelajohnson",
"id":258683,
"gravatar_id":"36cf0dc28c5302bcd68119fcaaf4d4f3"
},
"description":"This Epic has details on why Zulip is awesome! Firstly, Zulip is open source!",
"custom_attributes_values":null,
"status":{
"slug":"in-progress",
"id":1004971,
"color":"#ff9900",
"name":"In progress",
"is_closed":false
},
"project":{
"permalink":"https://tree.taiga.io/project/eeshangarg-zulip",
"logo_big_url":null,
"id":229096,
"name":"Zulip"
},
"epics_order":1508641159928,
"created_date":"2017-10-22T02:59:19.958Z",
"team_requirement":false,
"tags":[
],
"id":50266,
"subject":"Zulip is great!",
"owner":{
"photo":null,
"permalink":"https://tree.taiga.io/profile/eeshangarg",
"full_name":"Eeshan Garg",
"username":"eeshangarg",
"id":258659,
"gravatar_id":"cd181af88d928dab53c55600c9f7551d"
},
"ref":5,
"client_requirement":false,
"modified_date":"2017-10-22T23:57:13.871Z",
"color":"#729fcf",
"watchers":[
258659
]
}
}

View File

@ -221,3 +221,58 @@ class TaigaHookTests(WebhookTestCase):
# type: () -> None
message = u':thought_balloon: TomaszKolek commented on issue **New issue**.'
self.send_and_test_stream_message("issue_changed_comment_added", u'subject', message)
def test_taiga_epic_created(self):
# type: () -> None
message = u':package: Eeshan Garg created epic **Zulip is awesome!**'
self.send_and_test_stream_message("epic_created", u'subject', message)
def test_taiga_epic_changed_assigned(self):
# type: () -> None
message = u':busts_in_silhouette: Eeshan Garg assigned epic **Zulip is awesome!** to Eeshan Garg.'
self.send_and_test_stream_message("epic_changed_assigned", u'subject', message)
def test_taiga_epic_changed_unassigned(self):
# type: () -> None
message = u':busts_in_silhouette: Eeshan Garg unassigned epic **Zulip is awesome!**'
self.send_and_test_stream_message("epic_changed_unassigned", u'subject', message)
def test_taiga_epic_changed_reassigned(self):
# type: () -> None
message = u':busts_in_silhouette: Eeshan Garg reassigned epic **Zulip is awesome!** from Eeshan Garg to Angela Johnson.'
self.send_and_test_stream_message("epic_changed_reassigned", u'subject', message)
def test_taiga_epic_changed_blocked(self):
# type: () -> None
message = u':lock: Eeshan Garg blocked epic **Zulip is awesome!**'
self.send_and_test_stream_message("epic_changed_blocked", u'subject', message)
def test_taiga_epic_changed_unblocked(self):
# type: () -> None
message = u':unlock: Eeshan Garg unblocked epic **Zulip is awesome!**'
self.send_and_test_stream_message("epic_changed_unblocked", u'subject', message)
def test_taiga_epic_changed_status(self):
# type: () -> None
message = u':chart_increasing: Eeshan Garg changed status of epic **Zulip is awesome!** from New to In progress.'
self.send_and_test_stream_message("epic_changed_status", u'subject', message)
def test_taiga_epic_changed_renamed(self):
# type: () -> None
message = u':notebook: Eeshan Garg renamed epic from **Zulip is awesome!** to **Zulip is great!**'
self.send_and_test_stream_message("epic_changed_renamed", u'subject', message)
def test_taiga_epic_changed_description(self):
# type: () -> None
message = u':notebook: Eeshan Garg updated description of epic **Zulip is great!**'
self.send_and_test_stream_message("epic_changed_description", u'subject', message)
def test_taiga_epic_changed_commented(self):
# type: () -> None
message = u':thought_balloon: Eeshan Garg commented on epic **Zulip is great!**'
self.send_and_test_stream_message("epic_changed_commented", u'subject', message)
def test_taiga_epic_deleted(self):
# type: () -> None
message = u':cross_mark: Eeshan Garg deleted epic **Zulip is great!**'
self.send_and_test_stream_message("epic_deleted", u'subject', message)

View File

@ -49,6 +49,21 @@ def api_taiga_webhook(request, user_profile, message=REQ(argument_type='body'),
return json_success()
templates = {
'epic': {
'create': u':package: %(user)s created epic **%(subject)s**',
'set_assigned_to': u':busts_in_silhouette: %(user)s assigned epic **%(subject)s** to %(new)s.',
'unset_assigned_to': u':busts_in_silhouette: %(user)s unassigned epic **%(subject)s**',
'changed_assigned_to': u':busts_in_silhouette: %(user)s reassigned epic **%(subject)s**'
' from %(old)s to %(new)s.',
'blocked': u':lock: %(user)s blocked epic **%(subject)s**',
'unblocked': u':unlock: %(user)s unblocked epic **%(subject)s**',
'changed_status': u':chart_increasing: %(user)s changed status of epic **%(subject)s**'
' from %(old)s to %(new)s.',
'renamed': u':notebook: %(user)s renamed epic from **%(old)s** to **%(new)s**',
'description_diff': u':notebook: %(user)s updated description of epic **%(subject)s**',
'commented': u':thought_balloon: %(user)s commented on epic **%(subject)s**',
'delete': u':cross_mark: %(user)s deleted epic **%(subject)s**',
},
'userstory': {
'create': u':package: %(user)s created user story **%(subject)s**.',
'set_assigned_to': u':busts_in_silhouette: %(user)s assigned user story **%(subject)s** to %(new)s.',