From eac5d6b8ced8d6bbdf5939c58e39ca3302154976 Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Wed, 19 Jun 2024 14:32:25 -0400 Subject: [PATCH 1/7] add CRUD handlers for user notification rules --- user_notification_rule.go | 156 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 user_notification_rule.go diff --git a/user_notification_rule.go b/user_notification_rule.go new file mode 100644 index 0000000..25614e5 --- /dev/null +++ b/user_notification_rule.go @@ -0,0 +1,156 @@ +package aapi + +import ( + "fmt" + "log" + "net/http" +) + +// UserNotificationRuleService handles requests to user notification rule endpoints +// +// https://grafana.com/docs/oncall/latest/oncall-api-reference/personal_notification_rules/ +type UserNotificationRuleService struct { + client *Client + url string +} + +// NewUserNotificationRuleService creates UserNotificationRuleService with defined url +func NewUserNotificationRuleService(client *Client) *UserNotificationRuleService { + userNotificationRuleService := UserNotificationRuleService{client: client, url: "personal_notification_rules"} + return &userNotificationRuleService +} + +type PaginatedUserNotificationRulesResponse struct { + PaginatedResponse + UserNotificationRules []*UserNotificationRule `json:"results"` +} + +type UserNotificationRule struct { + ID string `json:"id"` + UserId string `json:"user_id"` + Position int `json:"position"` + Duration int `json:"duration"` + Important bool `json:"important"` + Type string `json:"type"` +} + +type ListUserNotificationRuleOptions struct { + ListOptions + UserId string `url:"user_id,omitempty" json:"user_id,omitempty"` + Important string `url:"important,omitempty" json:"important,omitempty"` +} + +// ListUserNotificationRules fetches all user notification rules for authorized organization +// +// https://grafana.com/docs/oncall/latest/oncall-api-reference/personal_notification_rules/#list-personal-notification-rules +func (service *UserNotificationRuleService) ListUserNotificationRules(opt *ListUserNotificationRuleOptions) (*PaginatedUserNotificationRulesResponse, *http.Response, error) { + req, err := service.client.NewRequest("GET", service.url, opt) + if err != nil { + return nil, nil, err + } + + var userNotificationRules *PaginatedUserNotificationRulesResponse + resp, err := service.client.Do(req, &userNotificationRules) + if err != nil { + return nil, resp, err + } + + return userNotificationRules, resp, err +} + +type GetUserNotificationRuleOptions struct { +} + +// GetUserNotificationRule fetches a user notification rule by given id +// +// https://grafana.com/docs/oncall/latest/oncall-api-reference/personal_notification_rules/#get-personal-notification-rule +func (service *UserNotificationRuleService) GetUserNotificationRule(id string, opt *GetUserNotificationRuleOptions) (*UserNotificationRule, *http.Response, error) { + u := fmt.Sprintf("%s/%s/", service.url, id) + + req, err := service.client.NewRequest("GET", u, opt) + if err != nil { + return nil, nil, err + } + + userNotificationRule := new(UserNotificationRule) + resp, err := service.client.Do(req, userNotificationRule) + if err != nil { + return nil, resp, err + } + + return userNotificationRule, resp, err +} + +type CreateUserNotificationRuleOptions struct { + UserId string `json:"user_id,omitempty"` + Position *int `json:"position,omitempty"` + Duration int `json:"duration,omitempty"` + Important bool `json:"important,omitempty"` + Type string `json:"type,omitempty"` +} + +// CreateUserNotificationRule creates a user notification rule for the given user, type, and position +// +// https://grafana.com/docs/oncall/latest/oncall-api-reference/personal_notification_rules/#post-a-personal-notification-rule +func (service *UserNotificationRuleService) CreateUserNotificationRule(opt *CreateUserNotificationRuleOptions) (*UserNotificationRule, *http.Response, error) { + u := fmt.Sprintf("%s/", service.url) + req, err := service.client.NewRequest("POST", u, opt) + if err != nil { + return nil, nil, err + } + + userNotificationRule := new(UserNotificationRule) + + resp, err := service.client.Do(req, userNotificationRule) + log.Printf("[DEBUG] request success") + + if err != nil { + return nil, resp, err + } + + return userNotificationRule, resp, err +} + +type UpdateUserNotificationRuleOptions struct { + Position *int `json:"position,omitempty"` + Duration int `json:"duration,omitempty"` + Type string `json:"type,omitempty"` +} + +// UpdateUserNotificationRule updates user notification rule with new position, duration, and type +// +// NOTE: this endpoint is not currently publicly documented, but it does exist +func (service *UserNotificationRuleService) UpdateUserNotificationRule(id string, opt *UpdateUserNotificationRuleOptions) (*UserNotificationRule, *http.Response, error) { + u := fmt.Sprintf("%s/%s/", service.url, id) + + req, err := service.client.NewRequest("PUT", u, opt) + if err != nil { + return nil, nil, err + } + + userNotificationRule := new(UserNotificationRule) + resp, err := service.client.Do(req, userNotificationRule) + if err != nil { + return nil, resp, err + } + + return userNotificationRule, resp, err +} + +type DeleteUserNotificationRuleOptions struct { +} + +// DeleteUserNotificationRule deletes user notification rule +// +// https://grafana.com/docs/oncall/latest/oncall-api-reference/personal_notification_rules/#delete-a-personal-notification-rule +func (service *UserNotificationRuleService) DeleteUserNotificationRule(id string, opt *DeleteUserNotificationRuleOptions) (*http.Response, error) { + u := fmt.Sprintf("%s/%s/", service.url, id) + + req, err := service.client.NewRequest("DELETE", u, opt) + if err != nil { + return nil, err + } + + resp, err := service.client.Do(req, nil) + return resp, err +} From 0d49a0f1a9baca6c856c16d99cf5efa67c46efbd Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Wed, 19 Jun 2024 16:46:52 -0400 Subject: [PATCH 2/7] finish adding user notification rule endpoint handlers --- client.go | 28 ++++++++++++++-------------- user_notification_rule.go | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/client.go b/client.go index 7d308e8..b6af886 100644 --- a/client.go +++ b/client.go @@ -44,19 +44,19 @@ type Client struct { limiter *rate.Limiter UserAgent string // List of Services. Keep in sync with func newClient - Alerts *AlertService - Integrations *IntegrationService - EscalationChains *EscalationChainService - Escalations *EscalationService - Users *UserService - Schedules *ScheduleService - Routes *RouteService - SlackChannels *SlackChannelService - UserGroups *UserGroupService - CustomActions *CustomActionService - OnCallShifts *OnCallShiftService - Teams *TeamService - Webhooks *WebhookService + Alerts *AlertService + Integrations *IntegrationService + EscalationChains *EscalationChainService + Escalations *EscalationService + Users *UserService + Schedules *ScheduleService + Routes *RouteService + SlackChannels *SlackChannelService + UserGroups *UserGroupService + OnCallShifts *OnCallShiftService + Teams *TeamService + Webhooks *WebhookService + UserNotificationRules *UserNotificationRuleService } func New(base_url, token string) (*Client, error) { @@ -108,10 +108,10 @@ func newClient(url string) (*Client, error) { c.Routes = NewRouteService(c) c.SlackChannels = NewSlackChannelService(c) c.UserGroups = NewUserGroupService(c) - c.CustomActions = NewCustomActionService(c) c.OnCallShifts = NewOnCallShiftService(c) c.Teams = NewTeamService(c) c.Webhooks = NewWebhookService(c) + c.UserNotificationRules = NewUserNotificationRuleService(c) return c, nil } diff --git a/user_notification_rule.go b/user_notification_rule.go index 25614e5..f870246 100644 --- a/user_notification_rule.go +++ b/user_notification_rule.go @@ -84,7 +84,7 @@ func (service *UserNotificationRuleService) GetUserNotificationRule(id string, o type CreateUserNotificationRuleOptions struct { UserId string `json:"user_id,omitempty"` Position *int `json:"position,omitempty"` - Duration int `json:"duration,omitempty"` + Duration *int `json:"duration,omitempty"` Important bool `json:"important,omitempty"` Type string `json:"type,omitempty"` } @@ -113,7 +113,7 @@ func (service *UserNotificationRuleService) CreateUserNotificationRule(opt *Crea type UpdateUserNotificationRuleOptions struct { Position *int `json:"position,omitempty"` - Duration int `json:"duration,omitempty"` + Duration *int `json:"duration,omitempty"` Type string `json:"type,omitempty"` } From 32c66a706550b08684dec31f72466f458835154d Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Wed, 19 Jun 2024 16:46:56 -0400 Subject: [PATCH 3/7] tests --- user_notification_rule_test.go | 130 +++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 user_notification_rule_test.go diff --git a/user_notification_rule_test.go b/user_notification_rule_test.go new file mode 100644 index 0000000..51d6ed4 --- /dev/null +++ b/user_notification_rule_test.go @@ -0,0 +1,130 @@ +package aapi + +import ( + "fmt" + "net/http" + "reflect" + "testing" +) + +var baseUrl = "personal_notification_rules" +var testId = "NT79GA9I7E4DJ" +var testUserId = "U4DNY931HHJS5" + +var testUserNotificationRule = &UserNotificationRule{ + ID: testId, + UserId: testUserId, + Position: 0, + Type: "notify_by_sms", +} + +var testUserNotificationRuleBody = fmt.Sprintf(`{ + "id": "%s", + "user_id": "%s", + "position": 0, + "type": "notify_by_sms" +}`, testId, testUserId) + +func TestCreateUserNotificationRule(t *testing.T) { + mux, server, client := setup(t) + defer teardown(server) + + url := fmt.Sprintf("/api/v1/%s/", baseUrl) + mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + testRequestMethod(t, r, "POST") + fmt.Fprint(w, testUserNotificationRuleBody) + }) + + createOptions := &CreateUserNotificationRuleOptions{ + UserId: testUserId, + Important: true, + Type: "notify_by_sms", + } + userNotificationRule, _, err := client.UserNotificationRules.CreateUserNotificationRule(createOptions) + + if err != nil { + t.Fatal(err) + } + + want := testUserNotificationRule + + if !reflect.DeepEqual(want, userNotificationRule) { + t.Errorf("returned\n %+v\n want\n %+v\n", userNotificationRule, want) + } +} + +func TestDeleteUserNotificationRule(t *testing.T) { + mux, server, client := setup(t) + defer teardown(server) + + url := fmt.Sprintf("/api/v1/%s/%s/", baseUrl, testId) + mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + testRequestMethod(t, r, "DELETE") + }) + + options := &DeleteUserNotificationRuleOptions{} + + _, err := client.UserNotificationRules.DeleteUserNotificationRule(testId, options) + if err != nil { + t.Fatal(err) + } +} + +func TestListUserNotificationRules(t *testing.T) { + mux, server, client := setup(t) + defer teardown(server) + + url := fmt.Sprintf("/api/v1/%s/", baseUrl) + mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + testRequestMethod(t, r, "GET") + fmt.Fprint(w, fmt.Sprintf(`{"count": 1, "next": null, "previous": null, "results": [%s]}`, testUserNotificationRuleBody)) + }) + + options := &ListUserNotificationRuleOptions{ + UserId: testUserId, + } + + userNotificationRules, _, err := client.UserNotificationRules.ListUserNotificationRules(options) + if err != nil { + t.Fatal(err) + } + + want := &PaginatedUserNotificationRulesResponse{ + PaginatedResponse: PaginatedResponse{ + Count: 1, + Next: nil, + Previous: nil, + }, + UserNotificationRules: []*UserNotificationRule{ + testUserNotificationRule, + }, + } + if !reflect.DeepEqual(want, userNotificationRules) { + t.Errorf(" returned\n %+v, \nwant\n %+v", userNotificationRules, want) + } +} + +func TestGetUserNotificationRule(t *testing.T) { + mux, server, client := setup(t) + defer teardown(server) + + url := fmt.Sprintf("/api/v1/%s/%s/", baseUrl, testId) + mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + testRequestMethod(t, r, "GET") + fmt.Fprint(w, testUserNotificationRuleBody) + }) + + options := &GetUserNotificationRuleOptions{} + + userNotificationRule, _, err := client.UserNotificationRules.GetUserNotificationRule(testId, options) + + if err != nil { + t.Fatal(err) + } + + want := userNotificationRule + + if !reflect.DeepEqual(want, userNotificationRule) { + t.Errorf("returned\n %+v\n want\n %+v\n", userNotificationRule, want) + } +} From 0cf54ca96d214f59fd8154a0315e6539db348344 Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Wed, 19 Jun 2024 16:47:01 -0400 Subject: [PATCH 4/7] remove custom action handlers --- custom_action.go | 170 ------------------------------------------ custom_action_test.go | 119 ----------------------------- 2 files changed, 289 deletions(-) delete mode 100644 custom_action.go delete mode 100644 custom_action_test.go diff --git a/custom_action.go b/custom_action.go deleted file mode 100644 index 0d029ae..0000000 --- a/custom_action.go +++ /dev/null @@ -1,170 +0,0 @@ -package aapi - -import ( - "fmt" - "net/http" -) - -// CustomActionService handles requests to outgoing webhook endpoint -// -// https://grafana.com/docs/grafana-cloud/oncall/oncall-api-reference/outgoing_webhooks/ -type CustomActionService struct { - client *Client - url string -} - -// NewCustomActionService creates CustomActionService with defined url -func NewCustomActionService(client *Client) *CustomActionService { - customActionService := CustomActionService{} - customActionService.client = client - customActionService.url = "actions" - return &customActionService -} - -type PaginatedCustomActionsResponse struct { - PaginatedResponse - CustomActions []*CustomAction `json:"results"` -} - -type CustomAction struct { - ID string `json:"id"` - Name string `json:"name"` - TeamId string `json:"team_id"` - Url string `json:"url"` - Data *string `json:"data"` - User *string `json:"user"` - Password *string `json:"password"` - AuthorizationHeader *string `json:"authorization_header"` - ForwardWholePayload bool `json:"forward_whole_payload"` -} - -type ListCustomActionOptions struct { - ListOptions - Name string `url:"name,omitempty" json:"name,omitempty"` -} - -// ListCustomActions fetches all customActions for authorized organization -// -// https://grafana.com/docs/grafana-cloud/oncall/oncall-api-reference/outgoing_webhooks/#list-actions -func (service *CustomActionService) ListCustomActions(opt *ListCustomActionOptions) (*PaginatedCustomActionsResponse, *http.Response, error) { - u := fmt.Sprintf("%s", service.url) - - req, err := service.client.NewRequest("GET", u, opt) - if err != nil { - return nil, nil, err - } - - var customActions *PaginatedCustomActionsResponse - resp, err := service.client.Do(req, &customActions) - if err != nil { - return nil, resp, err - } - - return customActions, resp, err -} - -type GetCustomActionOptions struct { -} - -// GetCustomAction fetches custom action by given id. -// -// https://grafana.com/docs/grafana-cloud/oncall/oncall-api-reference/outgoing_webhooks/ -func (service *CustomActionService) GetCustomAction(id string, opt *GetCustomActionOptions) (*CustomAction, *http.Response, error) { - u := fmt.Sprintf("%s/%s/", service.url, id) - - req, err := service.client.NewRequest("GET", u, opt) - if err != nil { - return nil, nil, err - } - - customAction := new(CustomAction) - resp, err := service.client.Do(req, customAction) - if err != nil { - return nil, resp, err - } - - return customAction, resp, err -} - -type CreateCustomActionOptions struct { - Name string `json:"name,omitempty"` - TeamId string `json:"team_id"` - Url string `json:"url,omitempty"` - Data *string `json:"data"` - User *string `json:"user"` - Password *string `json:"password"` - AuthorizationHeader *string `json:"authorization_header"` - ForwardWholePayload bool `json:"forward_whole_payload"` -} - -// CreateCustomAction creates custom action -// -// https://grafana.com/docs/grafana-cloud/oncall/oncall-api-reference/outgoing_webhooks/ -func (service *CustomActionService) CreateCustomAction(opt *CreateCustomActionOptions) (*CustomAction, *http.Response, error) { - u := fmt.Sprintf("%s/", service.url) - - req, err := service.client.NewRequest("POST", u, opt) - if err != nil { - return nil, nil, err - } - - customAction := new(CustomAction) - - resp, err := service.client.Do(req, customAction) - - if err != nil { - return nil, resp, err - } - - return customAction, resp, err -} - -type UpdateCustomActionOptions struct { - Name string `json:"name,omitempty"` - Url string `json:"url"` - Data *string `json:"data"` - User *string `json:"user"` - Password *string `json:"password"` - AuthorizationHeader *string `json:"authorization_header"` - ForwardWholePayload bool `json:"forward_whole_payload"` - TeamId string `json:"team_id"` -} - -// UpdateCustomAction updates custom action -// -// https://grafana.com/docs/grafana-cloud/oncall/oncall-api-reference/outgoing_webhooks/ -func (service *CustomActionService) UpdateCustomAction(id string, opt *UpdateCustomActionOptions) (*CustomAction, *http.Response, error) { - u := fmt.Sprintf("%s/%s/", service.url, id) - - req, err := service.client.NewRequest("PUT", u, opt) - if err != nil { - return nil, nil, err - } - - CustomAction := new(CustomAction) - resp, err := service.client.Do(req, CustomAction) - if err != nil { - return nil, resp, err - } - - return CustomAction, resp, err -} - -type DeleteCustomActionOptions struct { -} - -// DeleteCustomAction deletes custom action. -// -// https://grafana.com/docs/grafana-cloud/oncall/oncall-api-reference/outgoing_webhooks/ -func (service *CustomActionService) DeleteCustomAction(id string, opt *DeleteCustomActionOptions) (*http.Response, error) { - - u := fmt.Sprintf("%s/%s/", service.url, id) - - req, err := service.client.NewRequest("DELETE", u, opt) - if err != nil { - return nil, err - } - - resp, err := service.client.Do(req, nil) - return resp, err -} diff --git a/custom_action_test.go b/custom_action_test.go deleted file mode 100644 index cc0c8a6..0000000 --- a/custom_action_test.go +++ /dev/null @@ -1,119 +0,0 @@ -package aapi - -import ( - "fmt" - "net/http" - "reflect" - "testing" -) - -var testCustomAction = &CustomAction{ - ID: "KGEFG74LU1D8L", - Name: "Test action", - TeamId: "T3HRAP3K3IKOP", -} - -var testCustomActionBody = `{ - "id": "KGEFG74LU1D8L", - "name": "Test action", - "team_id": "T3HRAP3K3IKOP" -}` - -func TestListCustomActions(t *testing.T) { - mux, server, client := setup(t) - defer teardown(server) - - mux.HandleFunc("/api/v1/actions/", func(w http.ResponseWriter, r *http.Request) { - testRequestMethod(t, r, "GET") - fmt.Fprint(w, fmt.Sprintf(`{"count": 1, "next": null, "previous": null, "results": [%s]}`, testCustomActionBody)) - }) - - options := &ListCustomActionOptions{ - Name: "Test action", - } - - customActions, _, err := client.CustomActions.ListCustomActions(options) - if err != nil { - t.Fatal(err) - } - - want := &PaginatedCustomActionsResponse{ - PaginatedResponse: PaginatedResponse{ - Count: 1, - Next: nil, - Previous: nil, - }, - CustomActions: []*CustomAction{ - testCustomAction, - }, - } - if !reflect.DeepEqual(want, customActions) { - t.Errorf("returned\n %+v, \nwant\n %+v", customActions, want) - } -} - -func TestCreateCustomAction(t *testing.T) { - mux, server, client := setup(t) - defer teardown(server) - - mux.HandleFunc("/api/v1/actions/", func(w http.ResponseWriter, r *http.Request) { - testRequestMethod(t, r, "POST") - fmt.Fprint(w, testCustomActionBody) - }) - - createOptions := &CreateCustomActionOptions{ - Name: "Test CustomAction", - Url: "https://example.com", - } - customAction, _, err := client.CustomActions.CreateCustomAction(createOptions) - - if err != nil { - t.Fatal(err) - } - - want := testCustomAction - - if !reflect.DeepEqual(want, customAction) { - t.Errorf("returned\n %+v\n want\n %+v\n", customAction, want) - } -} - -func TestDeleteCustomAction(t *testing.T) { - mux, server, client := setup(t) - defer teardown(server) - - mux.HandleFunc("/api/v1/actions/KGEFG74LU1D8L/", func(w http.ResponseWriter, r *http.Request) { - testRequestMethod(t, r, "DELETE") - }) - - options := &DeleteCustomActionOptions{} - - _, err := client.CustomActions.DeleteCustomAction("KGEFG74LU1D8L", options) - if err != nil { - t.Fatal(err) - } -} - -func TestGetCustomAction(t *testing.T) { - mux, server, client := setup(t) - defer teardown(server) - - mux.HandleFunc("/api/v1/actions/KGEFG74LU1D8L/", func(w http.ResponseWriter, r *http.Request) { - testRequestMethod(t, r, "GET") - fmt.Fprint(w, testCustomActionBody) - }) - - options := &GetCustomActionOptions{} - - customAction, _, err := client.CustomActions.GetCustomAction("KGEFG74LU1D8L", options) - - if err != nil { - t.Fatal(err) - } - - want := testCustomAction - - if !reflect.DeepEqual(want, customAction) { - t.Errorf("returned\n %+v\n want\n %+v\n", customAction, want) - } -} From 697c4098894ed5ed31d141a61a07f0fe08d2ffc9 Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Wed, 19 Jun 2024 16:58:15 -0400 Subject: [PATCH 5/7] add codeowners file --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..492d540 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @grafana/grafana-oncall-backend From ef6111c32df22846dcddb7407c27f95b7ef928ed Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Wed, 3 Jul 2024 11:34:40 -0400 Subject: [PATCH 6/7] WIP --- user_notification_rule.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/user_notification_rule.go b/user_notification_rule.go index f870246..4359f51 100644 --- a/user_notification_rule.go +++ b/user_notification_rule.go @@ -82,11 +82,12 @@ func (service *UserNotificationRuleService) GetUserNotificationRule(id string, o } type CreateUserNotificationRuleOptions struct { - UserId string `json:"user_id,omitempty"` - Position *int `json:"position,omitempty"` - Duration *int `json:"duration,omitempty"` - Important bool `json:"important,omitempty"` - Type string `json:"type,omitempty"` + UserId string `json:"user_id,omitempty"` + Position *int `json:"position,omitempty"` + Duration *int `json:"duration,omitempty"` + Important bool `json:"important,omitempty"` + Type string `json:"type,omitempty"` + ManualOrder bool `json:"manual_order,omitempty"` } // CreateUserNotificationRule creates a user notification rule for the given user, type, and position @@ -112,9 +113,10 @@ func (service *UserNotificationRuleService) CreateUserNotificationRule(opt *Crea } type UpdateUserNotificationRuleOptions struct { - Position *int `json:"position,omitempty"` - Duration *int `json:"duration,omitempty"` - Type string `json:"type,omitempty"` + Position *int `json:"position,omitempty"` + Duration *int `json:"duration,omitempty"` + Type string `json:"type,omitempty"` + ManualOrder bool `json:"manual_order,omitempty"` } // UpdateUserNotificationRule updates user notification rule with new position, duration, and type From a809266dfef168e0eff5ffd10ba9f13084648297 Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Wed, 3 Jul 2024 16:03:56 -0400 Subject: [PATCH 7/7] add test for PUT route --- user_notification_rule_test.go | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/user_notification_rule_test.go b/user_notification_rule_test.go index 51d6ed4..a2ef302 100644 --- a/user_notification_rule_test.go +++ b/user_notification_rule_test.go @@ -36,9 +36,10 @@ func TestCreateUserNotificationRule(t *testing.T) { }) createOptions := &CreateUserNotificationRuleOptions{ - UserId: testUserId, - Important: true, - Type: "notify_by_sms", + UserId: testUserId, + Important: true, + Type: "notify_by_sms", + ManualOrder: true, } userNotificationRule, _, err := client.UserNotificationRules.CreateUserNotificationRule(createOptions) @@ -53,6 +54,33 @@ func TestCreateUserNotificationRule(t *testing.T) { } } +func TestUpdateUserNotificationRule(t *testing.T) { + mux, server, client := setup(t) + defer teardown(server) + + url := fmt.Sprintf("/api/v1/%s/%s/", baseUrl, testId) + mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { + testRequestMethod(t, r, "PUT") + fmt.Fprint(w, testUserNotificationRuleBody) + }) + + updateOptions := &UpdateUserNotificationRuleOptions{ + Type: "notify_by_sms", + ManualOrder: true, + } + userNotificationRule, _, err := client.UserNotificationRules.UpdateUserNotificationRule(testId, updateOptions) + + if err != nil { + t.Fatal(err) + } + + want := testUserNotificationRule + + if !reflect.DeepEqual(want, userNotificationRule) { + t.Errorf("returned\n %+v\n want\n %+v\n", userNotificationRule, want) + } +} + func TestDeleteUserNotificationRule(t *testing.T) { mux, server, client := setup(t) defer teardown(server)