Skip to content

Commit

Permalink
[MI-2621]: Created font icons for subscription card and changed subsc…
Browse files Browse the repository at this point in the history
…ription titles to default color. (#27)

* [MI-2611]: Fixed modals not opening on multiple clients in case of cloud servers

* [MI-2613]: Fixed resetting error message on Link modal, showing descriptive error messages on UI and handling modals if account is not connected

* [MI-2613]: Fixed channel validation for DMs

* [MI-2613]: Added checks for filter API calls and user friendly error message

* [MI-2613]: Added logic to check if a subscription is not found on the Azure DevOps portal then delete it from the Mattermost's KV store

* [MI-2621]: Created font icons for subscription card and changed subscription titles to default color.

* [MI-2621]: Fixed test cases

* [MI-2621]: Fixed test cases

* [MI-2621]: Refactoring

* [MI-2621]: Added tooltip on project list card

* [MI-2621]: Fixed test cases

* [MI-2621]: Review fix

* [MI-2651]: Changed texts for work-item, added workitem in boards command, changed plugin name (#28)

* [MI-2651]: Changed texts for work-item, added workitem in boards command, changed plugin name

* [MI-2651]: Changed texts

* [MI-2651]: Made anyone as default arg for subscription list

* [MI-2651]: Added azd prefix for modal classes

* [MI-2651]: Added CSS util classes

* [MI-2651]: Fixed test cases

Co-authored-by: Abhishek Verma <abhishek.verma@brightscout.com>

Co-authored-by: Abhishek Verma <abhishek.verma@brightscout.com>
  • Loading branch information
avas27JTG and avas27JTG authored Jan 23, 2023
1 parent 72424ce commit 3ab28e7
Show file tree
Hide file tree
Showing 41 changed files with 342 additions and 161 deletions.
2 changes: 1 addition & 1 deletion plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "mattermost-plugin-azure-devops",
"name": "Mattermost Azure DevOps plugin",
"name": "Azure DevOps",
"description": "This plugin provides services of Azure DevOps such as Boards and Repos",
"icon_path": "public/assets/azurebot.svg",
"version": "3.1.0",
Expand Down
Binary file not shown.
12 changes: 12 additions & 0 deletions public/assets/font-icons/azure-devops-icon-font.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions server/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const (
CommandRepos = "repos"
CommandPipelines = "pipelines"
CommandCreate = "create"
CommandWorkitem = "workitem"
CommandSubscription = "subscription"
CommandAdd = "add"
CommandList = "list"
Expand Down
2 changes: 1 addition & 1 deletion server/constants/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const (
UserConnected = "Your Azure DevOps account is successfully connected!"
UserAlreadyConnected = "Your Azure DevOps account is already connected"
UserDisconnected = "Your Azure DevOps account is now disconnected"
CreatedTask = "[%s #%d](%s) (%s) was successfully created by %s."
CreatedTask = "Work item [#%d: \"%s\"](%s) of type \"%s\" was successfully created by %s."
TaskTitle = "[%s #%d: %s](%s)"
PullRequestTitle = "[#%d: %s](%s)"
BuildDetailsTitle = "[#%s](%s): %s"
Expand Down
2 changes: 1 addition & 1 deletion server/plugin/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (p *Plugin) handleCreateTask(w http.ResponseWriter, r *http.Request) {
}

p.writeJSON(w, task)
message := fmt.Sprintf(constants.CreatedTask, task.Fields.Type, task.ID, task.Link.HTML.Href, task.Fields.Title, task.Fields.CreatedBy.DisplayName)
message := fmt.Sprintf(constants.CreatedTask, task.ID, task.Fields.Title, task.Link.HTML.Href, task.Fields.Type, task.Fields.CreatedBy.DisplayName)

// Send message to DM.
if _, DMErr := p.DM(mattermostUserID, message, true); DMErr != nil {
Expand Down
153 changes: 103 additions & 50 deletions server/plugin/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -787,12 +787,14 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
mockAPI := &plugintest.API{}
p := setupMockPlugin(mockAPI, nil, nil)
for _, testCase := range []struct {
description string
body string
channelID string
err error
statusCode int
parseTimeError error
description string
body string
channelID string
isValidChannelID bool
err error
statusCode int
parseTimeError error
webhookSecret string
}{
{
description: "SubscriptionNotifications: valid",
Expand All @@ -801,31 +803,38 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: empty body",
body: `{}`,
err: errors.New("error empty body"),
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
description: "SubscriptionNotifications: empty body",
body: `{}`,
err: errors.New("error empty body"),
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: invalid channel ID",
body: `{}`,
err: errors.New("error invalid channel ID"),
channelID: "mockInvalidChannelID",
statusCode: http.StatusBadRequest,
description: "SubscriptionNotifications: invalid channel ID",
body: `{}`,
err: errors.New("error invalid channel ID"),
channelID: "mockInvalidChannelID",
statusCode: http.StatusBadRequest,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: invalid body",
body: `{
"detailedMessage": {
"markdown": "mockMarkdown"`,
err: errors.New("error invalid body"),
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusBadRequest,
err: errors.New("error invalid body"),
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusBadRequest,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: without channelID",
Expand All @@ -834,7 +843,9 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
statusCode: http.StatusBadRequest,
statusCode: http.StatusBadRequest,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType pull request created",
Expand All @@ -844,19 +855,24 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType workItem created",
body: `{
"eventType": "workitem.created",
"resource": {"fields": {"System.Title": "mockTitle", "System.TeamProject": "mockProject"}},
"detailedMessage": {
"markdown": "mockMarkdown"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType pull request commented",
Expand All @@ -871,8 +887,10 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
}
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType code pushed",
Expand All @@ -889,8 +907,10 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
]
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType build completed",
Expand All @@ -900,8 +920,10 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType build completed - error while parsing time",
Expand All @@ -911,9 +933,11 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
parseTimeError: errors.New("error parsing time"),
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusInternalServerError,
parseTimeError: errors.New("error parsing time"),
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusInternalServerError,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType release created",
Expand All @@ -923,8 +947,10 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType release abandoned",
Expand All @@ -934,8 +960,10 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType release abandoned - error while parsing time",
Expand All @@ -945,9 +973,11 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
parseTimeError: errors.New("error parsing time"),
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusInternalServerError,
parseTimeError: errors.New("error parsing time"),
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusInternalServerError,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType release deployment started",
Expand All @@ -957,8 +987,10 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType release deployment completed",
Expand All @@ -971,8 +1003,10 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"comment": "mockComment"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType run stage state changed",
Expand All @@ -982,8 +1016,10 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: eventType run state changed",
Expand All @@ -993,14 +1029,31 @@ func TestHandleSubscriptionNotifications(t *testing.T) {
"markdown": "mockMarkdown"
}
}`,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
channelID: "mockChannelIDmockChannelID",
statusCode: http.StatusOK,
isValidChannelID: true,
webhookSecret: "mockWebhookSecret",
},
{
description: "SubscriptionNotifications: without webhookSecret",
body: `{
"detailedMessage": {
"markdown": "mockMarkdown"
}
}`,
isValidChannelID: true,
statusCode: http.StatusUnauthorized,
err: errors.New("webhook secret is absent"),
},
} {
t.Run(testCase.description, func(t *testing.T) {
mockAPI.On("LogError", testutils.GetMockArgumentsWithType("string", 3)...)
mockAPI.On("CreatePost", mock.AnythingOfType("*model.Post")).Return(&model.Post{}, nil)

monkey.Patch(model.IsValidId, func(string) bool {
return testCase.isValidChannelID
})

monkey.Patch(time.Parse, func(_, _ string) (time.Time, error) {
return time.Time{}, testCase.parseTimeError
})
Expand Down
Loading

0 comments on commit 3ab28e7

Please sign in to comment.