From 5a5bb5bfa4abd575c95da30b1d2ed1d24ac9c927 Mon Sep 17 00:00:00 2001 From: Scott McAllister Date: Mon, 13 Apr 2020 16:10:53 -0700 Subject: [PATCH 1/2] WIP: adding ruleset --- ruleset.go | 306 ++++++++++++++++++++++++++++++++++++++++++++++ ruleset_test.go | 315 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 621 insertions(+) create mode 100644 ruleset.go create mode 100644 ruleset_test.go diff --git a/ruleset.go b/ruleset.go new file mode 100644 index 00000000..388b88c0 --- /dev/null +++ b/ruleset.go @@ -0,0 +1,306 @@ +package pagerduty + +import ( + "fmt" + "net/http" +) + +// Ruleset represents a ruleset. +type Ruleset struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + RoutingKeys []string `json:"routing_keys,omitempty"` + Team *RulesetObject `json:"team,omitempty"` + Updater *RulesetObject `json:"updater,omitempty"` + Creator *RulesetObject `json:"creator,omitempty"` +} + +// RulesetObject represents a generic object that is common within a ruleset object +type RulesetObject struct { + Type string `json:"type,omitempty"` + ID string `json:"id,omitempty"` +} + +// RulesetPayload represents payload with a ruleset object +type RulesetPayload struct { + Ruleset *Ruleset `json:"ruleset,omitempty"` +} + +// ListRulesetsResponse represents a list response of rulesets. +type ListRulesetsResponse struct { + Total int `json:"total,omitempty"` + Rulesets []*Ruleset `json:"rulesets,omitempty"` + Offset int `json:"offset,omitempty"` + More bool `json:"more,omitempty"` + Limit int `json:"limit,omitempty"` +} + +// RulesetRule represents a Ruleset rule +type RulesetRule struct { + ID string `json:"id,omitempty"` + Position int `json:"position,omitempty"` + Disabled bool `json:"disabled,omitempty"` + Conditions *RuleConditions `json:"conditions,omitempty"` + Actions *RuleActions `json:"actions,omitempty"` + Ruleset *RulesetReference `json:"ruleset,omitempty"` + Self string `json:"self,omitempty"` + CatchAll bool `json:"catch_all,omitempty"` + TimeFrame *RuleTimeFrame `json:"time_frame,omitempty"` +} + +// RulesetRulePayload represents a payload for ruleset rules +type RulesetRulePayload struct { + Rule *RulesetRule `json:"rule,omitempty"` +} + +// RuleConditions represents the conditions field for a Ruleset +type RuleConditions struct { + Operator string `json:"operator,omitempty"` + RuleSubconditions []*RuleSubcondition `json:"subconditions,omitempty"` +} + +// RuleSubcondition represents a subcondition of a ruleset condition +type RuleSubcondition struct { + Operator string `json:"operator,omitempty"` + Parameters *ConditionParameter `json:"parameters,omitempty"` +} + +// ConditionParameter represents parameters in a rule condition +type ConditionParameter struct { + Path string `json:"path,omitempty"` + Value string `json:"value,omitempty"` +} + +// RuleTimeFrame represents a time_frame object on the rule object +type RuleTimeFrame struct { + ScheduledWeekly *ScheduledWeekly `json:"scheduled_weekly,omitempty"` + ActiveBetween *ActiveBetween `json:"active_between,omitempty"` +} + +// ScheduledWeekly represents a time_frame object for scheduling rules weekly +type ScheduledWeekly struct { + Weekdays []int `json:"weekdays,omitempty"` + Timezone string `json:"timezone,omitempty"` + StartTime int `json:"start_time,omitempty"` + Duration int `json:"duration,omitempty"` +} + +// ActiveBetween represents an active_between object for setting a timeline for rules +type ActiveBetween struct { + StartTime int `json:"start_time,omitempty"` + EndTime int `json:"end_time,omitempty"` +} + +// ListRulesetRulesResponse represents a list of rules in a ruleset +type ListRulesetRulesResponse struct { + Total int `json:"total,omitempty"` + Rules []*RulesetRule `json:"rules,omitempty"` + Offset int `json:"offset,omitempty"` + More bool `json:"more,omitempty"` + Limit int `json:"limit,omitempty"` +} + +// RuleActions represents a rule action +type RuleActions struct { + Suppress *RuleActionSuppress `json:"suppress,omitempty"` + Annotate *RuleActionParameter `json:"annotate,omitempty"` + Severity *RuleActionParameter `json:"severity,omitempty"` + Priority *RuleActionParameter `json:"priority,omitempty"` + Route *RuleActionParameter `json:"route,omitempty"` + EventAction *RuleActionParameter `json:"event_action,omitempty"` + Extractions []*RuleActionExtraction `json:"extractions,omitempty"` +} + +// RuleActionParameter represents a generic parameter object on a rule action +type RuleActionParameter struct { + Value string `json:"value,omitempty"` +} + +// RuleActionSuppress represents a rule suppress action object +type RuleActionSuppress struct { + Value bool `json:"value,omitempty"` + ThresholdValue int `json:"threshold_value,omitempty"` + ThresholdTimeUnit string `json:"threshold_time_unit,omitempty"` + ThresholdTimeAmount int `json:"threshold_time_amount,omitempty"` +} + +// RuleActionExtraction represents a rule extraction action object +type RuleActionExtraction struct { + Target string `json:"target,omitempty"` + Source string `json:"source,omitempty"` + Regex string `json:"regex,omitempty"` +} + +// ListRulesets lists the first page of rulesets of your PagerDuty account. +func (c *Client) ListRulesets() (*ListRulesetsResponse, *http.Response, error) { + // v, err := query.Values(o) + // if err != nil { + // return nil, nil, err + // } + resp, err := c.get("/rulesets") + if err != nil { + return nil, nil, err + } + var result ListRulesetsResponse + return &result, resp, c.decodeJSON(resp, &result) +} + +// ListAllRulesets gets all rulesets. +func (c *Client) ListAllRulesets() ([]Ruleset, error) { + rulesets := make([]Ruleset, 0) + + // Create a handler closure capable of parsing data from the rulesets endpoint + // and appending resultant rulesets to the return slice. + responseHandler := func(response *http.Response) (APIListObject, error) { + var result ListRulesetsResponse + if err := c.decodeJSON(response, &result); err != nil { + return APIListObject{}, err + } + + rulesets = append(rulesets, result.Rulesets...) + + // Return stats on the current page. Caller can use this information to + // adjust for requesting additional pages. + return APIListObject{ + More: result.More, + Offset: result.Offset, + Limit: result.Limit, + }, nil + } + + // Make call to get all pages associated with the base endpoint. + if err := c.pagedGet("/rulesets/", responseHandler); err != nil { + return nil, err + } + + return rulesets, nil +} + +// CreateRuleset creates a new user. +func (c *Client) CreateRuleset(r *Ruleset) (*Ruleset, *Response, error) { + data := make(map[string]Ruleset) + data["ruleset"] = r + resp, err := c.post("/rulesets", data, nil) + return getRulesetFromResponse(c, resp, err) +} + +// DeleteRuleset deletes a user. +func (c *Client) DeleteRuleset(id string) error { + _, err := c.delete("/rulesets/" + id) + return err +} + +// GetRuleset gets details about a ruleset. +func (c *Client) GetRuleset(id string) (*User, *Response, error) { + resp, err := c.get("/rulesets/" + id) + return getRulesetFromResponse(c, resp, err) +} + +// UpdateRuleset updates a ruleset. +func (c *Client) UpdateRuleset(r *Ruleset) (*Ruleset, *Response, error) { + v := make(map[string]Ruleset) + v["ruleset"] = r + resp, err := c.put("/rulesets/"+r.ID, v, nil) + return getRulesetFromResponse(c, resp, err) +} + +func getRulesetFromResponse(c *Client, resp *http.Response, err error) (*User, *Response, error) { + if err != nil { + return nil, err + } + var target map[string]User + if dErr := c.decodeJSON(resp, &target); dErr != nil { + return nil, fmt.Errorf("Could not decode JSON response: %v", dErr) + } + t, nodeOK := target["ruleset"] + if !nodeOK { + return nil, fmt.Errorf("JSON response does not have %s field", rootNode) + } + return &t, resp, nil +} + +// ListRulesetRules fetches rules of ruleset. +func (c *Client) ListRulesetRules(rulesetID string) (*ListRulesetRulesResponse, *Response, error) { + resp, err := c.get("/rulesets/" + rulesetID + "/rules") + if err != nil { + return nil, err + } + var result ListRulesetRulesResponse + return &result, resp, c.decodeJSON(resp, &result) +} + +// ListAllRulesetRules gets all rules for a ruleset. +func (c *Client) ListAllRulesetRules(rulesetID) ([]RulesetRule, error) { + rules := make([]RulesetRule, 0) + + // Create a handler closure capable of parsing data from the ruleset rules endpoint + // and appending resultant ruleset rules to the return slice. + responseHandler := func(response *http.Response) (APIListObject, error) { + var result ListRulesetRulesResponse + if err := c.decodeJSON(response, &result); err != nil { + return APIListObject{}, err + } + + rules = append(rules, result.Rules...) + + // Return stats on the current page. Caller can use this information to + // adjust for requesting additional pages. + return APIListObject{ + More: result.More, + Offset: result.Offset, + Limit: result.Limit, + }, nil + } + + // Make call to get all pages associated with the base endpoint. + if err := c.pagedGet("/rulesets/", responseHandler); err != nil { + return nil, err + } + + return rulesets, nil +} + +// GetRulesetRule gets an event rule +func (c *Client) GetRulesetRule(rulesetID, ruleID string) (*RulesetRule, *Response, error) { + resp, err := c.get("/rulesets/" + rulesetID + "/rules/" + ruleID) + return getRuleFromResponse(c, resp, err) +} + +// DeleteRulesetRule deletes a rule. +func (c *Client) DeleteRulesetRule(rulesetID, ruleID string) error { + _, err := c.get("/rulesets/" + rulesetID + "/rules/" + ruleID) + return err +} + +// CreateRulesetRule creates a new rule for a ruleset. +func (c *Client) CreateRulesetRule(rulesetID string, rule *RulesetRule) (*RulesetRule, *Response, error) { + data := make(map[string]RulesetRule) + data["rule"] = rule + resp, err := c.post("/rulesets/"+rulesetID+"/rules/", data, nil) + return getRuleFromResponse(c, resp, err) +} + +// UpdateRulesetRule updates a rule. +func (c *Client) UpdateRulesetRule(rulesetID, ruleID string, r *RulesetRule) (*RulesetRule, *Response, error) { + v := make(map[string]RulesetRule) + v["rule"] = r + resp, err := c.put("/rulesets/"+rulesetID+"/rules/"+ruleID, v, nil) + return getRuleFromResponse(c, resp, err) +} + +func getRuleFromResponse(c *Client, resp *http.Response, err error) (*RulesetRule, *Response, error) { + if err != nil { + return nil, err + } + var target map[string]RulesetRule + if dErr := c.decodeJSON(resp, &target); dErr != nil { + return nil, fmt.Errorf("Could not decode JSON response: %v", dErr) + } + rootNode := "rule" + t, nodeOK := target[rootNode] + if !nodeOK { + return nil, fmt.Errorf("JSON response does not have %s field", rootNode) + } + return &t, resp, nil +} diff --git a/ruleset_test.go b/ruleset_test.go new file mode 100644 index 00000000..924ef3fb --- /dev/null +++ b/ruleset_test.go @@ -0,0 +1,315 @@ +package pagerduty + +import ( + "net/http" + "testing" +) + +// ListUsers +func TestUser_List(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.Write([]byte(`{"users": [{"id": "1"}]}`)) + }) + + var listObj = APIListObject{Limit: 0, Offset: 0, More: false, Total: 0} + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + var opts = ListUsersOptions{ + APIListObject: listObj, + Query: "foo", + TeamIDs: []string{}, + Includes: []string{}, + } + res, err := client.ListUsers(opts) + + want := &ListUsersResponse{ + APIListObject: listObj, + Users: []User{ + { + APIObject: APIObject{ + ID: "1", + }, + }, + }, + } + + if err != nil { + t.Fatal(err) + } + testEqual(t, want, res) +} + +// Create User +func TestUser_Create(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + w.Write([]byte(`{"user": {"id": "1", "email":"foo@bar.com"}}`)) + }) + + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + input := User{ + Email: "foo@bar.com", + } + res, err := client.CreateUser(input) + + want := &User{ + APIObject: APIObject{ + ID: "1", + }, + Email: "foo@bar.com", + } + + if err != nil { + t.Fatal(err) + } + testEqual(t, want, res) +} + +// Delete User +func TestUser_Delete(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + id := "1" + err := client.DeleteUser(id) + + if err != nil { + t.Fatal(err) + } +} + +// Get User +func TestUser_Get(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.Write([]byte(`{"user": {"id": "1", "email":"foo@bar.com"}}`)) + }) + + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + userID := "1" + opts := GetUserOptions{ + Includes: []string{}, + } + res, err := client.GetUser(userID, opts) + + want := &User{ + APIObject: APIObject{ + ID: "1", + }, + Email: "foo@bar.com", + } + + if err != nil { + t.Fatal(err) + } + testEqual(t, want, res) +} + +// Update +func TestUser_Update(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + w.Write([]byte(`{"user": {"id": "1", "email":"foo@bar.com"}}`)) + }) + + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + input := User{ + APIObject: APIObject{ + ID: "1", + }, + Email: "foo@bar.com", + } + res, err := client.UpdateUser(input) + + want := &User{ + APIObject: APIObject{ + ID: "1", + }, + Email: "foo@bar.com", + } + + if err != nil { + t.Fatal(err) + } + testEqual(t, want, res) +} + +// Get Current User +func TestUser_GetCurrent(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users/me", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.Write([]byte(`{"user": {"id": "1", "email":"foo@bar.com"}}`)) + }) + + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + opts := GetCurrentUserOptions{ + Includes: []string{}, + } + res, err := client.GetCurrentUser(opts) + + want := &User{ + APIObject: APIObject{ + ID: "1", + }, + Email: "foo@bar.com", + } + + if err != nil { + t.Fatal(err) + } + testEqual(t, want, res) +} + +// List User Contactmethods +func TestUser_ListContactMethods(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users/1/contact_methods", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.Write([]byte(`{"contact_methods": [{"id": "1"}]}`)) + }) + + var listObj = APIListObject{Limit: 0, Offset: 0, More: false, Total: 0} + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + ID := "1" + + res, err := client.ListUserContactMethods(ID) + + want := &ListContactMethodsResponse{ + APIListObject: listObj, + ContactMethods: []ContactMethod{ + { + ID: "1", + }, + }, + } + + if err != nil { + t.Fatal(err) + } + testEqual(t, want, res) +} + +// Get user ContactMethod +func TestUser_GetContactMethod(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users/1/contact_methods/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.Write([]byte(`{"contact_method": {"id": "1"}}`)) + }) + + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + methodID := "1" + userID := "1" + + res, err := client.GetUserContactMethod(userID, methodID) + + want := &ContactMethod{ + ID: "1", + } + + if err != nil { + t.Fatal(err) + } + testEqual(t, want, res) +} + +// Create user ContactMethod +func TestUser_CreateContactMethod(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users/1/contact_methods", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + w.Write([]byte(`{"contact_method": {"id": "1", "type": "email_contact_method"}}`)) + }) + + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + userID := "1" + contactMethod := ContactMethod{ + Type: "email_contact_method", + } + res, err := client.CreateUserContactMethod(userID, contactMethod) + + want := &ContactMethod{ + ID: "1", + Type: "email_contact_method", + } + + if err != nil { + t.Fatal(err) + } + testEqual(t, want, res) +} + +// Delete User Contactmethod +func TestUser_DeleteContactMethod(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users/1/contact_methods/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + userID := "1" + contactMethodID := "1" + + err := client.DeleteUserContactMethod(userID, contactMethodID) + + if err != nil { + t.Fatal(err) + } +} + +// Update User ContactMethod +func TestUser_UpdateContactMethod(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/users/1/contact_methods/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + w.Write([]byte(`{"contact_method": {"id": "1", "type": "email_contact_method"}}`)) + }) + + var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} + userID := "1" + contactMethod := ContactMethod{ + ID: "1", + Type: "email_contact_method", + } + res, err := client.UpdateUserContactMethod(userID, contactMethod) + + want := &ContactMethod{ + ID: "1", + Type: "email_contact_method", + } + + if err != nil { + t.Fatal(err) + } + testEqual(t, want, res) +} From b9031f2e3bff78c98849dcdc9bf8c5ca647c3841 Mon Sep 17 00:00:00 2001 From: Scott McAllister Date: Wed, 3 Jun 2020 19:04:44 -0700 Subject: [PATCH 2/2] finishing tests for ruleset --- ruleset.go | 117 +++++++++------------- ruleset_test.go | 261 +++++++++++++++++++----------------------------- 2 files changed, 151 insertions(+), 227 deletions(-) diff --git a/ruleset.go b/ruleset.go index 388b88c0..0fb9dd75 100644 --- a/ruleset.go +++ b/ruleset.go @@ -29,24 +29,24 @@ type RulesetPayload struct { // ListRulesetsResponse represents a list response of rulesets. type ListRulesetsResponse struct { - Total int `json:"total,omitempty"` + Total uint `json:"total,omitempty"` Rulesets []*Ruleset `json:"rulesets,omitempty"` - Offset int `json:"offset,omitempty"` + Offset uint `json:"offset,omitempty"` More bool `json:"more,omitempty"` - Limit int `json:"limit,omitempty"` + Limit uint `json:"limit,omitempty"` } // RulesetRule represents a Ruleset rule type RulesetRule struct { - ID string `json:"id,omitempty"` - Position int `json:"position,omitempty"` - Disabled bool `json:"disabled,omitempty"` - Conditions *RuleConditions `json:"conditions,omitempty"` - Actions *RuleActions `json:"actions,omitempty"` - Ruleset *RulesetReference `json:"ruleset,omitempty"` - Self string `json:"self,omitempty"` - CatchAll bool `json:"catch_all,omitempty"` - TimeFrame *RuleTimeFrame `json:"time_frame,omitempty"` + ID string `json:"id,omitempty"` + Position int `json:"position,omitempty"` + Disabled bool `json:"disabled,omitempty"` + Conditions *RuleConditions `json:"conditions,omitempty"` + Actions *RuleActions `json:"actions,omitempty"` + Ruleset *APIObject `json:"ruleset,omitempty"` + Self string `json:"self,omitempty"` + CatchAll bool `json:"catch_all,omitempty"` + TimeFrame *RuleTimeFrame `json:"time_frame,omitempty"` } // RulesetRulePayload represents a payload for ruleset rules @@ -94,11 +94,11 @@ type ActiveBetween struct { // ListRulesetRulesResponse represents a list of rules in a ruleset type ListRulesetRulesResponse struct { - Total int `json:"total,omitempty"` + Total uint `json:"total,omitempty"` Rules []*RulesetRule `json:"rules,omitempty"` - Offset int `json:"offset,omitempty"` + Offset uint `json:"offset,omitempty"` More bool `json:"more,omitempty"` - Limit int `json:"limit,omitempty"` + Limit uint `json:"limit,omitempty"` } // RuleActions represents a rule action @@ -132,23 +132,10 @@ type RuleActionExtraction struct { Regex string `json:"regex,omitempty"` } -// ListRulesets lists the first page of rulesets of your PagerDuty account. -func (c *Client) ListRulesets() (*ListRulesetsResponse, *http.Response, error) { - // v, err := query.Values(o) - // if err != nil { - // return nil, nil, err - // } - resp, err := c.get("/rulesets") - if err != nil { - return nil, nil, err - } - var result ListRulesetsResponse - return &result, resp, c.decodeJSON(resp, &result) -} - -// ListAllRulesets gets all rulesets. -func (c *Client) ListAllRulesets() ([]Ruleset, error) { - rulesets := make([]Ruleset, 0) +// ListRulesets gets all rulesets. +func (c *Client) ListRulesets() (*ListRulesetsResponse, error) { + rulesetResponse := new(ListRulesetsResponse) + rulesets := make([]*Ruleset, 0) // Create a handler closure capable of parsing data from the rulesets endpoint // and appending resultant rulesets to the return slice. @@ -173,13 +160,14 @@ func (c *Client) ListAllRulesets() ([]Ruleset, error) { if err := c.pagedGet("/rulesets/", responseHandler); err != nil { return nil, err } + rulesetResponse.Rulesets = rulesets - return rulesets, nil + return rulesetResponse, nil } // CreateRuleset creates a new user. -func (c *Client) CreateRuleset(r *Ruleset) (*Ruleset, *Response, error) { - data := make(map[string]Ruleset) +func (c *Client) CreateRuleset(r *Ruleset) (*Ruleset, *http.Response, error) { + data := make(map[string]*Ruleset) data["ruleset"] = r resp, err := c.post("/rulesets", data, nil) return getRulesetFromResponse(c, resp, err) @@ -192,52 +180,44 @@ func (c *Client) DeleteRuleset(id string) error { } // GetRuleset gets details about a ruleset. -func (c *Client) GetRuleset(id string) (*User, *Response, error) { +func (c *Client) GetRuleset(id string) (*Ruleset, *http.Response, error) { resp, err := c.get("/rulesets/" + id) return getRulesetFromResponse(c, resp, err) } // UpdateRuleset updates a ruleset. -func (c *Client) UpdateRuleset(r *Ruleset) (*Ruleset, *Response, error) { - v := make(map[string]Ruleset) +func (c *Client) UpdateRuleset(r *Ruleset) (*Ruleset, *http.Response, error) { + v := make(map[string]*Ruleset) v["ruleset"] = r resp, err := c.put("/rulesets/"+r.ID, v, nil) return getRulesetFromResponse(c, resp, err) } -func getRulesetFromResponse(c *Client, resp *http.Response, err error) (*User, *Response, error) { +func getRulesetFromResponse(c *Client, resp *http.Response, err error) (*Ruleset, *http.Response, error) { if err != nil { - return nil, err + return nil, nil, err } - var target map[string]User + var target map[string]Ruleset if dErr := c.decodeJSON(resp, &target); dErr != nil { - return nil, fmt.Errorf("Could not decode JSON response: %v", dErr) + return nil, nil, fmt.Errorf("Could not decode JSON response: %v", dErr) } t, nodeOK := target["ruleset"] if !nodeOK { - return nil, fmt.Errorf("JSON response does not have %s field", rootNode) + return nil, nil, fmt.Errorf("JSON response does not have ruleset field") } return &t, resp, nil } -// ListRulesetRules fetches rules of ruleset. -func (c *Client) ListRulesetRules(rulesetID string) (*ListRulesetRulesResponse, *Response, error) { - resp, err := c.get("/rulesets/" + rulesetID + "/rules") - if err != nil { - return nil, err - } - var result ListRulesetRulesResponse - return &result, resp, c.decodeJSON(resp, &result) -} - -// ListAllRulesetRules gets all rules for a ruleset. -func (c *Client) ListAllRulesetRules(rulesetID) ([]RulesetRule, error) { - rules := make([]RulesetRule, 0) +// ListRulesetRules gets all rules for a ruleset. +func (c *Client) ListRulesetRules(rulesetID string) (*ListRulesetRulesResponse, error) { + rulesResponse := new(ListRulesetRulesResponse) + rules := make([]*RulesetRule, 0) // Create a handler closure capable of parsing data from the ruleset rules endpoint // and appending resultant ruleset rules to the return slice. responseHandler := func(response *http.Response) (APIListObject, error) { var result ListRulesetRulesResponse + if err := c.decodeJSON(response, &result); err != nil { return APIListObject{}, err } @@ -254,53 +234,54 @@ func (c *Client) ListAllRulesetRules(rulesetID) ([]RulesetRule, error) { } // Make call to get all pages associated with the base endpoint. - if err := c.pagedGet("/rulesets/", responseHandler); err != nil { + if err := c.pagedGet("/rulesets/"+rulesetID+"/rules", responseHandler); err != nil { return nil, err } + rulesResponse.Rules = rules - return rulesets, nil + return rulesResponse, nil } // GetRulesetRule gets an event rule -func (c *Client) GetRulesetRule(rulesetID, ruleID string) (*RulesetRule, *Response, error) { +func (c *Client) GetRulesetRule(rulesetID, ruleID string) (*RulesetRule, *http.Response, error) { resp, err := c.get("/rulesets/" + rulesetID + "/rules/" + ruleID) return getRuleFromResponse(c, resp, err) } // DeleteRulesetRule deletes a rule. func (c *Client) DeleteRulesetRule(rulesetID, ruleID string) error { - _, err := c.get("/rulesets/" + rulesetID + "/rules/" + ruleID) + _, err := c.delete("/rulesets/" + rulesetID + "/rules/" + ruleID) return err } // CreateRulesetRule creates a new rule for a ruleset. -func (c *Client) CreateRulesetRule(rulesetID string, rule *RulesetRule) (*RulesetRule, *Response, error) { - data := make(map[string]RulesetRule) +func (c *Client) CreateRulesetRule(rulesetID string, rule *RulesetRule) (*RulesetRule, *http.Response, error) { + data := make(map[string]*RulesetRule) data["rule"] = rule resp, err := c.post("/rulesets/"+rulesetID+"/rules/", data, nil) return getRuleFromResponse(c, resp, err) } // UpdateRulesetRule updates a rule. -func (c *Client) UpdateRulesetRule(rulesetID, ruleID string, r *RulesetRule) (*RulesetRule, *Response, error) { - v := make(map[string]RulesetRule) +func (c *Client) UpdateRulesetRule(rulesetID, ruleID string, r *RulesetRule) (*RulesetRule, *http.Response, error) { + v := make(map[string]*RulesetRule) v["rule"] = r resp, err := c.put("/rulesets/"+rulesetID+"/rules/"+ruleID, v, nil) return getRuleFromResponse(c, resp, err) } -func getRuleFromResponse(c *Client, resp *http.Response, err error) (*RulesetRule, *Response, error) { +func getRuleFromResponse(c *Client, resp *http.Response, err error) (*RulesetRule, *http.Response, error) { if err != nil { - return nil, err + return nil, nil, err } var target map[string]RulesetRule if dErr := c.decodeJSON(resp, &target); dErr != nil { - return nil, fmt.Errorf("Could not decode JSON response: %v", dErr) + return nil, nil, fmt.Errorf("Could not decode JSON response: %v", dErr) } rootNode := "rule" t, nodeOK := target[rootNode] if !nodeOK { - return nil, fmt.Errorf("JSON response does not have %s field", rootNode) + return nil, nil, fmt.Errorf("JSON response does not have %s field", rootNode) } return &t, resp, nil } diff --git a/ruleset_test.go b/ruleset_test.go index 924ef3fb..90e2e6d3 100644 --- a/ruleset_test.go +++ b/ruleset_test.go @@ -5,64 +5,52 @@ import ( "testing" ) -// ListUsers -func TestUser_List(t *testing.T) { +// List Rulesets +func TestRuleset_List(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/rulesets/", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - w.Write([]byte(`{"users": [{"id": "1"}]}`)) + w.Write([]byte(`{"rulesets": [{"id": "1"}]}`)) }) - var listObj = APIListObject{Limit: 0, Offset: 0, More: false, Total: 0} var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - var opts = ListUsersOptions{ - APIListObject: listObj, - Query: "foo", - TeamIDs: []string{}, - Includes: []string{}, - } - res, err := client.ListUsers(opts) - want := &ListUsersResponse{ - APIListObject: listObj, - Users: []User{ + res, err := client.ListRulesets() + if err != nil { + t.Fatal(err) + } + want := &ListRulesetsResponse{ + Rulesets: []*Ruleset{ { - APIObject: APIObject{ - ID: "1", - }, + ID: "1", }, }, } - if err != nil { - t.Fatal(err) - } testEqual(t, want, res) } -// Create User -func TestUser_Create(t *testing.T) { +// Create Ruleset +func TestUser_Ruleset(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - w.Write([]byte(`{"user": {"id": "1", "email":"foo@bar.com"}}`)) + w.Write([]byte(`{"ruleset": {"id": "1", "name": "foo"}}`)) }) var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - input := User{ - Email: "foo@bar.com", + input := &Ruleset{ + Name: "foo", } - res, err := client.CreateUser(input) + res, _, err := client.CreateRuleset(input) - want := &User{ - APIObject: APIObject{ - ID: "1", - }, - Email: "foo@bar.com", + want := &Ruleset{ + ID: "1", + Name: "foo", } if err != nil { @@ -71,46 +59,24 @@ func TestUser_Create(t *testing.T) { testEqual(t, want, res) } -// Delete User -func TestUser_Delete(t *testing.T) { +// Get Ruleset +func TestRuleset_Get(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users/1", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "DELETE") - }) - - var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - id := "1" - err := client.DeleteUser(id) - - if err != nil { - t.Fatal(err) - } -} - -// Get User -func TestUser_Get(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/users/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/rulesets/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - w.Write([]byte(`{"user": {"id": "1", "email":"foo@bar.com"}}`)) + w.Write([]byte(`{"ruleset": {"id": "1", "name":"foo"}}`)) }) var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - userID := "1" - opts := GetUserOptions{ - Includes: []string{}, - } - res, err := client.GetUser(userID, opts) + ruleSetID := "1" - want := &User{ - APIObject: APIObject{ - ID: "1", - }, - Email: "foo@bar.com", + res, _, err := client.GetRuleset(ruleSetID) + + want := &Ruleset{ + ID: "1", + Name: "foo", } if err != nil { @@ -119,30 +85,26 @@ func TestUser_Get(t *testing.T) { testEqual(t, want, res) } -// Update -func TestUser_Update(t *testing.T) { +// Update Ruleset +func TestRuleset_Update(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/rulesets/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") - w.Write([]byte(`{"user": {"id": "1", "email":"foo@bar.com"}}`)) + w.Write([]byte(`{"ruleset": {"id": "1", "name":"foo"}}`)) }) var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - input := User{ - APIObject: APIObject{ - ID: "1", - }, - Email: "foo@bar.com", + input := &Ruleset{ + ID: "1", + Name: "foo", } - res, err := client.UpdateUser(input) + res, _, err := client.UpdateRuleset(input) - want := &User{ - APIObject: APIObject{ - ID: "1", - }, - Email: "foo@bar.com", + want := &Ruleset{ + ID: "1", + Name: "foo", } if err != nil { @@ -151,165 +113,146 @@ func TestUser_Update(t *testing.T) { testEqual(t, want, res) } -// Get Current User -func TestUser_GetCurrent(t *testing.T) { +// Delete Ruleset +func TestRuleset_Delete(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users/me", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - w.Write([]byte(`{"user": {"id": "1", "email":"foo@bar.com"}}`)) + mux.HandleFunc("/rulesets/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") }) var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - opts := GetCurrentUserOptions{ - Includes: []string{}, - } - res, err := client.GetCurrentUser(opts) - - want := &User{ - APIObject: APIObject{ - ID: "1", - }, - Email: "foo@bar.com", - } + id := "1" + err := client.DeleteRuleset(id) if err != nil { t.Fatal(err) } - testEqual(t, want, res) } -// List User Contactmethods -func TestUser_ListContactMethods(t *testing.T) { +// List Ruleset Rules +func TestRuleset_ListRules(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users/1/contact_methods", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/rulesets/1/rules", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - w.Write([]byte(`{"contact_methods": [{"id": "1"}]}`)) + w.Write([]byte(`{"rules": [{"id": "1"}]}`)) }) - var listObj = APIListObject{Limit: 0, Offset: 0, More: false, Total: 0} var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - ID := "1" - res, err := client.ListUserContactMethods(ID) + rulesetID := "1" + res, err := client.ListRulesetRules(rulesetID) + if err != nil { + t.Fatal(err) + } - want := &ListContactMethodsResponse{ - APIListObject: listObj, - ContactMethods: []ContactMethod{ + want := &ListRulesetRulesResponse{ + Rules: []*RulesetRule{ { ID: "1", }, }, } - - if err != nil { - t.Fatal(err) - } testEqual(t, want, res) } -// Get user ContactMethod -func TestUser_GetContactMethod(t *testing.T) { +// Get Ruleset Rule +func TestRuleset_GetRule(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users/1/contact_methods/1", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/rulesets/1/rules/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - w.Write([]byte(`{"contact_method": {"id": "1"}}`)) + w.Write([]byte(`{"rule": {"id": "1"}}`)) }) var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - methodID := "1" - userID := "1" - - res, err := client.GetUserContactMethod(userID, methodID) - - want := &ContactMethod{ - ID: "1", - } + rulesetID := "1" + ruleID := "1" + res, _, err := client.GetRulesetRule(rulesetID, ruleID) if err != nil { t.Fatal(err) } + + want := &RulesetRule{ + ID: "1", + } testEqual(t, want, res) } -// Create user ContactMethod -func TestUser_CreateContactMethod(t *testing.T) { +// Create Ruleset Rule +func TestRuleset_CreateRule(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users/1/contact_methods", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/rulesets/1/rules/", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - w.Write([]byte(`{"contact_method": {"id": "1", "type": "email_contact_method"}}`)) + w.Write([]byte(`{"rule": {"id": "1"}}`)) }) var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - userID := "1" - contactMethod := ContactMethod{ - Type: "email_contact_method", - } - res, err := client.CreateUserContactMethod(userID, contactMethod) - want := &ContactMethod{ - ID: "1", - Type: "email_contact_method", - } + rulesetID := "1" + rule := &RulesetRule{} + res, _, err := client.CreateRulesetRule(rulesetID, rule) if err != nil { t.Fatal(err) } + + want := &RulesetRule{ + ID: "1", + } testEqual(t, want, res) } -// Delete User Contactmethod -func TestUser_DeleteContactMethod(t *testing.T) { +// Update Ruleset Rule +func TestRuleset_UpdateRule(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users/1/contact_methods/1", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "DELETE") + mux.HandleFunc("/rulesets/1/rules/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + w.Write([]byte(`{"rule": {"id": "1"}}`)) }) var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - userID := "1" - contactMethodID := "1" - err := client.DeleteUserContactMethod(userID, contactMethodID) + rulesetID := "1" + ruleID := "1" + rule := &RulesetRule{} + res, _, err := client.UpdateRulesetRule(rulesetID, ruleID, rule) if err != nil { t.Fatal(err) } + + want := &RulesetRule{ + ID: "1", + } + testEqual(t, want, res) } -// Update User ContactMethod -func TestUser_UpdateContactMethod(t *testing.T) { +// Delete Ruleset Rule +func TestRuleset_DeleteRule(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/users/1/contact_methods/1", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "PUT") - w.Write([]byte(`{"contact_method": {"id": "1", "type": "email_contact_method"}}`)) + mux.HandleFunc("/rulesets/1/rules/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") }) var client = &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient} - userID := "1" - contactMethod := ContactMethod{ - ID: "1", - Type: "email_contact_method", - } - res, err := client.UpdateUserContactMethod(userID, contactMethod) + ruleID := "1" + rulesetID := "1" - want := &ContactMethod{ - ID: "1", - Type: "email_contact_method", - } + err := client.DeleteRulesetRule(rulesetID, ruleID) if err != nil { t.Fatal(err) } - testEqual(t, want, res) }