[APIv4] add getChannelMembersTimezone (#9286)
* add getChannelMembersTimezone * update per feedback review * add delimeter to error
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e87965f39d
Коммит
908ed5555f
@@ -33,7 +33,7 @@ func (api *API) InitChannel() {
|
|||||||
api.BaseRoutes.Channel.Handle("", api.ApiSessionRequired(deleteChannel)).Methods("DELETE")
|
api.BaseRoutes.Channel.Handle("", api.ApiSessionRequired(deleteChannel)).Methods("DELETE")
|
||||||
api.BaseRoutes.Channel.Handle("/stats", api.ApiSessionRequired(getChannelStats)).Methods("GET")
|
api.BaseRoutes.Channel.Handle("/stats", api.ApiSessionRequired(getChannelStats)).Methods("GET")
|
||||||
api.BaseRoutes.Channel.Handle("/pinned", api.ApiSessionRequired(getPinnedPosts)).Methods("GET")
|
api.BaseRoutes.Channel.Handle("/pinned", api.ApiSessionRequired(getPinnedPosts)).Methods("GET")
|
||||||
|
api.BaseRoutes.Channel.Handle("/timezones", api.ApiSessionRequired(getChannelMembersTimezones)).Methods("GET")
|
||||||
api.BaseRoutes.ChannelForUser.Handle("/unread", api.ApiSessionRequired(getChannelUnread)).Methods("GET")
|
api.BaseRoutes.ChannelForUser.Handle("/unread", api.ApiSessionRequired(getChannelUnread)).Methods("GET")
|
||||||
|
|
||||||
api.BaseRoutes.ChannelByName.Handle("", api.ApiSessionRequired(getChannelByName)).Methods("GET")
|
api.BaseRoutes.ChannelByName.Handle("", api.ApiSessionRequired(getChannelByName)).Methods("GET")
|
||||||
@@ -821,6 +821,26 @@ func getChannelMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Write([]byte(members.ToJson()))
|
w.Write([]byte(members.ToJson()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getChannelMembersTimezones(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
c.RequireChannelId()
|
||||||
|
if c.Err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.App.SessionHasPermissionToChannel(c.Session, c.Params.ChannelId, model.PERMISSION_READ_CHANNEL) {
|
||||||
|
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
membersTimezones, err := c.App.GetChannelMembersTimezones(c.Params.ChannelId)
|
||||||
|
if err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte(model.ArrayToJson(membersTimezones)))
|
||||||
|
}
|
||||||
|
|
||||||
func getChannelMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
|
func getChannelMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
c.RequireChannelId()
|
c.RequireChannelId()
|
||||||
if c.Err != nil {
|
if c.Err != nil {
|
||||||
|
|||||||
@@ -2335,3 +2335,52 @@ func TestUpdateChannelScheme(t *testing.T) {
|
|||||||
_, resp = th.SystemAdminClient.UpdateChannelScheme(channel.Id, channelScheme.Id)
|
_, resp = th.SystemAdminClient.UpdateChannelScheme(channel.Id, channelScheme.Id)
|
||||||
CheckUnauthorizedStatus(t, resp)
|
CheckUnauthorizedStatus(t, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetChannelMembersTimezones(t *testing.T) {
|
||||||
|
th := Setup().InitBasic().InitSystemAdmin()
|
||||||
|
defer th.TearDown()
|
||||||
|
Client := th.Client
|
||||||
|
|
||||||
|
user := th.BasicUser
|
||||||
|
user.Timezone["useAutomaticTimezone"] = "false"
|
||||||
|
user.Timezone["manualTimezone"] = "XOXO/BLABLA"
|
||||||
|
_, resp := Client.UpdateUser(user)
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
|
||||||
|
user2 := th.BasicUser2
|
||||||
|
user2.Timezone["automaticTimezone"] = "NoWhere/Island"
|
||||||
|
_, resp = th.SystemAdminClient.UpdateUser(user2)
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
|
||||||
|
timezone, resp := Client.GetChannelMembersTimezones(th.BasicChannel.Id)
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
if len(timezone) != 2 {
|
||||||
|
t.Fatal("should return 2 timezones")
|
||||||
|
}
|
||||||
|
|
||||||
|
//both users have same timezone
|
||||||
|
user2.Timezone["automaticTimezone"] = "XOXO/BLABLA"
|
||||||
|
_, resp = th.SystemAdminClient.UpdateUser(user2)
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
|
||||||
|
timezone, resp = Client.GetChannelMembersTimezones(th.BasicChannel.Id)
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
if len(timezone) != 1 {
|
||||||
|
t.Fatal("should return 1 timezone")
|
||||||
|
}
|
||||||
|
|
||||||
|
//no timezone set should return empty
|
||||||
|
user2.Timezone["automaticTimezone"] = ""
|
||||||
|
_, resp = th.SystemAdminClient.UpdateUser(user2)
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
|
||||||
|
user.Timezone["manualTimezone"] = ""
|
||||||
|
_, resp = Client.UpdateUser(user)
|
||||||
|
|
||||||
|
timezone, resp = Client.GetChannelMembersTimezones(th.BasicChannel.Id)
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
if len(timezone) > 0 {
|
||||||
|
t.Fatal("should return 0 timezone")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1153,6 +1153,24 @@ func (a *App) GetChannelMembersPage(channelId string, page, perPage int) (*model
|
|||||||
return result.Data.(*model.ChannelMembers), nil
|
return result.Data.(*model.ChannelMembers), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) GetChannelMembersTimezones(channelId string) ([]string, *model.AppError) {
|
||||||
|
result := <-a.Srv.Store.Channel().GetChannelMembersTimezones(channelId)
|
||||||
|
if result.Err != nil {
|
||||||
|
return nil, result.Err
|
||||||
|
}
|
||||||
|
membersTimezones := result.Data.([]map[string]string)
|
||||||
|
|
||||||
|
var timezones []string
|
||||||
|
for _, membersTimezone := range membersTimezones {
|
||||||
|
if membersTimezone["automaticTimezone"] == "" && membersTimezone["manualTimezone"] == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
timezones = append(timezones, model.GetPreferredTimezone(membersTimezone))
|
||||||
|
}
|
||||||
|
|
||||||
|
return model.RemoveDuplicateStrings(timezones), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) GetChannelMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError) {
|
func (a *App) GetChannelMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError) {
|
||||||
result := <-a.Srv.Store.Channel().GetMembersByIds(channelId, userIds)
|
result := <-a.Srv.Store.Channel().GetMembersByIds(channelId, userIds)
|
||||||
if result.Err != nil {
|
if result.Err != nil {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
@@ -709,3 +710,40 @@ func TestRenameChannel(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetChannelMembersTimezones(t *testing.T) {
|
||||||
|
th := Setup().InitBasic().InitSystemAdmin()
|
||||||
|
defer th.TearDown()
|
||||||
|
|
||||||
|
userRequestorId := ""
|
||||||
|
postRootId := ""
|
||||||
|
if _, err := th.App.AddChannelMember(th.BasicUser2.Id, th.BasicChannel, userRequestorId, postRootId, false); err != nil {
|
||||||
|
t.Fatal("Failed to add user to channel. Error: " + err.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
user := th.BasicUser
|
||||||
|
user.Timezone["useAutomaticTimezone"] = "false"
|
||||||
|
user.Timezone["manualTimezone"] = "XOXO/BLABLA"
|
||||||
|
th.App.UpdateUser(user, false)
|
||||||
|
|
||||||
|
user2 := th.BasicUser2
|
||||||
|
user2.Timezone["automaticTimezone"] = "NoWhere/Island"
|
||||||
|
th.App.UpdateUser(user2, false)
|
||||||
|
|
||||||
|
user3 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
|
||||||
|
ruser, _ := th.App.CreateUser(&user3)
|
||||||
|
th.App.AddUserToChannel(ruser, th.BasicChannel)
|
||||||
|
|
||||||
|
ruser.Timezone["automaticTimezone"] = "NoWhere/Island"
|
||||||
|
th.App.UpdateUser(ruser, false)
|
||||||
|
|
||||||
|
user4 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
|
||||||
|
ruser, _ = th.App.CreateUser(&user4)
|
||||||
|
th.App.AddUserToChannel(ruser, th.BasicChannel)
|
||||||
|
|
||||||
|
timezones, err := th.App.GetChannelMembersTimezones(th.BasicChannel.Id)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to get the timezones for a channel. Error: " + err.Error())
|
||||||
|
}
|
||||||
|
assert.Equal(t, 2, len(timezones))
|
||||||
|
}
|
||||||
|
|||||||
@@ -4986,6 +4986,10 @@
|
|||||||
"id": "store.sql_channel.get_members.app_error",
|
"id": "store.sql_channel.get_members.app_error",
|
||||||
"translation": "Unable to get the channel members"
|
"translation": "Unable to get the channel members"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_channel.get_timezone.app_error",
|
||||||
|
"translation": "We couldn't get the channel members timezones"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "store.sql_channel.get_members_by_ids.app_error",
|
"id": "store.sql_channel.get_members_by_ids.app_error",
|
||||||
"translation": "Unable to get the channel members"
|
"translation": "Unable to get the channel members"
|
||||||
|
|||||||
@@ -1746,6 +1746,17 @@ func (c *Client4) GetChannelStats(channelId string, etag string) (*ChannelStats,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetChannelMembersTimezones gets a list of timezones for a channel.
|
||||||
|
func (c *Client4) GetChannelMembersTimezones(channelId string) ([]string, *Response) {
|
||||||
|
r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/timezones", "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, BuildErrorResponse(r, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer closeBody(r)
|
||||||
|
return ArrayFromJson(r.Body), BuildResponse(r)
|
||||||
|
}
|
||||||
|
|
||||||
// GetPinnedPosts gets a list of pinned posts.
|
// GetPinnedPosts gets a list of pinned posts.
|
||||||
func (c *Client4) GetPinnedPosts(channelId string, etag string) (*PostList, *Response) {
|
func (c *Client4) GetPinnedPosts(channelId string, etag string) (*PostList, *Response) {
|
||||||
if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/pinned", etag); err != nil {
|
if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/pinned", etag); err != nil {
|
||||||
|
|||||||
@@ -499,11 +499,7 @@ func (u *User) IsSAMLUser() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) GetPreferredTimezone() string {
|
func (u *User) GetPreferredTimezone() string {
|
||||||
if u.Timezone["useAutomaticTimezone"] == "true" {
|
return GetPreferredTimezone(u.Timezone)
|
||||||
return u.Timezone["automaticTimezone"]
|
|
||||||
}
|
|
||||||
|
|
||||||
return u.Timezone["manualTimezone"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserFromJson will decode the input and return a User
|
// UserFromJson will decode the input and return a User
|
||||||
|
|||||||
@@ -564,3 +564,26 @@ func IsDomainName(s string) bool {
|
|||||||
|
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RemoveDuplicateStrings(in []string) []string {
|
||||||
|
out := []string{}
|
||||||
|
seen := make(map[string]bool, len(in))
|
||||||
|
|
||||||
|
for _, item := range in {
|
||||||
|
if !seen[item] {
|
||||||
|
out = append(out, item)
|
||||||
|
|
||||||
|
seen[item] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPreferredTimezone(timezone StringMap) string {
|
||||||
|
if timezone["useAutomaticTimezone"] == "true" {
|
||||||
|
return timezone["automaticTimezone"]
|
||||||
|
}
|
||||||
|
|
||||||
|
return timezone["manualTimezone"]
|
||||||
|
}
|
||||||
|
|||||||
@@ -1197,7 +1197,7 @@ func (s SqlChannelStore) GetMembers(channelId string, offset, limit int) store.S
|
|||||||
var dbMembers channelMemberWithSchemeRolesList
|
var dbMembers channelMemberWithSchemeRolesList
|
||||||
_, err := s.GetReplica().Select(&dbMembers, CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE ChannelId = :ChannelId LIMIT :Limit OFFSET :Offset", map[string]interface{}{"ChannelId": channelId, "Limit": limit, "Offset": offset})
|
_, err := s.GetReplica().Select(&dbMembers, CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE ChannelId = :ChannelId LIMIT :Limit OFFSET :Offset", map[string]interface{}{"ChannelId": channelId, "Limit": limit, "Offset": offset})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.GetMembers", "store.sql_channel.get_members.app_error", nil, "channel_id="+channelId+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.GetMembers", "store.sql_channel.get_members.app_error", nil, "channel_id="+channelId+","+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1205,6 +1205,27 @@ func (s SqlChannelStore) GetMembers(channelId string, offset, limit int) store.S
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s SqlChannelStore) GetChannelMembersTimezones(channelId string) store.StoreChannel {
|
||||||
|
return store.Do(func(result *store.StoreResult) {
|
||||||
|
var dbMembersTimezone []map[string]string
|
||||||
|
_, err := s.GetReplica().Select(&dbMembersTimezone, `
|
||||||
|
SELECT
|
||||||
|
Users.Timezone
|
||||||
|
FROM
|
||||||
|
ChannelMembers
|
||||||
|
LEFT JOIN
|
||||||
|
Users ON ChannelMembers.UserId = Id
|
||||||
|
WHERE ChannelId = :ChannelId
|
||||||
|
`, map[string]interface{}{
|
||||||
|
"ChannelId": channelId})
|
||||||
|
if err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlChannelStore.GetChannelMembersTimezones", "store.sql_channel.get_members.app_error", nil, "channel_id="+channelId+","+err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result.Data = dbMembersTimezone
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (s SqlChannelStore) GetMember(channelId string, userId string) store.StoreChannel {
|
func (s SqlChannelStore) GetMember(channelId string, userId string) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
var dbMember channelMemberWithSchemeRoles
|
var dbMember channelMemberWithSchemeRoles
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ type ChannelStore interface {
|
|||||||
UpdateMember(member *model.ChannelMember) StoreChannel
|
UpdateMember(member *model.ChannelMember) StoreChannel
|
||||||
GetMembers(channelId string, offset, limit int) StoreChannel
|
GetMembers(channelId string, offset, limit int) StoreChannel
|
||||||
GetMember(channelId string, userId string) StoreChannel
|
GetMember(channelId string, userId string) StoreChannel
|
||||||
|
GetChannelMembersTimezones(channelId string) StoreChannel
|
||||||
GetAllChannelMembersForUser(userId string, allowFromCache bool, includeDeleted bool) StoreChannel
|
GetAllChannelMembersForUser(userId string, allowFromCache bool, includeDeleted bool) StoreChannel
|
||||||
InvalidateAllChannelMembersForUser(userId string)
|
InvalidateAllChannelMembersForUser(userId string)
|
||||||
IsUserInChannelUseCache(userId string, channelId string) bool
|
IsUserInChannelUseCache(userId string, channelId string) bool
|
||||||
|
|||||||
@@ -442,6 +442,21 @@ func (_m *ChannelStore) GetMember(channelId string, userId string) store.StoreCh
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_m *ChannelStore) GetChannelMembersTimezones(channelId string) store.StoreChannel {
|
||||||
|
ret := _m.Called(channelId)
|
||||||
|
|
||||||
|
var r0 store.StoreChannel
|
||||||
|
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
|
||||||
|
r0 = rf(channelId)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.StoreChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// GetMemberCount provides a mock function with given fields: channelId, allowFromCache
|
// GetMemberCount provides a mock function with given fields: channelId, allowFromCache
|
||||||
func (_m *ChannelStore) GetMemberCount(channelId string, allowFromCache bool) store.StoreChannel {
|
func (_m *ChannelStore) GetMemberCount(channelId string, allowFromCache bool) store.StoreChannel {
|
||||||
ret := _m.Called(channelId, allowFromCache)
|
ret := _m.Called(channelId, allowFromCache)
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user