diff --git a/examples/pins/pins.go b/examples/pins/pins.go index 93de5c9..d225184 100644 --- a/examples/pins/pins.go +++ b/examples/pins/pins.go @@ -97,7 +97,7 @@ } // List all of the users pins. - listPins, _, err := api.ListPins(channelID, slack.NewListPinsParameters()) + listPins, _, err := api.ListPins(channelID) if err != nil { fmt.Printf("Error listing pins: %s\n", err) return diff --git a/pins.go b/pins.go index acb4fb8..b95efbb 100644 --- a/pins.go +++ b/pins.go @@ -3,28 +3,7 @@ import ( "errors" "net/url" - "strconv" ) - -const ( - DEFAULT_PINS_COUNT = 100 - DEFAULT_PINS_PAGE = 1 -) - -// ListPinsParameters contains all the optional parameters for the pins.list call -type ListPinsParameters struct { - Count int - Page int -} - -// NewListPinsParameters initializes the inputs to find all pins -// performed by a user. -func NewListPinsParameters() ListPinsParameters { - return ListPinsParameters{ - Count: DEFAULT_PINS_COUNT, - Page: DEFAULT_PINS_PAGE, - } -} type listPinsResponseFull struct { Items []Item @@ -83,16 +62,10 @@ } // ListPins returns information about the items a user reacted to. -func (api *Client) ListPins(channel string, params ListPinsParameters) ([]Item, *Paging, error) { +func (api *Client) ListPins(channel string) ([]Item, *Paging, error) { values := url.Values{ "channel": {channel}, "token": {api.config.token}, - } - if params.Count != DEFAULT_PINS_COUNT { - values.Add("count", strconv.Itoa(params.Count)) - } - if params.Page != DEFAULT_PINS_PAGE { - values.Add("page", strconv.Itoa(params.Page)) } response := &listPinsResponseFull{} err := post("pins.list", values, response, api.debug) diff --git a/pins_test.go b/pins_test.go index ee3f17c..b988521 100644 --- a/pins_test.go +++ b/pins_test.go @@ -202,13 +202,8 @@ } wantParams := map[string]string{ "channel": "ChannelID", - "count": "200", - "page": "2", - } - params := NewListPinsParameters() - params.Count = 200 - params.Page = 2 - got, paging, err := api.ListPins("ChannelID", params) + } + got, paging, err := api.ListPins("ChannelID") if err != nil { t.Fatalf("Unexpected error: %s", err) } diff --git a/stars.go b/stars.go index 3676311..cc12e6e 100644 --- a/stars.go +++ b/stars.go @@ -18,17 +18,15 @@ Page int } -// StarredItem is an item that has been starred. -type StarredItem struct { - Item -} +type StarredItem Item -type starsResponseFull struct { - Items []StarredItem `json:"items"` +type listResponseFull struct { + Items []Item `json:"items"` Paging `json:"paging"` SlackResponse } +// NewStarsParameters initialises StarsParameters with default values func NewStarsParameters() StarsParameters { return StarsParameters{ User: DEFAULT_STARS_USER, @@ -37,17 +35,58 @@ } } -// GetStarred returns a list of StarredItem items. The user then has to iterate over them and figure out what they should -// be looking at according to what is in the Type. -// for _, item := range items { -// switch c.Type { -// case "file_comment": -// log.Println(c.Comment) -// case "file": -// ... -// } -// } -func (api *Client) GetStarred(params StarsParameters) ([]StarredItem, *Paging, error) { +// AddStar stars an item in a channel +func (api *Client) AddStar(channel string, item ItemRef) error { + values := url.Values{ + "channel": {channel}, + "token": {api.config.token}, + } + if item.Timestamp != "" { + values.Set("timestamp", string(item.Timestamp)) + } + if item.File != "" { + values.Set("file", string(item.File)) + } + if item.Comment != "" { + values.Set("file_comment", string(item.Comment)) + } + response := &SlackResponse{} + if err := post("stars.add", values, response, api.debug); err != nil { + return err + } + if !response.Ok { + return errors.New(response.Error) + } + return nil +} + +// RemoveStar removes a starred item from a channel +func (api *Client) RemoveStar(channel string, item ItemRef) error { + values := url.Values{ + "channel": {channel}, + "token": {api.config.token}, + } + if item.Timestamp != "" { + values.Set("timestamp", string(item.Timestamp)) + } + if item.File != "" { + values.Set("file", string(item.File)) + } + if item.Comment != "" { + values.Set("file_comment", string(item.Comment)) + } + response := &SlackResponse{} + if err := post("stars.remove", values, response, api.debug); err != nil { + return err + } + if !response.Ok { + return errors.New(response.Error) + } + return nil +} + +// ListStars returns information about the stars a user added +func (api *Client) ListStars(params StarsParameters) ([]Item, *Paging, error) { values := url.Values{ "token": {api.config.token}, } @@ -60,7 +99,7 @@ if params.Page != DEFAULT_STARS_PAGE { values.Add("page", strconv.Itoa(params.Page)) } - response := &starsResponseFull{} + response := &listResponseFull{} err := post("stars.list", values, response, api.debug) if err != nil { return nil, nil, err @@ -70,3 +109,27 @@ } return response.Items, &response.Paging, nil } + +// GetStarred returns a list of StarredItem items. The user then has to iterate over them and figure out what they should +// be looking at according to what is in the Type. +// for _, item := range items { +// switch c.Type { +// case "file_comment": +// log.Println(c.Comment) +// case "file": +// ... +// +// } +// This function still exists to maintain backwards compatibility. +// I exposed it as returning []StarredItem, so it shall stay as StarredItem +func (api *Client) GetStarred(params StarsParameters) ([]StarredItem, *Paging, error) { + items, paging, err := api.ListStars(params) + if err != nil { + return nil, nil, err + } + starredItems := make([]StarredItem, len(items)) + for i, item := range items { + starredItems[i] = StarredItem(item) + } + return starredItems, paging, nil +} diff --git a/stars_test.go b/stars_test.go index 39993ec..ee8370b 100644 --- a/stars_test.go +++ b/stars_test.go @@ -1,6 +1,7 @@ package slack import ( + "fmt" "net/http" "reflect" "testing" @@ -27,46 +28,149 @@ func (sh *starsHandler) handler(w http.ResponseWriter, r *http.Request) { sh.accumulateFormValue("user", r) sh.accumulateFormValue("count", r) + sh.accumulateFormValue("channel", r) + sh.accumulateFormValue("file", r) + sh.accumulateFormValue("file_comment", r) sh.accumulateFormValue("page", r) + sh.accumulateFormValue("timestamp", r) w.Header().Set("Content-Type", "application/json") w.Write([]byte(sh.response)) } -func TestSlack_GetStarred(t *testing.T) { +func TestSlack_AddStar(t *testing.T) { once.Do(startServer) SLACK_API = "http://" + serverAddr + "/" api := New("testing-token") tests := []struct { - params StarsParameters - wantParams map[string]string - json string - starredItems []StarredItem - paging *Paging + channel string + ref ItemRef + wantParams map[string]string }{ { - StarsParameters{ - User: "U1", - Count: 10, - Page: 100, - }, - map[string]string{ - "user": "U1", - "count": "10", - "page": "100", - }, - `{"ok": true, + "ChannelID", + NewRefToMessage("ChannelID", "123"), + map[string]string{ + "channel": "ChannelID", + "timestamp": "123", + }, + }, + { + "ChannelID", + NewRefToFile("FileID"), + map[string]string{ + "channel": "ChannelID", + "file": "FileID", + }, + }, + { + "ChannelID", + NewRefToComment("FileCommentID"), + map[string]string{ + "channel": "ChannelID", + "file_comment": "FileCommentID", + }, + }, + } + var rh *starsHandler + http.HandleFunc("/stars.add", func(w http.ResponseWriter, r *http.Request) { rh.handler(w, r) }) + for i, test := range tests { + rh = newStarsHandler() + err := api.AddStar(test.channel, test.ref) + if err != nil { + t.Fatalf("%d: Unexpected error: %s", i, err) + } + if !reflect.DeepEqual(rh.gotParams, test.wantParams) { + t.Errorf("%d: Got params %#v, want %#v", i, rh.gotParams, test.wantParams) + } + } +} + +func TestSlack_RemoveStar(t *testing.T) { + once.Do(startServer) + SLACK_API = "http://" + serverAddr + "/" + api := New("testing-token") + tests := []struct { + channel string + ref ItemRef + wantParams map[string]string + }{ + { + "ChannelID", + NewRefToMessage("ChannelID", "123"), + map[string]string{ + "channel": "ChannelID", + "timestamp": "123", + }, + }, + { + "ChannelID", + NewRefToFile("FileID"), + map[string]string{ + "channel": "ChannelID", + "file": "FileID", + }, + }, + { + "ChannelID", + NewRefToComment("FileCommentID"), + map[string]string{ + "channel": "ChannelID", + "file_comment": "FileCommentID", + }, + }, + } + var rh *starsHandler + http.HandleFunc("/stars.remove", func(w http.ResponseWriter, r *http.Request) { rh.handler(w, r) }) + for i, test := range tests { + rh = newStarsHandler() + err := api.RemoveStar(test.channel, test.ref) + if err != nil { + t.Fatalf("%d: Unexpected error: %s", i, err) + } + if !reflect.DeepEqual(rh.gotParams, test.wantParams) { + t.Errorf("%d: Got params %#v, want %#v", i, rh.gotParams, test.wantParams) + } + } +} + +func TestSlack_ListStars(t *testing.T) { + once.Do(startServer) + SLACK_API = "http://" + serverAddr + "/" + api := New("testing-token") + rh := newStarsHandler() + http.HandleFunc("/stars.list", func(w http.ResponseWriter, r *http.Request) { rh.handler(w, r) }) + rh.response = `{"ok": true, "items": [ { "type": "message", - "channel": "C2147483705", + "channel": "C1", "message": { - "text": "hello" + "text": "hello", + "reactions": [ + { + "name": "astonished", + "count": 3, + "users": [ "U1", "U2", "U3" ] + }, + { + "name": "clock1", + "count": 3, + "users": [ "U1", "U2" ] + } + ] } }, { "type": "file", "file": { - "name": "toy" + "name": "toy", + "reactions": [ + { + "name": "clock1", + "count": 3, + "users": [ "U1", "U2" ] + } + ] } }, { @@ -75,20 +179,15 @@ "name": "toy" }, "comment": { - "comment": "nice" + "comment": "cool toy", + "reactions": [ + { + "name": "astonished", + "count": 3, + "users": [ "U1", "U2", "U3" ] + } + ] } - }, - { - "type": "channel", - "channel": "C2147483705" - }, - { - "type": "im", - "channel": "D1" - }, - { - "type": "group", - "channel": "G1" } ], "paging": { @@ -96,40 +195,60 @@ "total": 4, "page": 1, "pages": 1 - }}`, - []StarredItem{ - {Item: NewMessageItem("C2147483705", &Message{Msg: Msg{Text: "hello"}})}, - {Item: NewFileItem(&File{Name: "toy"})}, - {Item: NewFileCommentItem(&File{Name: "toy"}, &Comment{Comment: "nice"})}, - {Item: NewChannelItem("C2147483705")}, - {Item: NewIMItem("D1")}, - {Item: NewGroupItem("G1")}, - }, - &Paging{ - Count: 100, - Total: 4, - Page: 1, - Pages: 1, - }, - }, - } - var sh *starsHandler - http.HandleFunc("/stars.list", func(w http.ResponseWriter, r *http.Request) { sh.handler(w, r) }) - for i, test := range tests { - sh = newStarsHandler() - sh.response = test.json - responseItems, responsePaging, err := api.GetStarred(test.params) - if err != nil { - t.Fatalf("%d Unexpected error: %s", i, err) - } - if !reflect.DeepEqual(sh.gotParams, test.wantParams) { - t.Errorf("%d got %v; want %v", i, sh.gotParams, test.wantParams) - } - if !reflect.DeepEqual(responseItems, test.starredItems) { - t.Errorf("%d got %v; want %v", i, responseItems, test.starredItems) - } - if !reflect.DeepEqual(responsePaging, test.paging) { - t.Errorf("%d got %v; want %v", i, responsePaging, test.paging) - } - } -} + }}` + want := []Item{ + NewMessageItem("C1", &Message{Msg: Msg{Text: "hello"}}), + NewFileItem(&File{Name: "toy"}), + NewFileCommentItem(&File{Name: "toy"}, &Comment{Comment: "cool toy"}), + } + wantStarred := make([]StarredItem, len(want)) + for i, item := range want { + wantStarred[i] = StarredItem(item) + } + wantParams := map[string]string{ + "count": "200", + "page": "2", + } + params := NewStarsParameters() + params.Count = 200 + params.Page = 2 + got, paging, err := api.ListStars(params) + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Got Stars %#v, want %#v", got, want) + for i, item := range got { + fmt.Printf("Item %d, Type: %s\n", i, item.Type) + fmt.Printf("Message %#v\n", item.Message) + fmt.Printf("File %#v\n", item.File) + fmt.Printf("Comment %#v\n", item.Comment) + } + } + if !reflect.DeepEqual(rh.gotParams, wantParams) { + t.Errorf("Got params %#v, want %#v", rh.gotParams, wantParams) + } + if reflect.DeepEqual(paging, Paging{}) { + t.Errorf("Want paging data, got empty struct") + } + // Test GetStarred + gotStarred, paging, err := api.GetStarred(params) + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + if !reflect.DeepEqual(gotStarred, wantStarred) { + t.Errorf("Got Stars %#v, want %#v", gotStarred, wantStarred) + for i, item := range got { + fmt.Printf("Item %d, Type: %s\n", i, item.Type) + fmt.Printf("Message %#v\n", item.Message) + fmt.Printf("File %#v\n", item.File) + fmt.Printf("Comment %#v\n", item.Comment) + } + } + if !reflect.DeepEqual(rh.gotParams, wantParams) { + t.Errorf("Got params %#v, want %#v", rh.gotParams, wantParams) + } + if reflect.DeepEqual(paging, Paging{}) { + t.Errorf("Want paging data, got empty struct") + } +}