Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mm 699] - Reporter should receive DM when someone comments on their issue Fixes #699 #810

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f72da22
added notification for reporters if present
maisnamrajusingh Sep 29, 2021
84b6437
fixed import
maisnamrajusingh Sep 29, 2021
5dde612
fix cilint import
maisnamrajusingh Sep 29, 2021
5704c3d
fixed imports for clint
maisnamrajusingh Oct 1, 2021
5733290
removed unwanted code
maisnamrajusingh Oct 10, 2021
63efea5
resolved comments
Nov 22, 2021
cf08036
resolved lint error
Nov 22, 2021
5dc6dbd
resolved lint error
Nov 22, 2021
d1f8211
resolved comments
Dec 1, 2021
16ba571
resolved comments
Dec 1, 2021
5ff1b98
check if the notification already exist
Dec 2, 2021
b11631c
check if the notification already exist
Dec 2, 2021
b55fda3
check if the notification already exist
Dec 2, 2021
854446a
Merge remote-tracking branch 'upstream/master' into mm-699
Jan 7, 2022
5faa2fb
temp push
Jan 12, 2022
b2a441c
temp push
Jan 18, 2022
3560eeb
fixed lint issue
Jan 21, 2022
8c39571
removed unwanted code
Jan 21, 2022
d7baf6d
removed unwanted code
Jan 21, 2022
497e8bb
removed unwanted code
Jan 21, 2022
a0c746a
removed unwanted code
Jan 21, 2022
b9d09ed
removed unwanted code
Jan 21, 2022
35fd3be
worked on adding test case and backward compatibility for notificatio…
Feb 21, 2022
b964793
revert unwanted change
Feb 21, 2022
03a5d40
Merge branch 'master' into mm-699
sibasankarnayak Feb 21, 2022
a274682
revert changes
Feb 21, 2022
604c972
fix lint issue
Feb 21, 2022
9f1e96f
fix lint issue
Feb 21, 2022
9ed70f4
Merge remote-tracking branch 'upstream/master' into mm-699
Mar 1, 2022
2fed01e
fixed comment
Mar 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions server/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,30 @@ func createSettingsCommand(optInstance bool) *model.AutocompleteData {
"list", "", "View your current settings")
settings.AddCommand(list)

setting := []model.AutocompleteListItem{
{HelpText: "Turn on notification on", Item: "on"},
{HelpText: "Turn on notification off", Item: "off"},
}

notifications := model.NewAutocompleteData(
"notifications", "[on|off]", "Update your user notifications settings")
notifications.AddStaticListArgument("value", true, []model.AutocompleteListItem{
{HelpText: "Turn notifications on", Item: "on"},
{HelpText: "Turn notifications off", Item: "off"},
})
"notifications", "[assinee|mention|reporter]", "manage notifications")

assigneeNotifications := model.NewAutocompleteData(
subCommandAssignee, "", "manage assignee notifications")
assigneeNotifications.AddStaticListArgument("value", true, setting)

mentionNotifications := model.NewAutocompleteData(
subCommandMention, "", "manage mention notifications")
mentionNotifications.AddStaticListArgument("value", true, setting)

reporterNotifications := model.NewAutocompleteData(
subCommandReporter, "", "manage reporter notifications")
reporterNotifications.AddStaticListArgument("value", true, setting)

notifications.AddCommand(assigneeNotifications)
notifications.AddCommand(mentionNotifications)
notifications.AddCommand(reporterNotifications)

withFlagInstance(notifications, optInstance, routeAutocompleteInstalledInstanceWithAlias)
settings.AddCommand(notifications)

Expand Down Expand Up @@ -367,10 +385,12 @@ func (p *Plugin) ExecuteCommand(c *plugin.Context, commandArgs *model.CommandArg
if err != nil {
return p.responsef(commandArgs, err.Error()), nil
}

args := strings.Fields(commandArgs.Command)
if len(args) == 0 || args[0] != "/jira" {
return p.help(commandArgs), nil
}

return jiraCommandHandler.Handle(p, c, commandArgs, args[1:]...), nil
}

