diff options
author | Saturnino Abril <saturnino.abril@gmail.com> | 2017-03-13 21:26:51 +0900 |
---|---|---|
committer | George Goldberg <george@gberg.me> | 2017-03-13 12:26:51 +0000 |
commit | 8731465957ba41c1f828285e19ee3bb234e2ef58 (patch) | |
tree | 4051efe2fb0ec981e7004c32cf79d3592471fdfb | |
parent | 3559fb7959cf008b038239f2e7c43e604c44cd31 (diff) | |
download | chat-8731465957ba41c1f828285e19ee3bb234e2ef58.tar.gz chat-8731465957ba41c1f828285e19ee3bb234e2ef58.tar.bz2 chat-8731465957ba41c1f828285e19ee3bb234e2ef58.zip |
Endpoint for APIv4: GET /team/{team_id}/channels (#5681)
-rw-r--r-- | api4/channel.go | 22 | ||||
-rw-r--r-- | api4/channel_test.go | 80 | ||||
-rw-r--r-- | app/channel.go | 8 | ||||
-rw-r--r-- | i18n/en.json | 4 | ||||
-rw-r--r-- | model/client4.go | 15 | ||||
-rw-r--r-- | store/sql_channel_store.go | 34 | ||||
-rw-r--r-- | store/sql_channel_store_test.go | 85 | ||||
-rw-r--r-- | store/store.go | 1 |
8 files changed, 249 insertions, 0 deletions
diff --git a/api4/channel.go b/api4/channel.go index 8be522484..d86e54039 100644 --- a/api4/channel.go +++ b/api4/channel.go @@ -18,6 +18,8 @@ func InitChannel() { BaseRoutes.Channels.Handle("", ApiSessionRequired(createChannel)).Methods("POST") BaseRoutes.Channels.Handle("/direct", ApiSessionRequired(createDirectChannel)).Methods("POST") + BaseRoutes.Team.Handle("/channels", ApiSessionRequired(getPublicChannelsForTeam)).Methods("GET") + BaseRoutes.Channel.Handle("", ApiSessionRequired(getChannel)).Methods("GET") BaseRoutes.ChannelByName.Handle("", ApiSessionRequired(getChannelByName)).Methods("GET") BaseRoutes.ChannelByNameForTeamName.Handle("", ApiSessionRequired(getChannelByNameForTeamName)).Methods("GET") @@ -115,6 +117,26 @@ func getChannel(c *Context, w http.ResponseWriter, r *http.Request) { } } +func getPublicChannelsForTeam(c *Context, w http.ResponseWriter, r *http.Request) { + c.RequireTeamId() + if c.Err != nil { + return + } + + if !app.SessionHasPermissionToTeam(c.Session, c.Params.TeamId, model.PERMISSION_LIST_TEAM_CHANNELS) { + c.SetPermissionError(model.PERMISSION_LIST_TEAM_CHANNELS) + return + } + + if channels, err := app.GetPublicChannelsForTeam(c.Params.TeamId, c.Params.Page, c.Params.PerPage); err != nil { + c.Err = err + return + } else { + w.Write([]byte(channels.ToJson())) + return + } +} + func getChannelByName(c *Context, w http.ResponseWriter, r *http.Request) { c.RequireTeamId().RequireChannelName() if c.Err != nil { diff --git a/api4/channel_test.go b/api4/channel_test.go index c8faf7aa1..a7dbb958b 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -254,6 +254,86 @@ func TestGetChannel(t *testing.T) { CheckNotFoundStatus(t, resp) } +func TestGetPublicChannelsForTeam(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer TearDown() + Client := th.Client + team := th.BasicTeam + publicChannel1 := th.BasicChannel + publicChannel2 := th.BasicChannel2 + + channels, resp := Client.GetPublicChannelsForTeam(team.Id, 0, 100, "") + CheckNoError(t, resp) + if len(*channels) != 4 { + t.Fatal("wrong length") + } + + for i, c := range *channels { + if c.Type != model.CHANNEL_OPEN { + t.Fatal("should include open channel only") + } + + // only check the created 2 public channels + if i < 2 && !(c.DisplayName == publicChannel1.DisplayName || c.DisplayName == publicChannel2.DisplayName) { + t.Logf("channel %v: %v", i, c.DisplayName) + t.Fatal("should match public channel display name only") + } + } + + privateChannel := th.CreatePrivateChannel() + channels, resp = Client.GetPublicChannelsForTeam(team.Id, 0, 100, "") + CheckNoError(t, resp) + if len(*channels) != 4 { + t.Fatal("wrong length") + } + + for _, c := range *channels { + if c.Type != model.CHANNEL_OPEN { + t.Fatal("should not include private channel") + } + + if c.DisplayName == privateChannel.DisplayName { + t.Fatal("should not match private channel display name") + } + } + + channels, resp = Client.GetPublicChannelsForTeam(team.Id, 0, 1, "") + CheckNoError(t, resp) + if len(*channels) != 1 { + t.Fatal("should be one channel per page") + } + + channels, resp = Client.GetPublicChannelsForTeam(team.Id, 1, 1, "") + CheckNoError(t, resp) + if len(*channels) != 1 { + t.Fatal("should be one channel per page") + } + + channels, resp = Client.GetPublicChannelsForTeam(team.Id, 10000, 100, "") + CheckNoError(t, resp) + if len(*channels) != 0 { + t.Fatal("should be no channel") + } + + _, resp = Client.GetPublicChannelsForTeam("junk", 0, 100, "") + CheckBadRequestStatus(t, resp) + + _, resp = Client.GetPublicChannelsForTeam(model.NewId(), 0, 100, "") + CheckForbiddenStatus(t, resp) + + Client.Logout() + _, resp = Client.GetPublicChannelsForTeam(team.Id, 0, 100, "") + CheckUnauthorizedStatus(t, resp) + + user := th.CreateUser() + Client.Login(user.Email, user.Password) + _, resp = Client.GetPublicChannelsForTeam(team.Id, 0, 100, "") + CheckForbiddenStatus(t, resp) + + _, resp = th.SystemAdminClient.GetPublicChannelsForTeam(team.Id, 0, 100, "") + CheckNoError(t, resp) +} + func TestGetChannelByName(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer TearDown() diff --git a/app/channel.go b/app/channel.go index f037e64c3..67caed94d 100644 --- a/app/channel.go +++ b/app/channel.go @@ -646,6 +646,14 @@ func GetChannelsUserNotIn(teamId string, userId string, offset int, limit int) ( } } +func GetPublicChannelsForTeam(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError) { + if result := <-Srv.Store.Channel().GetPublicChannelsForTeam(teamId, offset, limit); result.Err != nil { + return nil, result.Err + } else { + return result.Data.(*model.ChannelList), nil + } +} + func GetChannelMember(channelId string, userId string) (*model.ChannelMember, *model.AppError) { if result := <-Srv.Store.Channel().GetMember(channelId, userId); result.Err != nil { return nil, result.Err diff --git a/i18n/en.json b/i18n/en.json index 24ade54d5..70f9906f0 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -4708,6 +4708,10 @@ "translation": "We couldn't get the channels" }, { + "id": "store.sql_channel.get_public_channels.get.app_error", + "translation": "We couldn't get public channels" + }, + { "id": "store.sql_channel.increment_mention_count.app_error", "translation": "We couldn't increment the mention count" }, diff --git a/model/client4.go b/model/client4.go index 808ce74e3..43787cf08 100644 --- a/model/client4.go +++ b/model/client4.go @@ -98,6 +98,10 @@ func (c *Client4) GetChannelsRoute() string { return fmt.Sprintf("/channels") } +func (c *Client4) GetPublicChannelsForTeamRoute(teamId string) string { + return fmt.Sprintf(c.GetTeamRoute(teamId) + "/channels") +} + func (c *Client4) GetChannelRoute(channelId string) string { return fmt.Sprintf(c.GetChannelsRoute()+"/%v", channelId) } @@ -706,6 +710,17 @@ func (c *Client4) GetChannel(channelId, etag string) (*Channel, *Response) { } } +// GetPublicChannelsForTeam returns a channel based on the provided team id string. +func (c *Client4) GetPublicChannelsForTeam(teamId string, page int, perPage int, etag string) (*ChannelList, *Response) { + query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) + if r, err := c.DoApiGet(c.GetPublicChannelsForTeamRoute(teamId)+query, etag); err != nil { + return nil, &Response{StatusCode: r.StatusCode, Error: err} + } else { + defer closeBody(r) + return ChannelListFromJson(r.Body), BuildResponse(r) + } +} + // GetChannelByName returns a channel based on the provided channel name and team id strings. func (c *Client4) GetChannelByName(channelName, teamId string, etag string) (*Channel, *Response) { if r, err := c.DoApiGet(c.GetChannelByNameRoute(channelName, teamId), etag); err != nil { diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go index 27a00f484..802a5a49d 100644 --- a/store/sql_channel_store.go +++ b/store/sql_channel_store.go @@ -550,6 +550,40 @@ func (s SqlChannelStore) GetMoreChannels(teamId string, userId string, offset in return storeChannel } +func (s SqlChannelStore) GetPublicChannelsForTeam(teamId string, offset int, limit int) StoreChannel { + storeChannel := make(StoreChannel, 1) + + go func() { + result := StoreResult{} + + data := &model.ChannelList{} + _, err := s.GetReplica().Select(data, + `SELECT + * + FROM + Channels + WHERE + TeamId = :TeamId + AND Type = 'O' + AND DeleteAt = 0 + ORDER BY DisplayName + LIMIT :Limit + OFFSET :Offset`, + map[string]interface{}{"TeamId": teamId, "Limit": limit, "Offset": offset}) + + if err != nil { + result.Err = model.NewLocAppError("SqlChannelStore.GetPublicChannelsForTeam", "store.sql_channel.get_public_channels.get.app_error", nil, "teamId="+teamId+", err="+err.Error()) + } else { + result.Data = data + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + type channelIdWithCountAndUpdateAt struct { Id string TotalMsgCount int64 diff --git a/store/sql_channel_store_test.go b/store/sql_channel_store_test.go index 7b06dff8f..0e726eab7 100644 --- a/store/sql_channel_store_test.go +++ b/store/sql_channel_store_test.go @@ -775,6 +775,91 @@ func TestChannelStoreGetMoreChannels(t *testing.T) { } } +func TestChannelStoreGetPublicChannelsForTeam(t *testing.T) { + Setup() + + o1 := model.Channel{} + o1.TeamId = model.NewId() + o1.DisplayName = "OpenChannel1Team1" + o1.Name = "a" + model.NewId() + "b" + o1.Type = model.CHANNEL_OPEN + Must(store.Channel().Save(&o1)) + + o2 := model.Channel{} + o2.TeamId = model.NewId() + o2.DisplayName = "OpenChannel1Team2" + o2.Name = "a" + model.NewId() + "b" + o2.Type = model.CHANNEL_OPEN + Must(store.Channel().Save(&o2)) + + o3 := model.Channel{} + o3.TeamId = o1.TeamId + o3.DisplayName = "PrivateChannel1Team1" + o3.Name = "a" + model.NewId() + "b" + o3.Type = model.CHANNEL_PRIVATE + Must(store.Channel().Save(&o3)) + + cresult := <-store.Channel().GetPublicChannelsForTeam(o1.TeamId, 0, 100) + if cresult.Err != nil { + t.Fatal(cresult.Err) + } + list := cresult.Data.(*model.ChannelList) + + if len(*list) != 1 { + t.Fatal("wrong list") + } + + if (*list)[0].Name != o1.Name { + t.Fatal("missing channel") + } + + o4 := model.Channel{} + o4.TeamId = o1.TeamId + o4.DisplayName = "OpenChannel2Team1" + o4.Name = "a" + model.NewId() + "b" + o4.Type = model.CHANNEL_OPEN + Must(store.Channel().Save(&o4)) + + cresult = <-store.Channel().GetPublicChannelsForTeam(o1.TeamId, 0, 100) + list = cresult.Data.(*model.ChannelList) + + if len(*list) != 2 { + t.Fatal("wrong list length") + } + + cresult = <-store.Channel().GetPublicChannelsForTeam(o1.TeamId, 0, 1) + list = cresult.Data.(*model.ChannelList) + + if len(*list) != 1 { + t.Fatal("wrong list length") + } + + cresult = <-store.Channel().GetPublicChannelsForTeam(o1.TeamId, 1, 1) + list = cresult.Data.(*model.ChannelList) + + if len(*list) != 1 { + t.Fatal("wrong list length") + } + + if r1 := <-store.Channel().AnalyticsTypeCount(o1.TeamId, model.CHANNEL_OPEN); r1.Err != nil { + t.Fatal(r1.Err) + } else { + if r1.Data.(int64) != 2 { + t.Log(r1.Data) + t.Fatal("wrong value") + } + } + + if r1 := <-store.Channel().AnalyticsTypeCount(o1.TeamId, model.CHANNEL_PRIVATE); r1.Err != nil { + t.Fatal(r1.Err) + } else { + if r1.Data.(int64) != 1 { + t.Log(r1.Data) + t.Fatal("wrong value") + } + } +} + func TestChannelStoreGetChannelCounts(t *testing.T) { Setup() diff --git a/store/store.go b/store/store.go index 330bc5716..8bc578114 100644 --- a/store/store.go +++ b/store/store.go @@ -101,6 +101,7 @@ type ChannelStore interface { GetDeletedByName(team_id string, name string) StoreChannel GetChannels(teamId string, userId string) StoreChannel GetMoreChannels(teamId string, userId string, offset int, limit int) StoreChannel + GetPublicChannelsForTeam(teamId string, offset int, limit int) StoreChannel GetChannelCounts(teamId string, userId string) StoreChannel GetTeamChannels(teamId string) StoreChannel GetAll(teamId string) StoreChannel |