From 9fc652e107334f5122e90bf39edc35dea5bb0a1b Mon Sep 17 00:00:00 2001 From: Michael Kochell Date: Fri, 24 Jan 2020 10:27:24 -0500 Subject: [PATCH] [MM-17903] Validate form for subscription create/edit (#432) clean up test --- server/http_test.go | 302 ++++++++++++++++++++++++++++--------------- server/issue_test.go | 8 ++ server/subscribe.go | 71 +++++++--- 3 files changed, 255 insertions(+), 126 deletions(-) diff --git a/server/http_test.go b/server/http_test.go index 35f91e921..85ac505bf 100644 --- a/server/http_test.go +++ b/server/http_test.go @@ -6,6 +6,7 @@ package main import ( "bytes" "encoding/json" + "fmt" "io/ioutil" "net/http" "net/http/httptest" @@ -172,60 +173,67 @@ func TestSubscribe(t *testing.T) { }, }, "Initial Subscription": { - subscription: `{"name": "some name", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"]}}`, + subscription: `{"name": "some name", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"], "issue_types": ["10001"]}}`, expectedStatusCode: http.StatusOK, apiCalls: checkHasSubscriptions([]ChannelSubscription{ ChannelSubscription{ ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }, nil, t), }, + "Initial Subscription, GetProject mocked error": { + subscription: fmt.Sprintf(`{"name": "some name", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["%s"], "issue_types": ["10001"]}}`, nonExistantProjectKey), + expectedStatusCode: http.StatusInternalServerError, + apiCalls: hasSubscriptions([]ChannelSubscription{}, t), + }, "Initial Subscription, empty name provided": { - subscription: `{"name": "", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"]}}`, + subscription: `{"name": "", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"], "issue_types": ["10001"]}}`, expectedStatusCode: http.StatusInternalServerError, - apiCalls: checkHasSubscriptions([]ChannelSubscription{ - ChannelSubscription{ - ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", - Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), - }, - }, - }, nil, t), + apiCalls: hasSubscriptions([]ChannelSubscription{}, t), }, "Initial Subscription, long name provided": { - subscription: `{"name": "` + TEST_DATA_LONG_SUBSCRIPTION_NAME + `", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"]}}`, + subscription: `{"name": "` + TEST_DATA_LONG_SUBSCRIPTION_NAME + `", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"], "issue_types": ["10001"]}}`, expectedStatusCode: http.StatusInternalServerError, - apiCalls: checkHasSubscriptions([]ChannelSubscription{ - ChannelSubscription{ - ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", - Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), - }, - }, - }, nil, t), + apiCalls: hasSubscriptions([]ChannelSubscription{}, t), + }, + "Initial Subscription, no project provided": { + subscription: `{"name": "somename", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": [], "issue_types": ["10001"]}}`, + expectedStatusCode: http.StatusInternalServerError, + apiCalls: hasSubscriptions([]ChannelSubscription{}, t), + }, + "Initial Subscription, no events provided": { + subscription: `{"name": "somename", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": [], "projects": ["myproject"], "issue_types": ["10001"]}}`, + expectedStatusCode: http.StatusInternalServerError, + apiCalls: hasSubscriptions([]ChannelSubscription{}, t), + }, + "Initial Subscription, no issue types provided": { + subscription: `{"name": "somename", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"], "issue_types": []}}`, + expectedStatusCode: http.StatusInternalServerError, + apiCalls: hasSubscriptions([]ChannelSubscription{}, t), }, "Adding to existing with other channel": { - subscription: `{"name": "some name", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"]}}`, + subscription: `{"name": "some name", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"], "issue_types": ["10001"]}}`, expectedStatusCode: http.StatusOK, apiCalls: checkHasSubscriptions([]ChannelSubscription{ ChannelSubscription{ ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, ChannelSubscription{ ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }, @@ -235,28 +243,31 @@ func TestSubscribe(t *testing.T) { Id: model.NewId(), ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }), t), }, "Adding to existing in same channel": { - subscription: `{"name": "subscription name", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"]}}`, + subscription: `{"name": "subscription name", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"], "issue_types": ["10001"]}}`, expectedStatusCode: http.StatusOK, apiCalls: checkHasSubscriptions([]ChannelSubscription{ ChannelSubscription{ ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, ChannelSubscription{ ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_updated"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_updated"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }, @@ -266,21 +277,23 @@ func TestSubscribe(t *testing.T) { Id: model.NewId(), ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_updated"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_updated"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }), t), }, "Adding to existing with same name in same channel": { - subscription: `{"name": "SubscriptionName", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"]}}`, + subscription: `{"name": "SubscriptionName", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "filters": {"events": ["jira:issue_created"], "projects": ["myproject"], "issue_types": ["10001"]}}`, expectedStatusCode: http.StatusInternalServerError, apiCalls: checkHasSubscriptions([]ChannelSubscription{ ChannelSubscription{ ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }, @@ -291,8 +304,9 @@ func TestSubscribe(t *testing.T) { Id: model.NewId(), ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_updated"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_updated"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }), t), @@ -394,8 +408,9 @@ func TestDeleteSubscription(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, })) @@ -414,8 +429,9 @@ func TestDeleteSubscription(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }, @@ -425,16 +441,18 @@ func TestDeleteSubscription(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, ChannelSubscription{ Id: "aaaaaaaaaaaaaaaaaaaaaaaaac", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaab", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }), t), @@ -545,16 +563,16 @@ func TestEditSubscription(t *testing.T) { }, }, "Editing subscription": { - subscription: `{"name": "some name", "id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaac", "filters": {"events": ["jira:issue_created"], "projects": ["otherproject"]}}`, + subscription: `{"name": "some name", "id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaac", "filters": {"events": ["jira:issue_created"], "projects": ["otherproject"], "issue_types": ["10001"]}}`, expectedStatusCode: http.StatusOK, apiCalls: checkHasSubscriptions([]ChannelSubscription{ ChannelSubscription{ Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("otherproject"), - Fields: []FieldFilter{}, + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("otherproject"), + IssueTypes: NewStringSet("10001"), }, }, }, @@ -564,63 +582,128 @@ func TestEditSubscription(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), - Fields: []FieldFilter{}, + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }), t), }, "Editing subscription, no name provided": { - subscription: `{"name": "", "id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaac", "filters": {"events": ["jira:issue_created"], "projects": ["otherproject"]}}`, + subscription: `{"name": "", "id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaac", "filters": {"events": ["jira:issue_created"], "projects": ["otherproject"], "issue_types": ["10001"]}}`, expectedStatusCode: http.StatusInternalServerError, - apiCalls: checkHasSubscriptions([]ChannelSubscription{ - ChannelSubscription{ - Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", - ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", - Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("otherproject"), - Fields: []FieldFilter{}, - }, - }, - }, + apiCalls: checkHasSubscriptions([]ChannelSubscription{}, withExistingChannelSubscriptions( []ChannelSubscription{ ChannelSubscription{ Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), - Fields: []FieldFilter{}, + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }), t), }, "Editing subscription, name too long": { - subscription: `{"name": "` + TEST_DATA_LONG_SUBSCRIPTION_NAME + `", "id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaac", "filters": {"events": ["jira:issue_created"], "projects": ["otherproject"]}}`, + subscription: `{"name": "` + TEST_DATA_LONG_SUBSCRIPTION_NAME + `", "id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaac", "filters": {"events": ["jira:issue_created"], "projects": ["otherproject"], "issue_types": ["10001"]}}`, expectedStatusCode: http.StatusInternalServerError, - apiCalls: checkHasSubscriptions([]ChannelSubscription{ - ChannelSubscription{ - Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", - ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", - Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("otherproject"), - Fields: []FieldFilter{}, - }, - }, - }, + apiCalls: checkHasSubscriptions([]ChannelSubscription{}, withExistingChannelSubscriptions( []ChannelSubscription{ ChannelSubscription{ Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), - Fields: []FieldFilter{}, + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), + }, + }, + }), t), + }, + "Editing subscription, no project provided": { + subscription: `{"name": "somename", "id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaac", "filters": {"events": ["jira:issue_created"], "projects": [], "issue_types": ["10001"]}}`, + expectedStatusCode: http.StatusInternalServerError, + apiCalls: checkHasSubscriptions([]ChannelSubscription{}, + withExistingChannelSubscriptions( + []ChannelSubscription{ + ChannelSubscription{ + Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", + ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", + Filters: SubscriptionFilters{ + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), + }, + }, + }), t), + }, + "Editing subscription, no events provided": { + subscription: `{"name": "somename", "id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaac", "filters": {"events": [], "projects": ["otherproject"], "issue_types": ["10001"]}}`, + expectedStatusCode: http.StatusInternalServerError, + apiCalls: checkHasSubscriptions([]ChannelSubscription{}, + withExistingChannelSubscriptions( + []ChannelSubscription{ + ChannelSubscription{ + Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", + ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", + Filters: SubscriptionFilters{ + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), + }, + }, + }), t), + }, + "Editing subscription, no issue types provided": { + subscription: `{"name": "somename", "id": "aaaaaaaaaaaaaaaaaaaaaaaaab", "channel_id": "aaaaaaaaaaaaaaaaaaaaaaaaac", "filters": {"events": ["jira:issue_created"], "projects": ["otherproject"], "issue_types": []}}`, + expectedStatusCode: http.StatusInternalServerError, + apiCalls: checkHasSubscriptions([]ChannelSubscription{}, + withExistingChannelSubscriptions( + []ChannelSubscription{ + ChannelSubscription{ + Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", + ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", + Filters: SubscriptionFilters{ + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), + }, + }, + }), t), + }, + "Editing subscription, GetProject mocked error. Existing sub has nonexistent project.": { + subscription: fmt.Sprintf(`{"id": "subaaaaaaaaaabbbbbbbbbbccc", "name": "subscription name", "channel_id": "channelaaaaaaaaaabbbbbbbbb", "filters": {"events": ["jira:issue_created"], "projects": ["%s"], "issue_types": ["10001"]}}`, nonExistantProjectKey), + expectedStatusCode: http.StatusInternalServerError, + apiCalls: checkHasSubscriptions([]ChannelSubscription{}, + withExistingChannelSubscriptions( + []ChannelSubscription{ + ChannelSubscription{ + Id: "subaaaaaaaaaabbbbbbbbbbccc", + ChannelId: "channelaaaaaaaaaabbbbbbbbb", + Filters: SubscriptionFilters{ + Events: NewStringSet("jira:issue_updated"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), + }, + }, + }), t), + }, + "Editing subscription, GetProject mocked error. Existing sub has existing project.": { + subscription: fmt.Sprintf(`{"id": "subaaaaaaaaaabbbbbbbbbbccc", "name": "subscription name", "channel_id": "channelaaaaaaaaaabbbbbbbbb", "filters": {"events": ["jira:issue_created"], "projects": ["%s"], "issue_types": ["10001"]}}`, nonExistantProjectKey), + expectedStatusCode: http.StatusInternalServerError, + apiCalls: checkHasSubscriptions([]ChannelSubscription{}, + withExistingChannelSubscriptions( + []ChannelSubscription{ + ChannelSubscription{ + Id: "subaaaaaaaaaabbbbbbbbbbccc", + ChannelId: "channelaaaaaaaaaabbbbbbbbb", + Filters: SubscriptionFilters{ + Events: NewStringSet("jira:issue_updated"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }), t), @@ -720,8 +803,9 @@ func TestGetSubscriptionsForChannel(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }, @@ -731,8 +815,9 @@ func TestGetSubscriptionsForChannel(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }, t), @@ -745,16 +830,18 @@ func TestGetSubscriptionsForChannel(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, ChannelSubscription{ Id: "aaaaaaaaaaaaaaaaaaaaaaaaac", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("things"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("things"), + IssueTypes: NewStringSet("10001"), }, }, }, @@ -764,16 +851,18 @@ func TestGetSubscriptionsForChannel(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, ChannelSubscription{ Id: "aaaaaaaaaaaaaaaaaaaaaaaaac", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("things"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("things"), + IssueTypes: NewStringSet("10001"), }, }, }, t), @@ -786,8 +875,9 @@ func TestGetSubscriptionsForChannel(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, }, @@ -797,16 +887,18 @@ func TestGetSubscriptionsForChannel(t *testing.T) { Id: "aaaaaaaaaaaaaaaaaaaaaaaaab", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaac", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("myproject"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("myproject"), + IssueTypes: NewStringSet("10001"), }, }, ChannelSubscription{ Id: "aaaaaaaaaaaaaaaaaaaaaaaaac", ChannelId: "aaaaaaaaaaaaaaaaaaaaaaaaad", Filters: SubscriptionFilters{ - Events: NewStringSet("jira:issue_created"), - Projects: NewStringSet("things"), + Events: NewStringSet("jira:issue_created"), + Projects: NewStringSet("things"), + IssueTypes: NewStringSet("10001"), }, }, }, t), diff --git a/server/issue_test.go b/server/issue_test.go index 48e75098a..8cf9a712f 100644 --- a/server/issue_test.go +++ b/server/issue_test.go @@ -13,6 +13,7 @@ const ( nonExistantIssueKey = "FAKE-1" noPermissionsIssueKey = "SUDO-1" existingIssueKey = "REAL-1" + nonExistantProjectKey = "FP" noIssueFoundError = "We couldn't find the issue key. Please confirm the issue key and try again. You may not have permissions to access this issue." noPermissionsError = "You do not have the appropriate permissions to perform this action. Please contact your Jira administrator." ) @@ -25,6 +26,13 @@ type testClient struct { IssueService } +func (client testClient) GetProject(key string) (*jira.Project, error) { + if key == nonExistantProjectKey { + return nil, errors.New("Project " + key + " not found") + } + return nil, nil +} + func (client testClient) GetTransitions(issueKey string) ([]jira.Transition, error) { if issueKey == nonExistantIssueKey { return []jira.Transition{}, errors.New(noIssueFoundError) diff --git a/server/subscribe.go b/server/subscribe.go index 836a55efa..5363e9559 100644 --- a/server/subscribe.go +++ b/server/subscribe.go @@ -270,7 +270,7 @@ func (p *Plugin) removeChannelSubscription(subscriptionId string) error { }) } -func (p *Plugin) addChannelSubscription(newSubscription *ChannelSubscription) error { +func (p *Plugin) addChannelSubscription(newSubscription *ChannelSubscription, client Client) error { ji, err := p.currentInstanceStore.LoadCurrentJIRAInstance() if err != nil { return err @@ -283,7 +283,7 @@ func (p *Plugin) addChannelSubscription(newSubscription *ChannelSubscription) er return nil, err } - err = p.validateSubscription(newSubscription) + err = p.validateSubscription(newSubscription, client) if err != nil { return nil, err } @@ -300,13 +300,25 @@ func (p *Plugin) addChannelSubscription(newSubscription *ChannelSubscription) er }) } -func (p *Plugin) validateSubscription(subscription *ChannelSubscription) error { +func (p *Plugin) validateSubscription(subscription *ChannelSubscription, client Client) error { if len(subscription.Name) == 0 { return errors.New("Please provide a name for the subscription.") } if len(subscription.Name) > MAX_SUBSCRIPTION_NAME_LENGTH { - return fmt.Errorf("Please provide a name less than %d characters.", MAX_SUBSCRIPTION_NAME_LENGTH) + return errors.Errorf("Please provide a name less than %d characters.", MAX_SUBSCRIPTION_NAME_LENGTH) + } + + if len(subscription.Filters.Events) == 0 { + return errors.New("Please provide at least one event type.") + } + + if len(subscription.Filters.IssueTypes) == 0 { + return errors.New("Please provide at least one issue type.") + } + + if (len(subscription.Filters.Projects)) == 0 { + return errors.New("Please provide a project identifier.") } channelId := subscription.ChannelId @@ -317,13 +329,20 @@ func (p *Plugin) validateSubscription(subscription *ChannelSubscription) error { for subID := range subs { if subs[subID].Name == subscription.Name && subs[subID].Id != subscription.Id { - return fmt.Errorf("Subscription name, '%s', already exists. Please choose another name.", subs[subID].Name) + return errors.Errorf("Subscription name, '%s', already exists. Please choose another name.", subs[subID].Name) } } + + projectKey := subscription.Filters.Projects.Elems()[0] + _, err = client.GetProject(projectKey) + if err != nil { + return errors.WithMessagef(err, "failed to get project %q", projectKey) + } + return nil } -func (p *Plugin) editChannelSubscription(modifiedSubscription *ChannelSubscription) error { +func (p *Plugin) editChannelSubscription(modifiedSubscription *ChannelSubscription, client Client) error { ji, err := p.currentInstanceStore.LoadCurrentJIRAInstance() if err != nil { return err @@ -341,7 +360,7 @@ func (p *Plugin) editChannelSubscription(modifiedSubscription *ChannelSubscripti return nil, errors.New("Existing subscription does not exist.") } - err = p.validateSubscription(modifiedSubscription) + err = p.validateSubscription(modifiedSubscription, client) if err != nil { return nil, err } @@ -725,28 +744,33 @@ func httpChannelCreateSubscription(p *Plugin, w http.ResponseWriter, r *http.Req return http.StatusForbidden, errors.Wrap(err, "you don't have permission to manage subscriptions") } - err = p.addChannelSubscription(&subscription) + ji, err := p.currentInstanceStore.LoadCurrentJIRAInstance() if err != nil { return http.StatusInternalServerError, err } - w.Header().Set("Content-Type", "application/json") - b, _ := json.Marshal(&subscription) - _, err = w.Write(b) + jiraUser, err := ji.GetPlugin().userStore.LoadJIRAUser(ji, mattermostUserId) if err != nil { - return http.StatusInternalServerError, errors.WithMessage(err, "failed to write response") + return http.StatusInternalServerError, err } - ji, err := p.currentInstanceStore.LoadCurrentJIRAInstance() + client, err := ji.GetClient(jiraUser) if err != nil { return http.StatusInternalServerError, err } - jiraUser, err := ji.GetPlugin().userStore.LoadJIRAUser(ji, mattermostUserId) + err = p.addChannelSubscription(&subscription, client) if err != nil { return http.StatusInternalServerError, err } + w.Header().Set("Content-Type", "application/json") + b, _ := json.Marshal(&subscription) + _, err = w.Write(b) + if err != nil { + return http.StatusInternalServerError, errors.WithMessage(err, "failed to write response") + } + post := &model.Post{ UserId: p.getConfig().botUserID, ChannelId: subscription.ChannelId, @@ -780,28 +804,33 @@ func httpChannelEditSubscription(p *Plugin, w http.ResponseWriter, r *http.Reque return http.StatusForbidden, errors.New("Not a member of the channel specified") } - err = p.editChannelSubscription(&subscription) + ji, err := p.currentInstanceStore.LoadCurrentJIRAInstance() if err != nil { return http.StatusInternalServerError, err } - w.Header().Set("Content-Type", "application/json") - b, _ := json.Marshal(&subscription) - _, err = w.Write(b) + jiraUser, err := ji.GetPlugin().userStore.LoadJIRAUser(ji, mattermostUserId) if err != nil { - return http.StatusInternalServerError, errors.WithMessage(err, "failed to write response") + return http.StatusInternalServerError, err } - ji, err := p.currentInstanceStore.LoadCurrentJIRAInstance() + client, err := ji.GetClient(jiraUser) if err != nil { return http.StatusInternalServerError, err } - jiraUser, err := ji.GetPlugin().userStore.LoadJIRAUser(ji, mattermostUserId) + err = p.editChannelSubscription(&subscription, client) if err != nil { return http.StatusInternalServerError, err } + w.Header().Set("Content-Type", "application/json") + b, _ := json.Marshal(&subscription) + _, err = w.Write(b) + if err != nil { + return http.StatusInternalServerError, errors.WithMessage(err, "failed to write response") + } + post := &model.Post{ UserId: p.getConfig().botUserID, ChannelId: subscription.ChannelId,