Expand Down Expand Up @@ -583,7 +603,10 @@ func executeSettings(p *Plugin, c *plugin.Context, header *model.CommandArgs, ar

switch args[0] {
case "list":
return p.responsef(header, "Current settings:\n%s", conn.Settings.String())
if conn.Settings != nil {
return p.responsef(header, "Current settings:\n%s", conn.Settings.String())
}
return p.responsef(header, "Please connect to jira account `/jira connect`")
case "notifications":
return p.settingsNotifications(header, instance.GetID(), user.MattermostUserID, conn, args)
default:
Expand Down
69 changes: 49 additions & 20 deletions server/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ import (
)

const (
mockUserIDWithNotifications = "1"
mockUserIDWithoutNotifications = "2"
mockUserIDUnknown = "3"
mockUserIDSysAdmin = "4"
mockUserIDNonSysAdmin = "5"
mattermostSiteURL = "https://somelink.com"
mockUserIDWithNotifications = "1"
mockMattermostIDWithNotifications = "testMattermostUserId012345"
mockUserIDWithoutNotifications = "2"
mockUserIDUnknown = "3"
mockUserIDSysAdmin = "4"
mockUserIDNonSysAdmin = "5"
mattermostSiteURL = "https://somelink.com"
)

type mockUserStoreKV struct {
Expand Down Expand Up @@ -69,8 +70,15 @@ func getMockUserStoreKV() mockUserStoreKV {
},
}

value := true
withNotifications := connection // copy
withNotifications.Settings = &ConnectionSettings{Notifications: true}
settings := &ConnectionSettings{
Notifications: value,
SendNotificationsForMention: &value,
SendNotificationsForAssignee: &value,
SendNotificationsForReporter: &value,
}
withNotifications.Settings = settings

return mockUserStoreKV{
users: map[types.ID]*User{
Expand All @@ -79,9 +87,10 @@ func getMockUserStoreKV() mockUserStoreKV {
mockUserIDWithoutNotifications: newuser(mockUserIDWithoutNotifications),
},
connections: map[types.ID]*Connection{
mockUserIDWithNotifications: &withNotifications,
mockUserIDWithoutNotifications: &connection,
"connected_user": &connection,
mockUserIDWithNotifications: &withNotifications,
mockUserIDWithoutNotifications: &connection,
"connected_user": &connection,
mockMattermostIDWithNotifications: &withNotifications,
},
}
}
Expand Down Expand Up @@ -165,12 +174,12 @@ func TestPlugin_ExecuteCommand_Settings(t *testing.T) {
"no params, with notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings", UserId: mockUserIDWithNotifications},
numInstances: 1,
expectedMsg: "Current settings:\n\tNotifications: on",
expectedMsg: "Current settings:\n\tNotifications Status:\n\t- Notifications : on \n\t- Notifications for assignee : on \n\t- Notifications for mention : on \n\t- Notifications for reporter : on",
},
"no params, without notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings", UserId: mockUserIDWithoutNotifications},
numInstances: 1,
expectedMsg: "Current settings:\n\tNotifications: off",
expectedMsg: "Current settings:\n\tNotifications Status:\n\t- Notifications : off \n\t- Notifications for assignee : off \n\t- Notifications for mention : off \n\t- Notifications for reporter : off",
},
"unknown setting": {
commandArgs: &model.CommandArgs{Command: "/jira settings" + " test", UserId: mockUserIDWithoutNotifications},
Expand All @@ -180,22 +189,42 @@ func TestPlugin_ExecuteCommand_Settings(t *testing.T) {
"set notifications without value": {
commandArgs: &model.CommandArgs{Command: "/jira settings" + " notifications", UserId: mockUserIDWithoutNotifications},
numInstances: 1,
expectedMsg: "`/jira settings notifications [value]`\n* Invalid value. Accepted values are: `on` or `off`.",
expectedMsg: "`/jira settings notifications [assignee|mention|reporter] [value]`\n* Invalid value. Accepted values are: `on` or `off`.",
},
"set notification with unknown value": {
commandArgs: &model.CommandArgs{Command: "/jira settings notifications test", UserId: mockUserIDWithoutNotifications},
numInstances: 1,
expectedMsg: "`/jira settings notifications [value]`\n* Invalid value. Accepted values are: `on` or `off`.",
expectedMsg: "`/jira settings notifications [assignee|mention|reporter] [value]`\n* Invalid value. Accepted values are: `on` or `off`.",
},
"enable assignee notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings notifications assignee on", UserId: mockUserIDWithoutNotifications},
numInstances: 1,
expectedMsg: "Settings updated.\n\tAssignee on.",
},
"disable assignee notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings notifications assignee off", UserId: mockUserIDWithNotifications},
numInstances: 1,
expectedMsg: "Settings updated.\n\tAssignee off.",
},
"enable reporter notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings notifications reporter on", UserId: mockUserIDWithoutNotifications},
numInstances: 1,
expectedMsg: "Settings updated.\n\tReporter on.",
},
"disable reporter notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings notifications reporter off", UserId: mockUserIDWithNotifications},
numInstances: 1,
expectedMsg: "Settings updated.\n\tReporter off.",
},
"enable notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings notifications on", UserId: mockUserIDWithoutNotifications},
"enable mention notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings notifications mention on", UserId: mockUserIDWithoutNotifications},
numInstances: 1,
expectedMsg: "Settings updated. Notifications on.",
expectedMsg: "Settings updated.\n\tMention on.",
},
"disable notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings notifications off", UserId: mockUserIDWithNotifications},
"disable mention notifications": {
commandArgs: &model.CommandArgs{Command: "/jira settings notifications mention off", UserId: mockUserIDWithNotifications},
numInstances: 1,
expectedMsg: "Settings updated. Notifications off.",
expectedMsg: "Settings updated.\n\tMention off.",
},
}
for name, tt := range tests {
Expand Down
11 changes: 9 additions & 2 deletions server/kv_mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,17 @@ func (store mockUserStore) StoreConnection(types.ID, types.ID, *Connection) erro
return nil
}
func (store mockUserStore) LoadConnection(types.ID, types.ID) (*Connection, error) {
return &Connection{}, nil
valueTrue := true
return &Connection{
Settings: &ConnectionSettings{
SendNotificationsForMention: &valueTrue,
SendNotificationsForAssignee: &valueTrue,
SendNotificationsForReporter: &valueTrue,
},
}, nil
}
func (store mockUserStore) LoadMattermostUserID(instanceID types.ID, jiraUserName string) (types.ID, error) {
return "testMattermostUserId012345", nil
return mockMattermostIDWithNotifications, nil
}
func (store mockUserStore) DeleteConnection(instanceID, mattermostUserID types.ID) error {
return nil
Expand Down
41 changes: 34 additions & 7 deletions server/settings.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"strings"

"github.com/mattermost/mattermost-server/v6/model"

"github.com/mattermost/mattermost-plugin-jira/server/utils/types"
Expand All @@ -9,17 +11,21 @@ import (
const (
settingOn = "on"
settingOff = "off"

subCommandAssignee = "assignee"
subCommandMention = "mention"
subCommandReporter = "reporter"
)

func (p *Plugin) settingsNotifications(header *model.CommandArgs, instanceID, mattermostUserID types.ID, connection *Connection, args []string) *model.CommandResponse {
const helpText = "`/jira settings notifications [value]`\n* Invalid value. Accepted values are: `on` or `off`."
const helpText = "`/jira settings notifications [assignee|mention|reporter] [value]`\n* Invalid value. Accepted values are: `on` or `off`."

if len(args) != 2 {
if len(args) != 3 {
return p.responsef(header, helpText)
}

var value bool
switch args[1] {
switch args[2] {
case settingOn:
value = true
case settingOff:
Expand All @@ -31,7 +37,17 @@ func (p *Plugin) settingsNotifications(header *model.CommandArgs, instanceID, ma
if connection.Settings == nil {
connection.Settings = &ConnectionSettings{}
}
connection.Settings.Notifications = value
switch args[1] {
case subCommandAssignee:
connection.Settings.SendNotificationsForAssignee = &value
case subCommandMention:
connection.Settings.SendNotificationsForMention = &value
case subCommandReporter:
connection.Settings.SendNotificationsForReporter = &value
default:
return p.responsef(header, helpText)
}

if err := p.userStore.StoreConnection(instanceID, mattermostUserID, connection); err != nil {
p.errorf("settingsNotifications, err: %v", err)
p.responsef(header, "Could not store new settings. Please contact your system administrator. error: %v", err)
Expand All @@ -43,9 +59,20 @@ func (p *Plugin) settingsNotifications(header *model.CommandArgs, instanceID, ma
return p.responsef(header, "Your username is not connected to Jira. Please type `jira connect`. %v", err)
}
notifications := settingOff
if updatedConnection.Settings.Notifications {
notifications = settingOn
switch args[1] {
case subCommandAssignee:
if *updatedConnection.Settings.SendNotificationsForAssignee {
notifications = settingOn
}
case subCommandMention:
if *updatedConnection.Settings.SendNotificationsForMention {
notifications = settingOn
}
case subCommandReporter:
if *updatedConnection.Settings.SendNotificationsForReporter {
notifications = settingOn
}
}

return p.responsef(header, "Settings updated. Notifications %s.", notifications)
return p.responsef(header, "Settings updated.\n\t%s %s.", strings.Title(args[1]), notifications)
}
9 changes: 4 additions & 5 deletions server/subscribe.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ import (

const (
JiraSubscriptionsKey = "jirasub"

FilterIncludeAny = "include_any"
FilterIncludeAll = "include_all"
FilterExcludeAny = "exclude_any"
FilterEmpty = "empty"
FilterIncludeAny = "include_any"
FilterIncludeAll = "include_all"
FilterExcludeAny = "exclude_any"
FilterEmpty = "empty"

MaxSubscriptionNameLength = 100
)
Expand Down
6 changes: 4 additions & 2 deletions server/subscribe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1381,8 +1381,10 @@ func TestGetChannelsSubscribed(t *testing.T) {
r := bytes.NewReader(data)
bb, err := ioutil.ReadAll(r)
require.Nil(t, err)

wh, err := ParseWebhook(bb)
instanceID := testInstance1.InstanceID
p := &Plugin{}
p.SetAPI(api)
wh, err := ParseWebhook(bb, p, instanceID)
assert.Nil(t, err)

actual, err := p.getChannelsSubscribed(wh.(*webhook), testInstance1.InstanceID)
Expand Down
28 changes: 24 additions & 4 deletions server/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,35 @@ func (c *Connection) JiraAccountID() types.ID {
}

type ConnectionSettings struct {
Notifications bool `json:"notifications"`
Notifications bool `json:"notifications"`
SendNotificationsForMention *bool `json:"send_notifications_for_mention"`
SendNotificationsForAssignee *bool `json:"send_notifications_for_assignee"`
SendNotificationsForReporter *bool `json:"send_notifications_for_reporter"`
}

func (s *ConnectionSettings) String() string {
notifications := "off"
assigneeNotifications := "Notifications for assignee : off"
mentionNotifications := "Notifications for mention : off"
reporterNotifications := "Notifications for reporter : off"
notifications := "Notifications : off"

if s != nil && *s.SendNotificationsForAssignee {
assigneeNotifications = "Notifications for assignee : on"
}

if s != nil && *s.SendNotificationsForMention {
mentionNotifications = "Notifications for mention : on"
}

if s != nil && *s.SendNotificationsForReporter {
reporterNotifications = "Notifications for reporter : on"
}

if s != nil && s.Notifications {
notifications = "on"
notifications = "Notifications : on"
}
return fmt.Sprintf("\tNotifications: %s", notifications)

return fmt.Sprintf("\tNotifications Status:\n\t- %s \n\t- %s \n\t- %s \n\t- %s", notifications, assigneeNotifications, mentionNotifications, reporterNotifications)
}

func NewUser(mattermostUserID types.ID) *User {
Expand Down
5 changes: 4 additions & 1 deletion server/user_cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func (p *Plugin) httpACUserInteractive(w http.ResponseWriter, r *http.Request, i
}

mmToken := r.FormValue(argMMToken)
value := true
connection := &Connection{
PluginVersion: manifest.Version,
User: jira.User{
Expand All @@ -102,7 +103,9 @@ func (p *Plugin) httpACUserInteractive(w http.ResponseWriter, r *http.Request, i
},
// Set default settings the first time a user connects
Settings: &ConnectionSettings{
Notifications: true,
SendNotificationsForMention: &value,
SendNotificationsForAssignee: &value,
SendNotificationsForReporter: &value,
},
}

Expand Down
8 changes: 6 additions & 2 deletions server/user_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,13 @@ func (p *Plugin) httpOAuth1aComplete(w http.ResponseWriter, r *http.Request, ins
return http.StatusInternalServerError, err
}
connection.User = *juser

value := true
// Set default settings the first time a user connects
connection.Settings = &ConnectionSettings{Notifications: true}
connection.Settings = &ConnectionSettings{
SendNotificationsForMention: &value,
SendNotificationsForAssignee: &value,
SendNotificationsForReporter: &value,
}

err = p.connectUser(instance, types.ID(mattermostUserID), connection)
if err != nil {
Expand Down
Loading