Move remaining actions over to use redux and v4 endpoints (#6720)

This commit is contained in:
Joram Wilander
2017-06-26 08:16:57 -04:00
committed by GitHub
parent fe7e9d95b3
commit 23ccfc845c
76 changed files with 686 additions and 6975 deletions

View File

@@ -1091,7 +1091,7 @@ func TestRestoreChannel(t *testing.T) {
_, resp = Client.RestoreChannel(privateChannel1.Id)
CheckOKStatus(t, resp)
}
}
func TestGetChannelByName(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
@@ -1684,7 +1684,7 @@ func TestAddChannelMember(t *testing.T) {
privateChannel := th.CreatePrivateChannel()
user3 := th.CreateUserWithClient(th.SystemAdminClient)
_, resp := th.SystemAdminClient.AddTeamMember(team.Id, user3.Id, "", "", team.InviteId)
_, resp := th.SystemAdminClient.AddTeamMember(team.Id, user3.Id)
CheckNoError(t, resp)
cm, resp := Client.AddChannelMember(publicChannel.Id, user2.Id)

View File

@@ -55,9 +55,14 @@ func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
m := r.MultipartForm
props := m.Value
if len(props["emoji"]) == 0 {
c.SetInvalidParam("emoji")
return
}
emoji := model.EmojiFromJson(strings.NewReader(props["emoji"][0]))
if emoji == nil {
c.SetInvalidParam("createEmoji")
c.SetInvalidParam("emoji")
return
}

View File

@@ -167,15 +167,32 @@ func getPost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !app.SessionHasPermissionToChannelByPost(c.Session, c.Params.PostId, model.PERMISSION_READ_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
var post *model.Post
var err *model.AppError
if post, err = app.GetSinglePost(c.Params.PostId); err != nil {
c.Err = err
return
}
if post, err := app.GetSinglePost(c.Params.PostId); err != nil {
var channel *model.Channel
if channel, err = app.GetChannel(post.ChannelId); err != nil {
c.Err = err
return
} else if HandleEtag(post.Etag(), "Get Post", w, r) {
}
if !app.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) {
if channel.Type == model.CHANNEL_OPEN {
if !app.SessionHasPermissionToTeam(c.Session, channel.TeamId, model.PERMISSION_READ_PUBLIC_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_PUBLIC_CHANNEL)
return
}
} else {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
return
}
}
if HandleEtag(post.Etag(), "Get Post", w, r) {
return
} else {
w.Header().Set(model.HEADER_ETAG_SERVER, post.Etag())
@@ -208,15 +225,40 @@ func getPostThread(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !app.SessionHasPermissionToChannelByPost(c.Session, c.Params.PostId, model.PERMISSION_READ_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
var list *model.PostList
var err *model.AppError
if list, err = app.GetPostThread(c.Params.PostId); err != nil {
c.Err = err
return
}
if list, err := app.GetPostThread(c.Params.PostId); err != nil {
var post *model.Post
if val, ok := list.Posts[c.Params.PostId]; ok {
post = val
} else {
c.SetInvalidUrlParam("post_id")
return
}
var channel *model.Channel
if channel, err = app.GetChannel(post.ChannelId); err != nil {
c.Err = err
return
} else if HandleEtag(list.Etag(), "Get Post Thread", w, r) {
}
if !app.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) {
if channel.Type == model.CHANNEL_OPEN {
if !app.SessionHasPermissionToTeam(c.Session, channel.TeamId, model.PERMISSION_READ_PUBLIC_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_PUBLIC_CHANNEL)
return
}
} else {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
return
}
}
if HandleEtag(list.Etag(), "Get Post Thread", w, r) {
return
} else {
w.Header().Set(model.HEADER_ETAG_SERVER, list.Etag())

View File

@@ -752,6 +752,23 @@ func TestGetPost(t *testing.T) {
CheckBadRequestStatus(t, resp)
_, resp = Client.GetPost(model.NewId(), "")
CheckNotFoundStatus(t, resp)
Client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id)
// Channel is public, should be able to read post
post, resp = Client.GetPost(th.BasicPost.Id, "")
CheckNoError(t, resp)
privatePost := th.CreatePostWithClient(Client, th.BasicPrivateChannel)
post, resp = Client.GetPost(privatePost.Id, "")
CheckNoError(t, resp)
Client.RemoveUserFromChannel(th.BasicPrivateChannel.Id, th.BasicUser.Id)
// Channel is private, should not be able to read post
post, resp = Client.GetPost(privatePost.Id, "")
CheckForbiddenStatus(t, resp)
Client.Logout()
@@ -831,6 +848,23 @@ func TestGetPostThread(t *testing.T) {
CheckBadRequestStatus(t, resp)
_, resp = Client.GetPostThread(model.NewId(), "")
CheckNotFoundStatus(t, resp)
Client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id)
// Channel is public, should be able to read post
_, resp = Client.GetPostThread(th.BasicPost.Id, "")
CheckNoError(t, resp)
privatePost := th.CreatePostWithClient(Client, th.BasicPrivateChannel)
_, resp = Client.GetPostThread(privatePost.Id, "")
CheckNoError(t, resp)
Client.RemoveUserFromChannel(th.BasicPrivateChannel.Id, th.BasicUser.Id)
// Channel is private, should not be able to read post
_, resp = Client.GetPostThread(privatePost.Id, "")
CheckForbiddenStatus(t, resp)
Client.Logout()

View File

@@ -37,6 +37,7 @@ func InitTeam() {
BaseRoutes.TeamMembers.Handle("/ids", ApiSessionRequired(getTeamMembersByIds)).Methods("POST")
BaseRoutes.TeamMembersForUser.Handle("", ApiSessionRequired(getTeamMembersForUser)).Methods("GET")
BaseRoutes.TeamMembers.Handle("", ApiSessionRequired(addTeamMember)).Methods("POST")
BaseRoutes.Teams.Handle("/members/invite", ApiSessionRequired(addUserToTeamFromInvite)).Methods("POST")
BaseRoutes.TeamMembers.Handle("/batch", ApiSessionRequired(addTeamMembers)).Methods("POST")
BaseRoutes.TeamMember.Handle("", ApiSessionRequired(removeTeamMember)).Methods("DELETE")
@@ -341,23 +342,36 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if len(member.UserId) != 26 {
c.SetInvalidParam("user_id")
return
}
if !app.SessionHasPermissionToTeam(c.Session, member.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
c.SetPermissionError(model.PERMISSION_ADD_USER_TO_TEAM)
return
}
member, err = app.AddTeamMember(member.TeamId, member.UserId)
if err != nil {
c.Err = err
return
}
w.WriteHeader(http.StatusCreated)
w.Write([]byte(member.ToJson()))
}
func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request) {
hash := r.URL.Query().Get("hash")
data := r.URL.Query().Get("data")
inviteId := r.URL.Query().Get("invite_id")
if len(member.UserId) > 0 {
if len(member.UserId) != 26 {
c.SetInvalidParam("user_id")
return
}
var member *model.TeamMember
var err *model.AppError
if !app.SessionHasPermissionToTeam(c.Session, member.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
c.SetPermissionError(model.PERMISSION_ADD_USER_TO_TEAM)
return
}
member, err = app.AddTeamMember(member.TeamId, member.UserId)
} else if len(hash) > 0 && len(data) > 0 {
if len(hash) > 0 && len(data) > 0 {
member, err = app.AddTeamMemberByHash(c.Session.UserId, hash, data)
if err != nil {
err = model.NewAppError("addTeamMember", "api.team.add_user_to_team.invalid_data.app_error", nil, "", http.StatusNotFound)

View File

@@ -778,7 +778,7 @@ func TestAddTeamMember(t *testing.T) {
// Regular user can't add a member to a team they don't belong to.
th.LoginBasic2()
tm, resp := Client.AddTeamMember(team.Id, otherUser.Id, "", "", "")
tm, resp := Client.AddTeamMember(team.Id, otherUser.Id)
CheckForbiddenStatus(t, resp)
if resp.Error == nil {
t.Fatalf("ERror is nhul")
@@ -787,7 +787,7 @@ func TestAddTeamMember(t *testing.T) {
// Regular user can add a member to a team they belong to.
th.LoginBasic()
tm, resp = Client.AddTeamMember(team.Id, otherUser.Id, "", "", "")
tm, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp)
CheckCreatedStatus(t, resp)
@@ -805,20 +805,20 @@ func TestAddTeamMember(t *testing.T) {
}
// Check with various invalid requests.
tm, resp = Client.AddTeamMember(team.Id, "junk", "", "", "")
tm, resp = Client.AddTeamMember(team.Id, "junk")
CheckBadRequestStatus(t, resp)
if tm != nil {
t.Fatal("should have not returned team member")
}
_, resp = Client.AddTeamMember("junk", otherUser.Id, "", "", "")
_, resp = Client.AddTeamMember("junk", otherUser.Id)
CheckBadRequestStatus(t, resp)
_, resp = Client.AddTeamMember(GenerateTestId(), otherUser.Id, "", "", "")
_, resp = Client.AddTeamMember(GenerateTestId(), otherUser.Id)
CheckForbiddenStatus(t, resp)
_, resp = Client.AddTeamMember(team.Id, GenerateTestId(), "", "", "")
_, resp = Client.AddTeamMember(team.Id, GenerateTestId())
CheckNotFoundStatus(t, resp)
Client.Logout()
@@ -840,7 +840,7 @@ func TestAddTeamMember(t *testing.T) {
th.LoginBasic()
// Test without the EE license to see that the permission restriction is ignored.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id, "", "", "")
_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp)
// Add an EE license.
@@ -851,7 +851,7 @@ func TestAddTeamMember(t *testing.T) {
th.LoginBasic()
// Check that a regular user can't add someone to the team.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id, "", "", "")
_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckForbiddenStatus(t, resp)
// Update user to team admin
@@ -865,7 +865,7 @@ func TestAddTeamMember(t *testing.T) {
th.LoginBasic()
// Should work as a team admin.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id, "", "", "")
_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp)
// Change permission level to System Admin
@@ -873,11 +873,11 @@ func TestAddTeamMember(t *testing.T) {
utils.SetDefaultRolesBasedOnConfig()
// Should not work as team admin.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id, "", "", "")
_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckForbiddenStatus(t, resp)
// Should work as system admin.
_, resp = th.SystemAdminClient.AddTeamMember(team.Id, otherUser.Id, "", "", "")
_, resp = th.SystemAdminClient.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp)
// Change permission level to All
@@ -891,7 +891,7 @@ func TestAddTeamMember(t *testing.T) {
th.LoginBasic()
// Should work as a regular user.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id, "", "", "")
_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp)
// Reset config and license.
@@ -911,7 +911,7 @@ func TestAddTeamMember(t *testing.T) {
data := model.MapToJson(dataObject)
hashed := utils.HashSha256(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
tm, resp = Client.AddTeamMember(team.Id, "", hashed, data, "")
tm, resp = Client.AddTeamMemberFromInvite(hashed, data, "")
CheckNoError(t, resp)
if tm == nil {
@@ -926,14 +926,14 @@ func TestAddTeamMember(t *testing.T) {
t.Fatal("team ids should have matched")
}
tm, resp = Client.AddTeamMember(team.Id, "", "junk", data, "")
tm, resp = Client.AddTeamMemberFromInvite("junk", data, "")
CheckNotFoundStatus(t, resp)
if tm != nil {
t.Fatal("should have not returned team member")
}
_, resp = Client.AddTeamMember(team.Id, "", hashed, "junk", "")
_, resp = Client.AddTeamMemberFromInvite(hashed, "junk", "")
CheckNotFoundStatus(t, resp)
// expired data of more than 50 hours
@@ -941,7 +941,7 @@ func TestAddTeamMember(t *testing.T) {
data = model.MapToJson(dataObject)
hashed = utils.HashSha256(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
tm, resp = Client.AddTeamMember(team.Id, "", hashed, data, "")
tm, resp = Client.AddTeamMemberFromInvite(hashed, data, "")
CheckNotFoundStatus(t, resp)
// invalid team id
@@ -949,13 +949,13 @@ func TestAddTeamMember(t *testing.T) {
data = model.MapToJson(dataObject)
hashed = utils.HashSha256(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
tm, resp = Client.AddTeamMember(team.Id, "", hashed, data, "")
tm, resp = Client.AddTeamMemberFromInvite(hashed, data, "")
CheckNotFoundStatus(t, resp)
// by invite_id
Client.Login(otherUser.Email, otherUser.Password)
tm, resp = Client.AddTeamMember(team.Id, "", "", "", team.InviteId)
tm, resp = Client.AddTeamMemberFromInvite("", "", team.InviteId)
CheckNoError(t, resp)
if tm == nil {
@@ -970,14 +970,14 @@ func TestAddTeamMember(t *testing.T) {
t.Fatal("team ids should have matched")
}
tm, resp = Client.AddTeamMember(team.Id, "", "", "", "junk")
tm, resp = Client.AddTeamMemberFromInvite("", "", "junk")
CheckNotFoundStatus(t, resp)
if tm != nil {
t.Fatal("should have not returned team member")
}
_, resp = Client.AddTeamMember(team.Id, "", "", "", "junk")
_, resp = Client.AddTeamMemberFromInvite("", "", "junk")
CheckNotFoundStatus(t, resp)
}
@@ -1124,7 +1124,7 @@ func TestRemoveTeamMember(t *testing.T) {
t.Fatal("should have passed")
}
_, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, th.BasicUser.Id, "", "", "")
_, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, th.BasicUser.Id)
CheckNoError(t, resp)
_, resp = Client.RemoveTeamMember(th.BasicTeam.Id, "junk")

View File

@@ -649,7 +649,7 @@ func TestSearchUsers(t *testing.T) {
t.Fatal("should have found user")
}
_, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, oddUser.Id, "", "", th.BasicTeam.InviteId)
_, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, oddUser.Id)
CheckNoError(t, resp)
users, resp = Client.SearchUsers(search)

View File

@@ -1102,9 +1102,20 @@ func (c *Client4) GetTeamMembersByIds(teamId string, userIds []string) ([]*TeamM
}
// AddTeamMember adds user to a team and return a team member.
func (c *Client4) AddTeamMember(teamId, userId, hash, dataToHash, inviteId string) (*TeamMember, *Response) {
func (c *Client4) AddTeamMember(teamId, userId string) (*TeamMember, *Response) {
member := &TeamMember{TeamId: teamId, UserId: userId}
if r, err := c.DoApiPost(c.GetTeamMembersRoute(teamId), member.ToJson()); err != nil {
return nil, BuildErrorResponse(r, err)
} else {
defer closeBody(r)
return TeamMemberFromJson(r.Body), BuildResponse(r)
}
}
// AddTeamMemberFromInvite adds a user to a team and return a team member using an invite id
// or an invite hash/data pair.
func (c *Client4) AddTeamMemberFromInvite(hash, dataToHash, inviteId string) (*TeamMember, *Response) {
var query string
if inviteId != "" {
@@ -1115,7 +1126,7 @@ func (c *Client4) AddTeamMember(teamId, userId, hash, dataToHash, inviteId strin
query += fmt.Sprintf("?hash=%v&data=%v", hash, dataToHash)
}
if r, err := c.DoApiPost(c.GetTeamMembersRoute(teamId)+query, member.ToJson()); err != nil {
if r, err := c.DoApiPost(c.GetTeamsRoute()+"/members/invite"+query, ""); err != nil {
return nil, BuildErrorResponse(r, err)
} else {
defer closeBody(r)
@@ -1123,7 +1134,7 @@ func (c *Client4) AddTeamMember(teamId, userId, hash, dataToHash, inviteId strin
}
}
// AddTeamMember adds a number of users to a team and returns the team members.
// AddTeamMembers adds a number of users to a team and returns the team members.
func (c *Client4) AddTeamMembers(teamId string, userIds []string) ([]*TeamMember, *Response) {
var members []*TeamMember
for _, userId := range userIds {

View File

@@ -318,7 +318,7 @@ func (s SqlPostStore) Get(id string) StoreChannel {
var post model.Post
err := s.GetReplica().SelectOne(&post, "SELECT * FROM Posts WHERE Id = :Id AND DeleteAt = 0", map[string]interface{}{"Id": id})
if err != nil {
result.Err = model.NewLocAppError("SqlPostStore.GetPost", "store.sql_post.get.app_error", nil, "id="+id+err.Error())
result.Err = model.NewAppError("SqlPostStore.GetPost", "store.sql_post.get.app_error", nil, "id="+id+err.Error(), http.StatusNotFound)
storeChannel <- result
close(storeChannel)
return
@@ -371,7 +371,7 @@ func (s SqlPostStore) GetSingle(id string) StoreChannel {
var post model.Post
err := s.GetReplica().SelectOne(&post, "SELECT * FROM Posts WHERE Id = :Id AND DeleteAt = 0", map[string]interface{}{"Id": id})
if err != nil {
result.Err = model.NewLocAppError("SqlPostStore.GetSingle", "store.sql_post.get.app_error", nil, "id="+id+err.Error())
result.Err = model.NewAppError("SqlPostStore.GetSingle", "store.sql_post.get.app_error", nil, "id="+id+err.Error(), http.StatusNotFound)
}
result.Data = &post

View File

@@ -3,8 +3,6 @@
import {clientLogout} from 'actions/global_actions.jsx';
import Client from 'client/web_client.jsx';
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
@@ -267,31 +265,26 @@ export function uploadBrandImage(brandImage, success, error) {
}
export function uploadLicenseFile(file, success, error) {
Client.uploadLicenseFile(
file,
() => {
if (success) {
success();
}
},
(err) => {
if (error) {
error(err);
AdminActions.uploadLicense(file)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.admin.uploadLicense.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}
export function removeLicenseFile(success, error) {
Client.removeLicenseFile(
() => {
if (success) {
success();
}
},
(err) => {
if (error) {
error(err);
AdminActions.removeLicense()(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.admin.removeLicense.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
@@ -374,3 +367,19 @@ export function removeIdpSamlCertificate(success, error) {
}
);
}
export function getStandardAnalytics(teamId) {
AdminActions.getStandardAnalytics(teamId)(dispatch, getState);
}
export function getAdvancedAnalytics(teamId) {
AdminActions.getAdvancedAnalytics(teamId)(dispatch, getState);
}
export function getPostsPerDayAnalytics(teamId) {
AdminActions.getPostsPerDayAnalytics(teamId)(dispatch, getState);
}
export function getUsersPerDayAnalytics(teamId) {
AdminActions.getUsersPerDayAnalytics(teamId)(dispatch, getState);
}

View File

@@ -1,8 +1,6 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import TeamStore from 'stores/team_store.jsx';
import UserStore from 'stores/user_store.jsx';
import ChannelStore from 'stores/channel_store.jsx';
@@ -14,36 +12,19 @@ import * as GlobalActions from 'actions/global_actions.jsx';
import {loadProfilesForSidebar, loadNewDMIfNeeded, loadNewGMIfNeeded} from 'actions/user_actions.jsx';
import {trackEvent} from 'actions/diagnostics_actions.jsx';
import Client from 'client/web_client.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as UserAgent from 'utils/user_agent.jsx';
import * as Utils from 'utils/utils.jsx';
import {Constants, Preferences, ActionTypes} from 'utils/constants.jsx';
import {Constants, Preferences} from 'utils/constants.jsx';
import {browserHistory} from 'react-router/es6';
// Redux actions
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {
viewChannel,
addChannelMember,
removeChannelMember,
updateChannelMemberRoles,
createDirectChannel,
fetchMyChannelsAndMembers,
joinChannel as joinChannelRedux,
leaveChannel as leaveChannelRedux,
updateChannel as updateChannelRedux,
searchChannels,
updateChannelNotifyProps as updateChannelNotifyPropsRedux,
createChannel as createChannelRedux,
patchChannel,
getChannelMembersByIds,
deleteChannel as deleteChannelRedux
} from 'mattermost-redux/actions/channels';
import * as ChannelActions from 'mattermost-redux/actions/channels';
import {savePreferences, deletePreferences} from 'mattermost-redux/actions/preferences';
import {Client4} from 'mattermost-redux/client';
import {getMyChannelMemberships} from 'mattermost-redux/selectors/entities/channels';
@@ -92,10 +73,8 @@ export function executeCommand(message, args, success, error) {
return;
}
Client.executeCommand(msg, args, success,
Client4.executeCommand(msg, args).then(success).catch(
(err) => {
AsyncClient.dispatchError(err, 'executeCommand');
if (error) {
error(err);
}
@@ -105,7 +84,7 @@ export function executeCommand(message, args, success, error) {
export function setChannelAsRead(channelIdParam) {
const channelId = channelIdParam || ChannelStore.getCurrentId();
viewChannel(channelId)(dispatch, getState);
ChannelActions.viewChannel(channelId)(dispatch, getState);
ChannelStore.resetCounts([channelId]);
ChannelStore.emitChange();
if (channelId === ChannelStore.getCurrentId()) {
@@ -114,7 +93,7 @@ export function setChannelAsRead(channelIdParam) {
}
export function addUserToChannel(channelId, userId, success, error) {
addChannelMember(channelId, userId)(dispatch, getState).then(
ChannelActions.addChannelMember(channelId, userId)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -127,7 +106,7 @@ export function addUserToChannel(channelId, userId, success, error) {
}
export function removeUserFromChannel(channelId, userId, success, error) {
removeChannelMember(channelId, userId)(dispatch, getState).then(
ChannelActions.removeChannelMember(channelId, userId)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -140,7 +119,7 @@ export function removeUserFromChannel(channelId, userId, success, error) {
}
export function makeUserChannelAdmin(channelId, userId, success, error) {
updateChannelMemberRoles(channelId, userId, 'channel_user channel_admin')(dispatch, getState).then(
ChannelActions.updateChannelMemberRoles(channelId, userId, 'channel_user channel_admin')(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -153,7 +132,7 @@ export function makeUserChannelAdmin(channelId, userId, success, error) {
}
export function makeUserChannelMember(channelId, userId, success, error) {
updateChannelMemberRoles(channelId, userId, 'channel_user')(dispatch, getState).then(
ChannelActions.updateChannelMemberRoles(channelId, userId, 'channel_user')(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -174,11 +153,8 @@ export function openDirectChannelToUser(userId, success, error) {
PreferenceStore.setPreference(Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, userId, 'true');
loadProfilesForSidebar();
AsyncClient.savePreference(
Preferences.CATEGORY_DIRECT_CHANNEL_SHOW,
userId,
'true'
);
const currentUserId = UserStore.getCurrentId();
savePreferences(currentUserId, [{user_id: currentUserId, category: Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, name: userId, value: 'true'}])(dispatch, getState);
if (success) {
success(channel, true);
@@ -187,7 +163,7 @@ export function openDirectChannelToUser(userId, success, error) {
return;
}
createDirectChannel(UserStore.getCurrentId(), userId)(dispatch, getState).then(
ChannelActions.createDirectChannel(UserStore.getCurrentId(), userId)(dispatch, getState).then(
(data) => {
loadProfilesForSidebar();
if (data && success) {
@@ -202,37 +178,15 @@ export function openDirectChannelToUser(userId, success, error) {
}
export function openGroupChannelToUsers(userIds, success, error) {
Client.createGroupChannel(
userIds,
ChannelActions.createGroupChannel(userIds)(dispatch, getState).then(
(data) => {
Client.getChannelMember(
data.id,
UserStore.getCurrentId(),
(data2) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_CHANNEL,
channel: data,
member: data2
});
PreferenceStore.setPreference(Preferences.CATEGORY_GROUP_CHANNEL_SHOW, data.id, 'true');
loadProfilesForSidebar();
AsyncClient.savePreference(
Preferences.CATEGORY_GROUP_CHANNEL_SHOW,
data.id,
'true'
);
if (success) {
success(data);
}
}
);
},
() => {
if (error) {
error();
loadProfilesForSidebar();
if (data && success) {
success(data, false);
} else if (data == null && error) {
browserHistory.push(TeamStore.getCurrentTeamUrl());
const serverError = getState().requests.channels.createChannel.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
@@ -240,22 +194,25 @@ export function openGroupChannelToUsers(userIds, success, error) {
export function markFavorite(channelId) {
trackEvent('api', 'api_channels_favorited');
AsyncClient.savePreference(Preferences.CATEGORY_FAVORITE_CHANNEL, channelId, 'true');
const currentUserId = UserStore.getCurrentId();
savePreferences(currentUserId, [{user_id: currentUserId, category: Preferences.CATEGORY_FAVORITE_CHANNEL, name: channelId, value: 'true'}])(dispatch, getState);
}
export function unmarkFavorite(channelId) {
trackEvent('api', 'api_channels_unfavorited');
const currentUserId = UserStore.getCurrentId();
const pref = {
user_id: UserStore.getCurrentId(),
user_id: currentUserId,
category: Preferences.CATEGORY_FAVORITE_CHANNEL,
name: channelId
};
AsyncClient.deletePreferences([pref]);
deletePreferences(currentUserId, [pref])(dispatch, getState);
}
export function loadChannelsForCurrentUser() {
fetchMyChannelsAndMembers(TeamStore.getCurrentId())(dispatch, getState).then(
ChannelActions.fetchMyChannelsAndMembers(TeamStore.getCurrentId())(dispatch, getState).then(
() => {
loadDMsAndGMsForUnreads();
}
@@ -281,7 +238,7 @@ export function loadDMsAndGMsForUnreads() {
}
export function joinChannel(channel, success, error) {
joinChannelRedux(UserStore.getCurrentId(), null, channel.id)(dispatch, getState).then(
ChannelActions.joinChannel(UserStore.getCurrentId(), null, channel.id)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -294,7 +251,7 @@ export function joinChannel(channel, success, error) {
}
export function updateChannel(channel, success, error) {
updateChannelRedux(channel)(dispatch, getState).then(
ChannelActions.updateChannel(channel)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -307,7 +264,7 @@ export function updateChannel(channel, success, error) {
}
export function searchMoreChannels(term, success, error) {
searchChannels(TeamStore.getCurrentId(), term)(dispatch, getState).then(
ChannelActions.searchChannels(TeamStore.getCurrentId(), term)(dispatch, getState).then(
(data) => {
if (data && success) {
const myMembers = getMyChannelMemberships(getState());
@@ -322,7 +279,7 @@ export function searchMoreChannels(term, success, error) {
}
export function autocompleteChannels(term, success, error) {
searchChannels(TeamStore.getCurrentId(), term)(dispatch, getState).then(
ChannelActions.searchChannels(TeamStore.getCurrentId(), term)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -335,7 +292,7 @@ export function autocompleteChannels(term, success, error) {
}
export function updateChannelNotifyProps(data, options, success, error) {
updateChannelNotifyPropsRedux(data.user_id, data.channel_id, Object.assign({}, data, options))(dispatch, getState).then(
ChannelActions.updateChannelNotifyProps(data.user_id, data.channel_id, Object.assign({}, data, options))(dispatch, getState).then(
(result) => {
if (result && success) {
success(result);
@@ -348,7 +305,7 @@ export function updateChannelNotifyProps(data, options, success, error) {
}
export function createChannel(channel, success, error) {
createChannelRedux(channel)(dispatch, getState).then(
ChannelActions.createChannel(channel)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -361,7 +318,7 @@ export function createChannel(channel, success, error) {
}
export function updateChannelPurpose(channelId, purpose, success, error) {
patchChannel(channelId, {purpose})(dispatch, getState).then(
ChannelActions.patchChannel(channelId, {purpose})(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -374,7 +331,7 @@ export function updateChannelPurpose(channelId, purpose, success, error) {
}
export function updateChannelHeader(channelId, header, success, error) {
patchChannel(channelId, {header})(dispatch, getState).then(
ChannelActions.patchChannel(channelId, {header})(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -387,7 +344,7 @@ export function updateChannelHeader(channelId, header, success, error) {
}
export function getChannelMembersForUserIds(channelId, userIds, success, error) {
getChannelMembersByIds(channelId, userIds)(dispatch, getState).then(
ChannelActions.getChannelMembersByIds(channelId, userIds)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
@@ -400,7 +357,7 @@ export function getChannelMembersForUserIds(channelId, userIds, success, error)
}
export function leaveChannel(channelId, success) {
leaveChannelRedux(channelId)(dispatch, getState).then(
ChannelActions.leaveChannel(channelId)(dispatch, getState).then(
() => {
if (ChannelUtils.isFavoriteChannelId(channelId)) {
unmarkFavorite(channelId);
@@ -417,7 +374,7 @@ export function leaveChannel(channelId, success) {
}
export function deleteChannel(channelId, success, error) {
deleteChannelRedux(channelId)(dispatch, getState).then(
ChannelActions.deleteChannel(channelId)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);

View File

@@ -1,8 +1,24 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import Client from 'client/web_client.jsx';
import UserStore from 'stores/user_store.jsx';
export function trackEvent(category, event, properties) {
Client.trackEvent(category, event, properties);
export function trackEvent(category, event, props) {
if (global.window && global.window.analytics) {
const properties = Object.assign({category, type: event, user_actual_id: UserStore.getCurrentId()}, props);
const options = {
context: {
ip: '0.0.0.0'
},
page: {
path: '',
referrer: '',
search: '',
title: '',
url: ''
},
anonymousId: '00000000000000000000000000'
};
global.window.analytics.track('event', properties, options);
}
}

View File

@@ -3,20 +3,21 @@
import UserStore from 'stores/user_store.jsx';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import {ActionTypes} from 'utils/constants.jsx';
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {getProfilesByIds} from 'mattermost-redux/actions/users';
import {getAllCustomEmojis} from 'mattermost-redux/actions/emojis';
import * as EmojiActions from 'mattermost-redux/actions/emojis';
export function loadEmoji(getProfiles = true) {
getAllCustomEmojis(10000)(dispatch, getState).then(
(data) => {
if (getProfiles) {
loadProfilesForEmoji(data);
}
}
);
export async function loadEmoji(getProfiles = true) {
const data = await EmojiActions.getAllCustomEmojis(10000)(dispatch, getState);
if (data && getProfiles) {
loadProfilesForEmoji(data);
}
}
function loadProfilesForEmoji(emojiList) {
@@ -35,3 +36,37 @@ function loadProfilesForEmoji(emojiList) {
getProfilesByIds(list)(dispatch, getState);
}
export function addEmoji(emoji, image, success, error) {
EmojiActions.createCustomEmoji(emoji, image)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.emojis.createCustomEmoji.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}
export function deleteEmoji(emojiId, success, error) {
EmojiActions.deleteCustomEmoji(emojiId)(dispatch, getState).then(
(data) => {
if (data) {
// Needed to remove recently used emoji
AppDispatcher.handleServerAction({
type: ActionTypes.REMOVED_CUSTOM_EMOJI,
id: emojiId
});
if (success) {
success(data);
}
} else if (data == null && error) {
const serverError = getState().requests.emojis.deleteCustomEmoji.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}

View File

@@ -5,6 +5,7 @@ import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {uploadFile as uploadFileRedux} from 'mattermost-redux/actions/files';
import {Client4} from 'mattermost-redux/client';
export function uploadFile(file, name, channelId, clientId, success, error) {
const fileFormData = new FormData();
@@ -23,3 +24,15 @@ export function uploadFile(file, name, channelId, clientId, success, error) {
}
);
}
export async function getPublicLink(fileId, success) {
Client4.getFilePublicLink(fileId).then(
(data) => {
if (data && success) {
success(data.link);
}
}
).catch(
() => {} //eslint-disable-line no-empty-function
);
}

View File

@@ -21,8 +21,6 @@ import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
import EventTypes from 'utils/event_types.jsx';
import Client from 'client/web_client.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import WebSocketClient from 'client/web_websocket_client.jsx';
import {sortTeamsByDisplayName} from 'utils/team_utils.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -35,20 +33,24 @@ import {browserHistory} from 'react-router/es6';
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {Client4} from 'mattermost-redux/client';
import {removeUserFromTeam} from 'mattermost-redux/actions/teams';
import {viewChannel, getChannelStats, getMyChannelMember, getChannelAndMyMember} from 'mattermost-redux/actions/channels';
import {viewChannel, getChannelStats, getMyChannelMember, getChannelAndMyMember, createDirectChannel} from 'mattermost-redux/actions/channels';
import {getPostThread} from 'mattermost-redux/actions/posts';
export function emitChannelClickEvent(channel) {
function userVisitedFakeChannel(chan, success, fail) {
const currentUserId = UserStore.getCurrentId();
const otherUserId = Utils.getUserIdFromChannelName(chan);
Client.createDirectChannel(
otherUserId,
createDirectChannel(currentUserId, otherUserId)(dispatch, getState).then(
(data) => {
success(data);
},
() => {
fail();
if (data) {
success(data);
} else {
fail();
}
}
);
}
@@ -119,32 +121,29 @@ export function doFocusPost(channelId, postId, data) {
export function emitPostFocusEvent(postId, onSuccess) {
loadChannelsForCurrentUser();
Client.getPermalinkTmp(
postId,
getPostThread(postId)(dispatch, getState).then(
(data) => {
if (!data) {
return;
}
const channelId = data.posts[data.order[0]].channel_id;
doFocusPost(channelId, postId, data);
if (data) {
const channelId = data.posts[data.order[0]].channel_id;
doFocusPost(channelId, postId, data);
if (onSuccess) {
onSuccess();
}
},
() => {
let link = `${TeamStore.getCurrentTeamRelativeUrl()}/channels/`;
const channel = ChannelStore.getCurrent();
if (channel) {
link += channel.name;
if (onSuccess) {
onSuccess();
}
} else {
link += 'town-square';
let link = `${TeamStore.getCurrentTeamRelativeUrl()}/channels/`;
const channel = ChannelStore.getCurrent();
if (channel) {
link += channel.name;
} else {
link += 'town-square';
}
const message = encodeURIComponent(Utils.localizeMessage('permalink.error.access', 'Permalink belongs to a deleted message or to a channel to which you do not have access.'));
const title = encodeURIComponent(Utils.localizeMessage('permalink.error.title', 'Message Not Found'));
browserHistory.push('/error?message=' + message + '&title=' + title + '&link=' + encodeURIComponent(link));
}
const message = encodeURIComponent(Utils.localizeMessage('permalink.error.access', 'Permalink belongs to a deleted message or to a channel to which you do not have access.'));
const title = encodeURIComponent(Utils.localizeMessage('permalink.error.title', 'Message Not Found'));
browserHistory.push('/error?message=' + message + '&title=' + title + '&link=' + encodeURIComponent(link));
}
);
}
@@ -353,8 +352,7 @@ export function newLocalizationSelected(locale) {
} else {
const localeInfo = I18n.getLanguageInfo(locale);
Client.getTranslations(
localeInfo.url,
Client4.getTranslations(localeInfo.url).then(
(data, res) => {
let translations = data;
if (!data && res.text) {
@@ -365,10 +363,9 @@ export function newLocalizationSelected(locale) {
locale,
translations
});
},
(err) => {
AsyncClient.dispatchError(err, 'getTranslations');
}
).catch(
() => {} //eslint-disable-line no-empty-function
);
}
}
@@ -414,14 +411,15 @@ export function emitRemoteUserTypingEvent(channelId, userId, postParentId) {
}
export function emitUserLoggedOutEvent(redirectTo = '/', shouldSignalLogout = true) {
Client.logout(
Client4.logout().then(
() => {
if (shouldSignalLogout) {
BrowserStore.signalLogout();
}
clientLogout(redirectTo);
},
}
).catch(
() => {
browserHistory.push(redirectTo);
}
@@ -523,7 +521,6 @@ export function redirectUserToDefaultTeam() {
if (channel) {
redirect(teams[teamId].name, channel);
} else if (channelId) {
Client.setTeamId(teamId);
getChannelAndMyMember(channelId)(dispatch, getState).then(
(data) => {
if (data) {
@@ -541,34 +538,6 @@ export function redirectUserToDefaultTeam() {
}
}
requestOpenGraphMetadata.openGraphMetadataOnGoingRequests = {}; // Format: {<url>: true}
export function requestOpenGraphMetadata(url) {
if (global.mm_config.EnableLinkPreviews !== 'true') {
return;
}
const onself = requestOpenGraphMetadata;
if (!onself.openGraphMetadataOnGoingRequests[url]) {
onself.openGraphMetadataOnGoingRequests[url] = true;
Client.getOpenGraphMetadata(url,
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECIVED_OPEN_GRAPH_METADATA,
url,
data
});
delete onself.openGraphMetadataOnGoingRequests[url];
},
(err) => {
AsyncClient.dispatchError(err, 'getOpenGraphMetadata');
delete onself.openGraphMetadataOnGoingRequests[url];
}
);
}
}
export function postListScrollChange() {
AppDispatcher.handleViewAction({
type: EventTypes.POST_LIST_SCROLL_CHANGE

View File

@@ -4,13 +4,21 @@
import UserStore from 'stores/user_store.jsx';
import TeamStore from 'stores/team_store.jsx';
// Redux actions
import * as UserAgent from 'utils/user_agent.jsx';
import {ActionTypes} from 'utils/constants.jsx';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {Client4} from 'mattermost-redux/client';
import {getProfilesByIds} from 'mattermost-redux/actions/users';
import * as IntegrationActions from 'mattermost-redux/actions/integrations';
import request from 'superagent';
export function loadIncomingHooks(complete) {
IntegrationActions.getIncomingHooks('', 0, 10000)(dispatch, getState).then(
(data) => {
@@ -201,3 +209,61 @@ export function deleteCommand(id) {
export function regenCommandToken(id) {
IntegrationActions.regenCommandToken(id)(dispatch, getState);
}
export function getSuggestedCommands(command, suggestionId, component) {
Client4.getCommandsList(TeamStore.getCurrentId()).then(
(data) => {
var matches = [];
data.forEach((cmd) => {
if (cmd.trigger !== 'shortcuts' || !UserAgent.isMobile()) {
if (('/' + cmd.trigger).indexOf(command) === 0) {
const s = '/' + cmd.trigger;
let hint = '';
if (cmd.auto_complete_hint && cmd.auto_complete_hint.length !== 0) {
hint = cmd.auto_complete_hint;
}
matches.push({
suggestion: s,
hint,
description: cmd.auto_complete_desc
});
}
}
});
matches = matches.sort((a, b) => a.suggestion.localeCompare(b.suggestion));
// pull out the suggested commands from the returned data
const terms = matches.map((suggestion) => suggestion.suggestion);
if (terms.length > 0) {
AppDispatcher.handleServerAction({
type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS,
id: suggestionId,
matchedPretext: command,
terms,
items: matches,
component
});
}
}
).catch(
() => {} //eslint-disable-line no-empty-function
);
}
export function getYoutubeVideoInfo(googleKey, videoId, success, error) {
request.get('https://www.googleapis.com/youtube/v3/videos').
query({part: 'snippet', id: videoId, key: googleKey}).
end((err, res) => {
if (err) {
return error(err);
}
if (!res.body) {
console.error('Missing response body for getYoutubeVideoInfo'); // eslint-disable-line no-console
}
return success(res.body);
});
}

View File

@@ -6,34 +6,25 @@ import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import UserStore from 'stores/user_store.jsx';
import PostStore from 'stores/post_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import {loadNewDMIfNeeded, loadNewGMIfNeeded} from 'actions/user_actions.jsx';
import {trackEvent} from 'actions/diagnostics_actions.jsx';
import {sendDesktopNotification} from 'actions/notification_actions.jsx';
import Client from 'client/web_client.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
const Preferences = Constants.Preferences;
// Redux actions
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {getProfilesByIds} from 'mattermost-redux/actions/users';
import {
createPost as createPostRedux,
getPostThread,
editPost,
deletePost as deletePostRedux,
getPosts,
getPostsBefore,
addReaction as addReactionRedux,
removeReaction as removeReactionRedux
} from 'mattermost-redux/actions/posts';
import * as PostActions from 'mattermost-redux/actions/posts';
import {getMyChannelMember} from 'mattermost-redux/actions/channels';
import {Client4} from 'mattermost-redux/client';
import {PostTypes} from 'mattermost-redux/action_types';
import * as Selectors from 'mattermost-redux/selectors/entities/posts';
import {batchActions} from 'redux-batched-actions';
@@ -47,11 +38,6 @@ export function handleNewPost(post, msg) {
if (ChannelStore.getMyMember(post.channel_id)) {
completePostReceive(post, websocketMessageProps);
} else {
// This API call requires any real team id in API v3, so set one if we don't already have one
if (!Client.teamId && msg && msg.data) {
Client.setTeamId(msg.data.team_id);
}
getMyChannelMember(post.channel_id)(dispatch, getState).then(() => completePostReceive(post, websocketMessageProps));
}
@@ -66,7 +52,7 @@ export function handleNewPost(post, msg) {
function completePostReceive(post, websocketMessageProps) {
if (post.root_id && Selectors.getPost(getState(), post.root_id) == null) {
getPostThread(post.root_id)(dispatch, getState).then(
PostActions.getPostThread(post.root_id)(dispatch, getState).then(
(data) => {
// Need manual dispatch to remove pending post
dispatch({
@@ -116,31 +102,16 @@ function completePostReceive(post, websocketMessageProps) {
sendDesktopNotification(post, websocketMessageProps);
}
export function pinPost(channelId, postId) {
AsyncClient.pinPost(channelId, postId);
}
export function unpinPost(channelId, postId) {
AsyncClient.unpinPost(channelId, postId);
}
export function flagPost(postId) {
trackEvent('api', 'api_posts_flagged');
AsyncClient.savePreference(Preferences.CATEGORY_FLAGGED_POST, postId, 'true');
PostActions.flagPost(postId)(dispatch, getState);
}
export function unflagPost(postId, success) {
trackEvent('api', 'api_posts_unflagged');
const pref = {
user_id: UserStore.getCurrentId(),
category: Preferences.CATEGORY_FLAGGED_POST,
name: postId
};
AsyncClient.deletePreferences([pref], success);
export function unflagPost(postId) {
PostActions.unflagPost(postId)(dispatch, getState);
}
export function getFlaggedPosts() {
Client.getFlaggedPosts(0, Constants.POST_CHUNK_SIZE,
Client4.getFlaggedPosts(UserStore.getCurrentId(), '', TeamStore.getCurrentId()).then(
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_SEARCH_TERM,
@@ -157,15 +128,14 @@ export function getFlaggedPosts() {
});
loadProfilesForPosts(data.posts);
},
(err) => {
AsyncClient.dispatchError(err, 'getFlaggedPosts');
}
).catch(
() => {} //eslint-disable-line no-empty-function
);
}
export function getPinnedPosts(channelId = ChannelStore.getCurrentId()) {
Client.getPinnedPosts(channelId,
Client4.getPinnedPosts(channelId).then(
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_SEARCH_TERM,
@@ -182,10 +152,9 @@ export function getPinnedPosts(channelId = ChannelStore.getCurrentId()) {
});
loadProfilesForPosts(data.posts);
},
(err) => {
AsyncClient.dispatchError(err, 'getPinnedPosts');
}
).catch(
() => {} //eslint-disable-line no-empty-function
);
}
@@ -211,15 +180,15 @@ export function loadProfilesForPosts(posts) {
}
export function addReaction(channelId, postId, emojiName) {
addReactionRedux(postId, emojiName)(dispatch, getState);
PostActions.addReaction(postId, emojiName)(dispatch, getState);
}
export function removeReaction(channelId, postId, emojiName) {
removeReactionRedux(postId, emojiName)(dispatch, getState);
PostActions.removeReaction(postId, emojiName)(dispatch, getState);
}
export function createPost(post, files, success) {
createPostRedux(post, files)(dispatch, getState).then(() => {
PostActions.createPost(post, files)(dispatch, getState).then(() => {
if (post.root_id) {
PostStore.storeCommentDraft(post.root_id, null);
} else {
@@ -233,7 +202,7 @@ export function createPost(post, files, success) {
}
export function updatePost(post, success) {
editPost(post)(dispatch, getState).then(
PostActions.editPost(post)(dispatch, getState).then(
(data) => {
if (data && success) {
success();
@@ -257,7 +226,7 @@ export function deletePost(channelId, post, success) {
hardDelete = true;
}
deletePostRedux(post, hardDelete)(dispatch, getState).then(
PostActions.deletePost(post, hardDelete)(dispatch, getState).then(
() => {
if (post.id === getState().views.rhs.selectedPostId) {
dispatch({
@@ -279,9 +248,7 @@ export function deletePost(channelId, post, success) {
}
export function performSearch(terms, isMentionSearch, success, error) {
Client.search(
terms,
isMentionSearch,
Client4.searchPosts(TeamStore.getCurrentId(), terms, isMentionSearch).then(
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_SEARCH,
@@ -294,10 +261,9 @@ export function performSearch(terms, isMentionSearch, success, error) {
if (success) {
success(data);
}
},
}
).catch(
(err) => {
AsyncClient.dispatchError(err, 'search');
if (error) {
error(err);
}
@@ -337,9 +303,9 @@ export function increasePostVisibility(channelId, focusedPostId) {
let posts;
if (focusedPostId) {
posts = await getPostsBefore(channelId, focusedPostId, page, POST_INCREASE_AMOUNT)(dispatch, getState);
posts = await PostActions.getPostsBefore(channelId, focusedPostId, page, POST_INCREASE_AMOUNT)(dispatch, getState);
} else {
posts = await getPosts(channelId, page, POST_INCREASE_AMOUNT)(doDispatch, doGetState);
posts = await PostActions.getPosts(channelId, page, POST_INCREASE_AMOUNT)(doDispatch, doGetState);
}
doDispatch({

View File

@@ -4,8 +4,6 @@
import TeamStore from 'stores/team_store.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import Client from 'client/web_client.jsx';
import {browserHistory} from 'react-router/es6';
// Redux actions
@@ -13,26 +11,17 @@ import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {Client4} from 'mattermost-redux/client';
import {getUser} from 'mattermost-redux/actions/users';
import {viewChannel} from 'mattermost-redux/actions/channels';
import {
createTeam as createTeamRedux,
updateTeam as updateTeamRedux,
removeUserFromTeam as removeUserFromTeamRedux,
getTeamStats,
checkIfTeamExists as checkIfTeamExistsRedux,
updateTeamMemberRoles as updateTeamMemberRolesRedux,
addUsersToTeam as addUsersToTeamRedux,
sendEmailInvitesToTeam,
getTeamsForUser as getTeamsForUserRedux,
getTeamMembersForUser as getTeamMembersForUserRedux
} from 'mattermost-redux/actions/teams';
import * as TeamActions from 'mattermost-redux/actions/teams';
import {TeamTypes} from 'mattermost-redux/action_types';
import {batchActions} from 'redux-batched-actions';
export function checkIfTeamExists(teamName, onSuccess, onError) {
checkIfTeamExistsRedux(teamName)(dispatch, getState).then(
TeamActions.checkIfTeamExists(teamName)(dispatch, getState).then(
(exists) => {
if (exists != null && onSuccess) {
onSuccess(exists);
@@ -45,7 +34,7 @@ export function checkIfTeamExists(teamName, onSuccess, onError) {
}
export function createTeam(team, onSuccess, onError) {
createTeamRedux(team)(dispatch, getState).then(
TeamActions.createTeam(team)(dispatch, getState).then(
(rteam) => {
if (rteam && onSuccess) {
browserHistory.push('/' + rteam.name + '/channels/town-square');
@@ -59,7 +48,7 @@ export function createTeam(team, onSuccess, onError) {
}
export function updateTeam(team, onSuccess, onError) {
updateTeamRedux(team)(dispatch, getState).then(
TeamActions.updateTeam(team)(dispatch, getState).then(
(rteam) => {
if (rteam && onSuccess) {
browserHistory.push('/' + rteam.name + '/channels/town-square');
@@ -73,10 +62,10 @@ export function updateTeam(team, onSuccess, onError) {
}
export function removeUserFromTeam(teamId, userId, success, error) {
removeUserFromTeamRedux(teamId, userId)(dispatch, getState).then(
TeamActions.removeUserFromTeam(teamId, userId)(dispatch, getState).then(
(data) => {
getUser(userId)(dispatch, getState);
getTeamStats(teamId)(dispatch, getState);
TeamActions.getTeamStats(teamId)(dispatch, getState);
if (data && success) {
success();
@@ -89,7 +78,7 @@ export function removeUserFromTeam(teamId, userId, success, error) {
}
export function updateTeamMemberRoles(teamId, userId, newRoles, success, error) {
updateTeamMemberRolesRedux(teamId, userId, newRoles)(dispatch, getState).then(
TeamActions.updateTeamMemberRoles(teamId, userId, newRoles)(dispatch, getState).then(
(data) => {
if (data && success) {
success();
@@ -102,10 +91,7 @@ export function updateTeamMemberRoles(teamId, userId, newRoles, success, error)
}
export function addUserToTeamFromInvite(data, hash, inviteId, success, error) {
Client.addUserToTeamFromInvite(
data,
hash,
inviteId,
Client4.addToTeamFromInvite(hash, data, inviteId).then(
(team) => {
const member = {
team_id: team.id,
@@ -131,6 +117,7 @@ export function addUserToTeamFromInvite(data, hash, inviteId, success, error) {
success(team);
}
},
).catch(
(err) => {
if (error) {
error(err);
@@ -140,7 +127,7 @@ export function addUserToTeamFromInvite(data, hash, inviteId, success, error) {
}
export function addUsersToTeam(teamId, userIds, success, error) {
addUsersToTeamRedux(teamId, userIds)(dispatch, getState).then(
TeamActions.addUsersToTeam(teamId, userIds)(dispatch, getState).then(
(teamMembers) => {
if (teamMembers && success) {
success(teamMembers);
@@ -153,13 +140,13 @@ export function addUsersToTeam(teamId, userIds, success, error) {
}
export function getInviteInfo(inviteId, success, error) {
Client.getInviteInfo(
inviteId,
Client4.getTeamInviteInfo(inviteId).then(
(inviteData) => {
if (success) {
success(inviteData);
}
},
}
).catch(
(err) => {
if (error) {
error(err);
@@ -176,7 +163,7 @@ export function inviteMembers(data, success, error) {
data.invites.forEach((i) => {
emails.push(i.email);
});
sendEmailInvitesToTeam(TeamStore.getCurrentId(), emails)(dispatch, getState).then(
TeamActions.sendEmailInvitesToTeam(TeamStore.getCurrentId(), emails)(dispatch, getState).then(
(result) => {
if (result && success) {
success();
@@ -194,7 +181,7 @@ export function switchTeams(url) {
}
export function getTeamsForUser(userId, success, error) {
getTeamsForUserRedux(userId)(dispatch, getState).then(
TeamActions.getTeamsForUser(userId)(dispatch, getState).then(
(result) => {
if (result && success) {
success(result);
@@ -207,7 +194,7 @@ export function getTeamsForUser(userId, success, error) {
}
export function getTeamMembersForUser(userId, success, error) {
getTeamMembersForUserRedux(userId)(dispatch, getState).then(
TeamActions.getTeamMembersForUser(userId)(dispatch, getState).then(
(result) => {
if (result && success) {
success(result);

View File

@@ -15,7 +15,6 @@ import {getDirectChannelName, getUserIdFromChannelName} from 'utils/utils.jsx';
import {Constants, ActionTypes, Preferences} from 'utils/constants.jsx';
import {browserHistory} from 'react-router/es6';
// Redux actions
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
@@ -29,7 +28,7 @@ import {Client4} from 'mattermost-redux/client';
import {getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
import {getTeamMembersByIds, getMyTeamMembers, getMyTeamUnreads} from 'mattermost-redux/actions/teams';
import {getChannelAndMyMember} from 'mattermost-redux/actions/channels';
import {savePreferences, deletePreferences} from 'mattermost-redux/actions/preferences';
import {savePreferences as savePreferencesRedux, deletePreferences} from 'mattermost-redux/actions/preferences';
import {Preferences as PreferencesRedux} from 'mattermost-redux/constants';
@@ -242,7 +241,7 @@ export function loadNewDMIfNeeded(channelId) {
if (pref === false) {
PreferenceStore.setPreference(Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, userId, 'true');
const currentUserId = UserStore.getCurrentId();
savePreferences(currentUserId, [{user_id: currentUserId, category: Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, name: userId, value: 'true'}])(dispatch, getState);
savePreferencesRedux(currentUserId, [{user_id: currentUserId, category: Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, name: userId, value: 'true'}])(dispatch, getState);
loadProfilesForDM();
}
}
@@ -267,7 +266,7 @@ export function loadNewGMIfNeeded(channelId) {
if (pref === false) {
PreferenceStore.setPreference(Preferences.CATEGORY_GROUP_CHANNEL_SHOW, channelId, 'true');
const currentUserId = UserStore.getCurrentId();
savePreferences(currentUserId, [{user_id: currentUserId, category: Preferences.CATEGORY_GROUP_CHANNEL_SHOW, name: channelId, value: 'true'}])(dispatch, getState);
savePreferencesRedux(currentUserId, [{user_id: currentUserId, category: Preferences.CATEGORY_GROUP_CHANNEL_SHOW, name: channelId, value: 'true'}])(dispatch, getState);
loadProfilesForGM();
}
}
@@ -328,7 +327,7 @@ export function loadProfilesForGM() {
if (newPreferences.length > 0) {
const currentUserId = UserStore.getCurrentId();
savePreferences(currentUserId, newPreferences)(dispatch, getState);
savePreferencesRedux(currentUserId, newPreferences)(dispatch, getState);
}
}
@@ -369,7 +368,7 @@ export function loadProfilesForDM() {
if (newPreferences.length > 0) {
const currentUserId = UserStore.getCurrentId();
savePreferences(currentUserId, newPreferences)(dispatch, getState);
savePreferencesRedux(currentUserId, newPreferences)(dispatch, getState);
}
if (profilesToLoad.length > 0) {
@@ -794,6 +793,25 @@ export function loadMyTeamMembers() {
);
}
export function savePreferences(prefs, success, error) {
const currentUserId = UserStore.getCurrentId();
savePreferencesRedux(currentUserId, prefs)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.preferences.savePreferences.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}
export async function savePreference(category, name, value) {
const currentUserId = UserStore.getCurrentId();
return savePreferencesRedux(currentUserId, [{user_id: currentUserId, category, name, value}])(dispatch, getState);
}
export function autoResetStatus() {
return async (doDispatch, doGetState) => {
const {currentUserId} = getState().entities.users;
@@ -813,3 +831,16 @@ export function autoResetStatus() {
return userStatus;
};
}
export function sendPasswordResetEmail(email, success, error) {
UserActions.sendPasswordResetEmail(email)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.users.passwordReset.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}

View File

@@ -4,7 +4,7 @@
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import {WebrtcActionTypes} from 'utils/constants.jsx';
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
export function initWebrtc(userId, isCalling) {
AppDispatcher.handleServerAction({
@@ -22,15 +22,17 @@ export function handle(message) {
}
export function webrtcToken(success, error) {
Client.webrtcToken(
Client4.webrtcToken().then(
(data) => {
if (success) {
success(data);
}
},
}
).catch(
() => {
if (error) {
error();
}
});
}
);
}

View File

@@ -11,13 +11,9 @@ import BrowserStore from 'stores/browser_store.jsx';
import ErrorStore from 'stores/error_store.jsx';
import NotificationStore from 'stores/notification_store.jsx'; //eslint-disable-line no-unused-vars
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import Client from 'client/web_client.jsx';
import WebSocketClient from 'client/web_websocket_client.jsx';
import * as WebrtcActions from './webrtc_actions.jsx';
import * as Utils from 'utils/utils.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import {getSiteURL} from 'utils/url.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import {handleNewPost, loadProfilesForPosts} from 'actions/post_actions.jsx';
@@ -25,19 +21,22 @@ import {loadProfilesForSidebar} from 'actions/user_actions.jsx';
import {loadChannelsForCurrentUser} from 'actions/channel_actions.jsx';
import * as StatusActions from 'actions/status_actions.jsx';
import {ActionTypes, Constants, Preferences, SocketEvents, UserStatuses} from 'utils/constants.jsx';
import {Constants, Preferences, SocketEvents, UserStatuses} from 'utils/constants.jsx';
import {browserHistory} from 'react-router/es6';
// Redux actions
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {batchActions} from 'redux-batched-actions';
import {Client4} from 'mattermost-redux/client';
import * as TeamActions from 'mattermost-redux/actions/teams';
import {viewChannel, getChannelAndMyMember, getChannelStats} from 'mattermost-redux/actions/channels';
import {getPosts} from 'mattermost-redux/actions/posts';
import {setServerVersion} from 'mattermost-redux/actions/general';
import {ChannelTypes, TeamTypes, UserTypes, PostTypes} from 'mattermost-redux/action_types';
import {ChannelTypes, TeamTypes, UserTypes, PostTypes, EmojiTypes} from 'mattermost-redux/action_types';
const MAX_WEBSOCKET_FAILS = 7;
@@ -47,7 +46,7 @@ export function initialize() {
return;
}
let connUrl = getSiteURL();
let connUrl = Client4.getWebSocketUrl();
// replace the protocol with a websocket one
if (connUrl.startsWith('https:')) {
@@ -57,7 +56,7 @@ export function initialize() {
}
// append a port number if one isn't already specified
if (!(/:\d+$/).test(connUrl)) {
if (!(/:\d+/).test(connUrl)) {
if (connUrl.startsWith('wss:')) {
connUrl += ':' + global.window.mm_config.WebsocketSecurePort;
} else {
@@ -65,18 +64,10 @@ export function initialize() {
}
}
// append the websocket api path
connUrl += Client.getUsersRoute() + '/websocket';
WebSocketClient.setEventCallback(handleEvent);
WebSocketClient.setFirstConnectCallback(handleFirstConnect);
WebSocketClient.setReconnectCallback(() => reconnect(false));
WebSocketClient.setMissedEventCallback(() => {
if (global.window.mm_config.EnableDeveloper === 'true') {
Client.logClientError('missed websocket event seq=' + WebSocketClient.eventSequence);
}
reconnect(false);
});
WebSocketClient.setMissedEventCallback(() => reconnect(false));
WebSocketClient.setCloseCallback(handleClose);
WebSocketClient.initialize(connUrl);
}
@@ -95,11 +86,9 @@ export function reconnect(includeWebSocket = true) {
reconnectWebSocket();
}
if (Client.teamId) {
loadChannelsForCurrentUser();
getPosts(ChannelStore.getCurrentId())(dispatch, getState);
StatusActions.loadStatusesForChannelAndSidebar();
}
loadChannelsForCurrentUser();
getPosts(ChannelStore.getCurrentId())(dispatch, getState);
StatusActions.loadStatusesForChannelAndSidebar();
ErrorStore.clearLastError();
ErrorStore.emitChange();
@@ -269,25 +258,10 @@ function handlePostDeleteEvent(msg) {
dispatch({type: PostTypes.POST_DELETED, data: post});
}
function handleTeamAddedEvent(msg) {
Client.getTeam(msg.data.team_id, (team) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_TEAM,
team
});
Client.getMyTeamMembers((data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_MY_TEAM_MEMBERS,
team_members: data
});
AsyncClient.getMyTeamsUnread();
}, (err) => {
AsyncClient.dispatchError(err, 'getMyTeamMembers');
});
}, (err) => {
AsyncClient.dispatchError(err, 'getTeam');
});
async function handleTeamAddedEvent(msg) {
await TeamActions.getTeam(msg.data.team_id)(dispatch, getState);
await TeamActions.getMyTeamMembers()(dispatch, getState);
await TeamActions.getMyTeamUnreads()(dispatch, getState);
}
function handleLeaveTeamEvent(msg) {
@@ -296,7 +270,6 @@ function handleLeaveTeamEvent(msg) {
// if they are on the team being removed redirect them to default team
if (TeamStore.getCurrentId() === msg.data.team_id) {
Client.setTeamId('');
BrowserStore.removeGlobalItem('team');
BrowserStore.removeGlobalItem(msg.data.team_id);
@@ -424,7 +397,6 @@ function handleStatusChangedEvent(msg) {
}
function handleHelloEvent(msg) {
Client.serverVersion = msg.data.server_version;
setServerVersion(msg.data.server_version)(dispatch, getState);
}
@@ -445,9 +417,9 @@ function handleReactionAddedEvent(msg) {
function handleAddEmoji(msg) {
const data = JSON.parse(msg.data.emoji);
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_CUSTOM_EMOJI,
emoji: data
dispatch({
type: EmojiTypes.RECEIVED_CUSTOM_EMOJI,
data
});
}

View File

@@ -1,154 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import Client from './client.jsx';
import TeamStore from 'stores/team_store.jsx';
import UserStore from 'stores/user_store.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import {reconnect} from 'actions/websocket_actions.jsx';
import request from 'superagent';
const HTTP_UNAUTHORIZED = 401;
const mfaPaths = [
'/mfa/setup',
'/mfa/confirm'
];
class WebClientClass extends Client {
constructor() {
super();
this.enableLogErrorsToConsole(true);
this.hasInternetConnection = true;
TeamStore.addChangeListener(this.onTeamStoreChanged.bind(this));
}
onTeamStoreChanged() {
this.setTeamId(TeamStore.getCurrentId());
}
trackEvent(category, event, props) {
if (global.window && global.window.analytics) {
const properties = Object.assign({category, type: event, user_actual_id: UserStore.getCurrentId()}, props);
const options = {
context: {
ip: '0.0.0.0'
},
page: {
path: '',
referrer: '',
search: '',
title: '',
url: ''
},
anonymousId: '00000000000000000000000000'
};
global.window.analytics.track('event', properties, options);
}
}
handleError(err, res) {
if (res && res.body && res.body.id === 'api.context.mfa_required.app_error') {
if (mfaPaths.indexOf(window.location.pathname) === -1) {
window.location.reload();
}
return;
}
if (err.status === HTTP_UNAUTHORIZED && res.req.url !== this.getUsersRoute() + '/login' && !res.req.url.startsWith(this.getUsersRoute() + '/claim')) {
GlobalActions.emitUserLoggedOutEvent('/login');
}
if (err.status == null) {
this.hasInternetConnection = false;
}
}
handleSuccess = (res) => { // eslint-disable-line no-unused-vars
if (res && !this.hasInternetConnection) {
reconnect();
this.hasInternetConnection = true;
}
}
// not sure why but super.login doesn't work if using an () => arrow functions.
// I think this might be a webpack issue.
webLogin(loginId, password, token, success, error) {
this.login(
loginId,
password,
token,
(data) => {
this.trackEvent('api', 'api_users_login_success');
BrowserStore.signalLogin();
if (success) {
success(data);
}
},
(err) => {
this.trackEvent('api', 'api_users_login_fail');
if (error) {
error(err);
}
}
);
}
webLoginByLdap(loginId, password, token, success, error) {
this.loginByLdap(
loginId,
password,
token,
(data) => {
this.trackEvent('api', 'api_users_login_success');
this.trackEvent('api', 'api_users_login_ldap_success');
BrowserStore.signalLogin();
if (success) {
success(data);
}
},
(err) => {
this.trackEvent('api', 'api_users_login_fail');
this.trackEvent('api', 'api_users_login_ldap_fail');
if (error) {
error(err);
}
}
);
}
getYoutubeVideoInfo(googleKey, videoId, success, error) {
request.get('https://www.googleapis.com/youtube/v3/videos').
query({part: 'snippet', id: videoId, key: googleKey}).
end((err, res) => {
if (err) {
return error(err);
}
if (!res.body) {
console.error('Missing response body for getYoutubeVideoInfo'); // eslint-disable-line no-console
}
return success(res.body);
});
}
uploadFileV4(file, filename, channelId, clientId, success, error) {
return request.
post(`${this.url}/api/v4/files`).
set(this.defaultHeaders).
attach('files', file, filename).
field('channel_id', channelId).
field('client_ids', clientId).
accept('application/json').
end(this.handleResponse.bind(this, 'uploadFile', success, error));
}
}
var WebClient = new WebClientClass();
export default WebClient;

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +0,0 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
// This file is only for testing on non-browser environments.
// See browser_web_client.jsx for the actual implementation for browsers.
import Client from './client.jsx';
var WebClient = new Client();
export default WebClient;

View File

@@ -16,7 +16,7 @@ import AnalyticsStore from 'stores/analytics_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import UserStore from 'stores/user_store.jsx';
import {getStandardAnalytics} from 'utils/async_client.jsx';
import {getStandardAnalytics} from 'actions/admin_actions.jsx';
import {Constants, StatTypes, UserSearchOptions} from 'utils/constants.jsx';
import * as Utils from 'utils/utils.jsx';

View File

@@ -1,16 +1,19 @@
import PropTypes from 'prop-types';
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import PropTypes from 'prop-types';
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
import ManageTeamsModal from 'components/admin_console/manage_teams_modal/manage_teams_modal.jsx';
import ResetPasswordModal from 'components/admin_console/reset_password_modal.jsx';
import SearchableUserList from 'components/searchable_user_list/searchable_user_list.jsx';
import {getUser} from 'utils/async_client.jsx';
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {getUser} from 'mattermost-redux/actions/users';
import {Constants} from 'utils/constants.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -107,7 +110,7 @@ export default class SystemUsersList extends React.Component {
}
doPasswordResetSubmit(user) {
getUser(user.id);
getUser(user.id)(dispatch, getState);
this.setState({
showPasswordModal: false,

View File

@@ -8,7 +8,7 @@ import StatisticCount from './statistic_count.jsx';
import AnalyticsStore from 'stores/analytics_store.jsx';
import * as Utils from 'utils/utils.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as AdminActions from 'actions/admin_actions.jsx';
import Constants from 'utils/constants.jsx';
const StatTypes = Constants.StatTypes;
@@ -28,12 +28,12 @@ export default class SystemAnalytics extends React.Component {
componentDidMount() {
AnalyticsStore.addChangeListener(this.onChange);
AsyncClient.getStandardAnalytics();
AsyncClient.getPostsPerDayAnalytics();
AsyncClient.getUsersPerDayAnalytics();
AdminActions.getStandardAnalytics();
AdminActions.getPostsPerDayAnalytics();
AdminActions.getUsersPerDayAnalytics();
if (global.window.mm_license.IsLicensed === 'true') {
AsyncClient.getAdvancedAnalytics();
AdminActions.getAdvancedAnalytics();
}
}

View File

@@ -11,7 +11,7 @@ import LoadingScreen from 'components/loading_screen.jsx';
import AnalyticsStore from 'stores/analytics_store.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as AdminActions from 'actions/admin_actions.jsx';
import {StatTypes} from 'utils/constants.jsx';
import LineChart from 'components/analytics/line_chart.jsx';
@@ -71,10 +71,9 @@ export default class TeamAnalytics extends React.Component {
}
getData(id) {
AsyncClient.getStandardAnalytics(id);
AsyncClient.getPostsPerDayAnalytics(id);
AsyncClient.getUsersPerDayAnalytics(id);
AsyncClient.getRecentAndNewUsersAnalytics(id);
AdminActions.getStandardAnalytics(id);
AdminActions.getPostsPerDayAnalytics(id);
AdminActions.getUsersPerDayAnalytics(id);
}
componentWillUnmount() {

View File

@@ -9,7 +9,7 @@ import AnalyticsStore from 'stores/analytics_store.jsx';
import ErrorStore from 'stores/error_store.jsx';
import UserStore from 'stores/user_store.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as AdminActions from 'actions/admin_actions.jsx';
import {ErrorBarTypes, StatTypes} from 'utils/constants.jsx';
import {isLicenseExpiring, isLicenseExpired, isLicensePastGracePeriod, displayExpiryDate} from 'utils/license_utils.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -150,7 +150,7 @@ export default class AnnouncementBar extends React.PureComponent {
onErrorChange() {
const newState = this.getState();
if (newState.message === ErrorBarTypes.LICENSE_EXPIRING && !this.state.totalUsers) {
AsyncClient.getStandardAnalytics();
AdminActions.getStandardAnalytics();
}
this.setState(newState);
}

View File

@@ -25,11 +25,9 @@ export default class ChannelView extends React.Component {
this.state = this.getStateFromStores(props);
}
getStateFromStores(props) {
const channel = ChannelStore.getByName(props.params.channel);
const channelId = channel ? channel.id : '';
getStateFromStores() {
return {
channelId
channelId: ChannelStore.getCurrentId()
};
}
isStateValid() {

View File

@@ -1,11 +1,10 @@
import PropTypes from 'prop-types';
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import PropTypes from 'prop-types';
import * as AsyncClient from 'utils/async_client.jsx';
import * as EmojiActions from 'actions/emoji_actions.jsx';
import EmojiStore from 'stores/emoji_store.jsx';
import BackstageHeader from 'components/backstage/components/backstage_header.jsx';
@@ -115,7 +114,7 @@ export default class AddEmoji extends React.Component {
return;
}
AsyncClient.addEmoji(
EmojiActions.addEmoji(
emoji,
this.state.image,
() => {

View File

@@ -7,14 +7,12 @@ import LoadingScreen from 'components/loading_screen.jsx';
import EmojiStore from 'stores/emoji_store.jsx';
import UserStore from 'stores/user_store.jsx';
import {loadEmoji} from 'actions/emoji_actions.jsx';
import * as EmojiActions from 'actions/emoji_actions.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as Utils from 'utils/utils.jsx';
import PropTypes from 'prop-types';
import React from 'react';
import PropTypes from 'prop-types';
import {Link} from 'react-router';
import {FormattedMessage} from 'react-intl';
@@ -38,7 +36,7 @@ export default class EmojiList extends React.Component {
this.state = {
emojis: EmojiStore.getCustomEmojiMap(),
loading: !EmojiStore.hasReceivedCustomEmojis(),
loading: true,
filter: '',
users: UserStore.getProfiles()
};
@@ -49,7 +47,7 @@ export default class EmojiList extends React.Component {
UserStore.addChangeListener(this.handleUserChange);
if (window.mm_config.EnableCustomEmoji === 'true') {
loadEmoji();
EmojiActions.loadEmoji().then(() => this.setState({loading: false}));
}
this.updateTitle();
@@ -71,8 +69,7 @@ export default class EmojiList extends React.Component {
handleEmojiChange() {
this.setState({
emojis: EmojiStore.getCustomEmojiMap(),
loading: !EmojiStore.hasReceivedCustomEmojis()
emojis: EmojiStore.getCustomEmojiMap()
});
}
@@ -87,7 +84,7 @@ export default class EmojiList extends React.Component {
}
deleteEmoji(emoji) {
AsyncClient.deleteEmoji(emoji.id);
EmojiActions.deleteEmoji(emoji.id);
}
render() {

View File

@@ -3,7 +3,7 @@
import React from 'react';
import * as AsyncClient from 'utils/async_client.jsx';
import {getPublicLink} from 'actions/file_actions.jsx';
import Constants from 'utils/constants.jsx';
import ModalStore from 'stores/modal_store.jsx';
import PureRenderMixin from 'react-addons-pure-render-mixin';
@@ -34,7 +34,7 @@ export default class GetPublicLinkModal extends React.Component {
componentDidUpdate(prevProps, prevState) {
if (this.state.show && !prevState.show) {
AsyncClient.getPublicLink(this.state.fileId, this.handlePublicLink);
getPublicLink(this.state.fileId, this.handlePublicLink);
}
}

View File

@@ -11,8 +11,7 @@ import {checkMfa, webLogin} from 'actions/user_actions.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import UserStore from 'stores/user_store.jsx';
import Client from 'client/web_client.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import {Client4} from 'mattermost-redux/client';
import * as TextFormatting from 'utils/text_formatting.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -71,8 +70,6 @@ export default class LoginController extends React.Component {
if (this.props.location.query.extra === Constants.SIGNIN_VERIFIED && this.props.location.query.email) {
this.refs.password.focus();
}
AsyncClient.checkVersion();
}
preSubmit(e) {
@@ -243,7 +240,7 @@ export default class LoginController extends React.Component {
return (
<div>
<img
src={Client.getAdminRoute() + '/get_brand_image'}
src={Client4.getBrandImageUrl(0)}
/>
<p dangerouslySetInnerHTML={{__html: TextFormatting.formatText(text)}}/>
</div>
@@ -493,7 +490,7 @@ export default class LoginController extends React.Component {
<a
className='btn btn-custom-login gitlab'
key='gitlab'
href={Client.getOAuthRoute() + '/gitlab/login' + this.props.location.search}
href={Client4.getUrl() + '/oauth/gitlab/login' + this.props.location.search}
>
<span>
<span className='icon'/>
@@ -513,7 +510,7 @@ export default class LoginController extends React.Component {
<a
className='btn btn-custom-login google'
key='google'
href={Client.getOAuthRoute() + '/google/login' + this.props.location.search}
href={Client4.getUrl() + '/oauth/google/login' + this.props.location.search}
>
<span>
<span className='icon'/>
@@ -533,7 +530,7 @@ export default class LoginController extends React.Component {
<a
className='btn btn-custom-login office365'
key='office365'
href={Client.getOAuthRoute() + '/office365/login' + this.props.location.search}
href={Client4.getUrl() + '/oauth/office365/login' + this.props.location.search}
>
<span>
<span className='icon'/>

View File

@@ -4,7 +4,7 @@
import $ from 'jquery';
import ReactDOM from 'react-dom';
import * as Utils from 'utils/utils.jsx';
import client from 'client/web_client.jsx';
import {sendPasswordResetEmail} from 'actions/user_actions.jsx';
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
@@ -45,7 +45,7 @@ class PasswordResetSendLink extends React.Component {
error: ''
});
client.sendPasswordReset(
sendPasswordResetEmail(
email,
() => {
this.setState({

View File

@@ -40,7 +40,7 @@ export default class PostList extends React.PureComponent {
/**
* The channel the posts are in
*/
channel: PropTypes.object,
channel: PropTypes.object.isRequired,
/**
* The last time the channel was viewed, sets the new message separator

View File

@@ -3,7 +3,7 @@
import * as GlobalActions from 'actions/global_actions.jsx';
import LocalizationStore from 'stores/localization_store.jsx';
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
import {IntlProvider} from 'react-intl';
@@ -85,7 +85,7 @@ export default class Root extends React.Component {
localizationChanged() {
const locale = LocalizationStore.getLocale();
Client.setAcceptLanguage(locale);
Client4.setAcceptLanguage(locale);
this.setState({locale, translations: LocalizationStore.getTranslations()});
}

View File

@@ -18,7 +18,6 @@ import PreferenceStore from 'stores/preference_store.jsx';
import ModalStore from 'stores/modal_store.jsx';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import {sortTeamsByDisplayName} from 'utils/team_utils.jsx';
import * as Utils from 'utils/utils.jsx';
import * as ChannelUtils from 'utils/channel_utils.jsx';
@@ -42,8 +41,12 @@ import favicon from 'images/favicon/favicon-16x16.png';
import redFavicon from 'images/favicon/redfavicon-16x16.png';
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {getMyPreferences} from 'mattermost-redux/selectors/entities/preferences';
import {getUsers} from 'mattermost-redux/selectors/entities/users';
import {savePreferences} from 'mattermost-redux/actions/preferences';
export default class Sidebar extends React.Component {
constructor(props) {
@@ -381,13 +384,8 @@ export default class Sidebar extends React.Component {
category = Constants.Preferences.CATEGORY_GROUP_CHANNEL_SHOW;
}
AsyncClient.savePreference(
category,
id,
'false',
() => {
this.isLeaving.set(channel.id, false);
},
const currentUserId = UserStore.getCurrentId();
savePreferences(currentUserId, [{user_id: currentUserId, category, name: id, value: 'false'}])(dispatch, getState).then(
() => {
this.isLeaving.set(channel.id, false);
}

View File

@@ -1,9 +1,8 @@
import PropTypes from 'prop-types';
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import PropTypes from 'prop-types';
import FormError from 'components/form_error.jsx';
import LoadingScreen from 'components/loading_screen.jsx';
@@ -11,8 +10,7 @@ import LoadingScreen from 'components/loading_screen.jsx';
import UserStore from 'stores/user_store.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
import * as GlobalActions from 'actions/global_actions.jsx';
import {addUserToTeamFromInvite, getInviteInfo} from 'actions/team_actions.jsx';
import {loadMe} from 'actions/user_actions.jsx';
@@ -62,7 +60,6 @@ export default class SignupController extends React.Component {
}
componentDidMount() {
AsyncClient.checkVersion();
BrowserStore.removeGlobalItem('team');
if (this.props.location.query) {
const hash = this.props.location.query.h;
@@ -160,7 +157,7 @@ export default class SignupController extends React.Component {
<a
className='btn btn-custom-login btn--full gitlab'
key='gitlab'
href={Client.getOAuthRoute() + '/gitlab/signup' + window.location.search}
href={Client4.getOAuthRoute() + '/gitlab/signup' + window.location.search}
>
<span>
<span className='icon'/>
@@ -180,7 +177,7 @@ export default class SignupController extends React.Component {
<a
className='btn btn-custom-login btn--full google'
key='google'
href={Client.getOAuthRoute() + '/google/signup' + window.location.search}
href={Client4.getOAuthRoute() + '/google/signup' + window.location.search}
>
<span>
<span className='icon'/>
@@ -200,7 +197,7 @@ export default class SignupController extends React.Component {
<a
className='btn btn-custom-login btn--full office365'
key='office365'
href={Client.getOAuthRoute() + '/office365/signup' + window.location.search}
href={Client4.getOAuthRoute() + '/office365/signup' + window.location.search}
>
<span>
<span className='icon'/>

View File

@@ -10,7 +10,7 @@ import {autocompleteUsersInChannel} from 'actions/user_actions.jsx';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import * as Utils from 'utils/utils.jsx';
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
import {Constants, ActionTypes} from 'utils/constants.jsx';
import React from 'react';
@@ -66,7 +66,7 @@ class AtMentionSuggestion extends Suggestion {
icon = (
<img
className='mention__image'
src={Client.getUsersRoute() + '/' + user.id + '/image?time=' + user.last_picture_update}
src={Client4.getUsersRoute() + '/' + user.id + '/image?time=' + user.last_picture_update}
/>
);
}

View File

@@ -3,10 +3,10 @@
import React from 'react';
import * as AsyncClient from 'utils/async_client.jsx';
import Suggestion from './suggestion.jsx';
import {getSuggestedCommands} from 'actions/integration_actions.jsx';
class CommandSuggestion extends Suggestion {
render() {
const {item, isSelection} = this.props;
@@ -35,7 +35,7 @@ class CommandSuggestion extends Suggestion {
export default class CommandProvider {
handlePretextChanged(suggestionId, pretext) {
if (pretext.startsWith('/')) {
AsyncClient.getSuggestedCommands(pretext.toLowerCase(), suggestionId, CommandSuggestion, pretext.toLowerCase());
getSuggestedCommands(pretext.toLowerCase(), suggestionId, CommandSuggestion, pretext.toLowerCase());
}
}
}

View File

@@ -7,7 +7,7 @@ import Provider from './provider.jsx';
import {autocompleteUsersInTeam} from 'actions/user_actions.jsx';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
import * as Utils from 'utils/utils.jsx';
import {ActionTypes} from 'utils/constants.jsx';
@@ -41,7 +41,7 @@ class SearchUserSuggestion extends Suggestion {
<i className='fa fa fa-plus-square'/>
<img
className='profile-img rounded'
src={Client.getUsersRoute() + '/' + item.id + '/image?time=' + item.last_picture_update}
src={Client4.getUsersRoute() + '/' + item.id + '/image?time=' + item.last_picture_update}
/>
<div className='mention--align'>
<span>

View File

@@ -4,7 +4,6 @@
import Suggestion from './suggestion.jsx';
import Provider from './provider.jsx';
import Client from 'client/web_client.jsx';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import {Constants, ActionTypes} from 'utils/constants.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -47,7 +46,7 @@ class SwitchChannelSuggestion extends Suggestion {
<div className='pull-left'>
<img
className='mention__image'
src={Client.getUsersRoute() + '/' + channel.id + '/image?time=' + channel.last_picture_update}
src={Client4.getUsersRoute() + '/' + channel.id + '/image?time=' + channel.last_picture_update}
/>
</div>
);

View File

@@ -4,7 +4,7 @@
import UserStore from 'stores/user_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import {savePreference} from 'actions/user_actions.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import {trackEvent} from 'actions/diagnostics_actions.jsx';
@@ -60,7 +60,7 @@ export default class TutorialIntroScreens extends React.Component {
const step = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 0);
AsyncClient.savePreference(
savePreference(
Preferences.TUTORIAL_STEP,
UserStore.getCurrentId(),
(step + 1).toString()
@@ -81,7 +81,7 @@ export default class TutorialIntroScreens extends React.Component {
break;
}
AsyncClient.savePreference(
savePreference(
Preferences.TUTORIAL_STEP,
UserStore.getCurrentId(),
'999'

View File

@@ -3,7 +3,7 @@
import UserStore from 'stores/user_store.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import {savePreference} from 'actions/user_actions.jsx';
import {trackEvent} from 'actions/diagnostics_actions.jsx';
import Constants from 'utils/constants.jsx';
@@ -39,7 +39,7 @@ export default class TutorialTip extends React.Component {
if (!show && this.state.currentScreen >= this.props.screens.length - 1) {
const step = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 0);
AsyncClient.savePreference(
savePreference(
Preferences.TUTORIAL_STEP,
UserStore.getCurrentId(),
(step + 1).toString()
@@ -91,7 +91,7 @@ export default class TutorialTip extends React.Component {
trackEvent('tutorial', tag);
}
AsyncClient.savePreference(
savePreference(
Preferences.TUTORIAL_STEP,
UserStore.getCurrentId(),
'999'

View File

@@ -3,7 +3,7 @@
import ProfilePopover from './profile_popover.jsx';
import * as Utils from 'utils/utils.jsx';
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
import {OverlayTrigger} from 'react-bootstrap';
@@ -63,7 +63,7 @@ export default class UserProfile extends React.Component {
if (this.props.user) {
name = Utils.displayUsername(this.props.user.id);
profileImg = Client.getUsersRoute() + '/' + this.props.user.id + '/image?time=' + this.props.user.last_picture_update;
profileImg = Client4.getUsersRoute() + '/' + this.props.user.id + '/image?time=' + this.props.user.last_picture_update;
}
if (this.props.overwriteName) {

View File

@@ -1,11 +1,10 @@
import PropTypes from 'prop-types';
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import PropTypes from 'prop-types';
import {savePreference} from 'utils/async_client.jsx';
import {savePreference} from 'actions/user_actions.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import {localizeMessage} from 'utils/utils.jsx';

View File

@@ -2,21 +2,21 @@
// See License.txt for license information.
import $ from 'jquery';
import * as AsyncClient from 'utils/async_client.jsx';
import SettingItemMin from '../setting_item_min.jsx';
import SettingItemMax from '../setting_item_max.jsx';
import Constants from 'utils/constants.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import UserStore from 'stores/user_store.jsx';
import Constants from 'utils/constants.jsx';
const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES;
import * as Utils from 'utils/utils.jsx';
import {FormattedMessage} from 'react-intl';
const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES;
import PropTypes from 'prop-types';
import {savePreferences} from 'actions/user_actions.jsx';
import React from 'react';
import PropTypes from 'prop-types';
import {FormattedMessage} from 'react-intl';
export default class AdvancedSettingsDisplay extends React.Component {
constructor(props) {
@@ -133,7 +133,7 @@ export default class AdvancedSettingsDisplay extends React.Component {
});
});
AsyncClient.savePreferences(
savePreferences(
preferences,
() => {
this.updateSection('');

View File

@@ -7,11 +7,11 @@ import SettingItemMax from '../setting_item_max.jsx';
import ManageLanguages from './manage_languages.jsx';
import ThemeSetting from './user_settings_theme.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import UserStore from 'stores/user_store.jsx';
import * as Utils from 'utils/utils.jsx';
import * as I18n from 'i18n/i18n.jsx';
import {savePreferences} from 'actions/user_actions.jsx';
import Constants from 'utils/constants.jsx';
const Preferences = Constants.Preferences;
@@ -29,9 +29,8 @@ function getDisplayStateFromStores() {
};
}
import PropTypes from 'prop-types';
import React from 'react';
import PropTypes from 'prop-types';
export default class UserSettingsDisplay extends React.Component {
constructor(props) {
@@ -92,7 +91,7 @@ export default class UserSettingsDisplay extends React.Component {
value: this.state.collapseDisplay
};
AsyncClient.savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference, messageDisplayPreference, collapseDisplayPreference],
savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference, messageDisplayPreference, collapseDisplayPreference],
() => {
this.updateSection('');
},

View File

@@ -9,7 +9,7 @@ import SettingPicture from 'components/setting_picture.jsx';
import UserStore from 'stores/user_store.jsx';
import ErrorStore from 'stores/error_store.jsx';
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
import Constants from 'utils/constants.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -1141,7 +1141,7 @@ class UserSettingsGeneralTab extends React.Component {
<SettingPicture
title={formatMessage(holders.profilePicture)}
submit={this.submitPicture}
src={Client.getUsersRoute() + '/' + user.id + '/image?time=' + user.last_picture_update}
src={Client4.getUsersRoute() + '/' + user.id + '/image?time=' + user.last_picture_update}
serverError={serverError}
clientError={clientError}
updateSection={(e) => {

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
import WebSocketClient from 'client/web_websocket_client.jsx';
import UserStore from 'stores/user_store.jsx';
@@ -197,7 +197,7 @@ export default class WebrtcNotification extends React.Component {
const user = this.state.userCalling;
if (user) {
const username = Utils.displayUsername(user.id);
const profileImgSrc = Client.getUsersRoute() + '/' + user.id + '/image?time=' + (user.last_picture_update || new Date().getTime());
const profileImgSrc = Client4.getUsersRoute() + '/' + user.id + '/image?time=' + (user.last_picture_update || new Date().getTime());
const profileImg = (
<img
className='user-popover__image'

View File

@@ -5,7 +5,7 @@ import UserStore from 'stores/user_store.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import WebrtcStore from 'stores/webrtc_store.jsx';
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
import WebSocketClient from 'client/web_websocket_client.jsx';
import Janus from 'janus';
@@ -84,14 +84,14 @@ export default class WebrtcController extends React.Component {
const currentUser = UserStore.getCurrentUser();
const remoteUser = UserStore.getProfile(props.userId);
const remoteUserImage = Client.getUsersRoute() + '/' + remoteUser.id + '/image?time=' + remoteUser.last_picture_update;
const remoteUserImage = Client4.getUsersRoute() + '/' + remoteUser.id + '/image?time=' + remoteUser.last_picture_update;
this.state = {
windowWidth: Utils.windowWidth(),
windowHeight: Utils.windowHeight(),
channelId: ChannelStore.getCurrentId(),
currentUser,
currentUserImage: Client.getUsersRoute() + '/' + currentUser.id + '/image?time=' + currentUser.last_picture_update,
currentUserImage: Client4.getUsersRoute() + '/' + currentUser.id + '/image?time=' + currentUser.last_picture_update,
remoteUserImage,
localMediaLoaded: false,
isPaused: false,
@@ -133,7 +133,7 @@ export default class WebrtcController extends React.Component {
(nextProps.userId !== this.props.userId) ||
(nextProps.isCaller !== this.props.isCaller)) {
const remoteUser = UserStore.getProfile(nextProps.userId);
const remoteUserImage = Client.getUsersRoute() + '/' + remoteUser.id + '/image?time=' + remoteUser.last_picture_update;
const remoteUserImage = Client4.getUsersRoute() + '/' + remoteUser.id + '/image?time=' + remoteUser.last_picture_update;
this.setState({
error: null,
remoteUserImage

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import WebClient from 'client/web_client.jsx';
import {getYoutubeVideoInfo} from 'actions/integration_actions.jsx';
import * as Utils from 'utils/utils.jsx';
const ytRegex = /(?:http|https):\/\/(?:www\.|m\.)?(?:(?:youtube\.com\/(?:(?:v\/)|(?:(?:watch|embed\/watch)(?:\/|.*v=))|(?:embed\/)|(?:user\/[^/]+\/u\/[0-9]\/)))|(?:youtu\.be\/))([^#&?]*)/;
@@ -98,7 +98,7 @@ export default class YoutubeVideo extends React.PureComponent {
componentDidMount() {
const key = global.window.mm_config.GoogleDeveloperKey;
if (key) {
WebClient.getYoutubeVideoInfo(key, this.state.videoId,
getYoutubeVideoInfo(key, this.state.videoId,
this.handleReceivedMetadata, this.handleMetadataError);
} else {
this.loadWithoutKey();

View File

@@ -14,8 +14,6 @@ import {reconnect} from 'actions/websocket_actions.jsx';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
import * as AsyncClient from 'utils/async_client.jsx';
import Client from 'client/web_client.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -31,6 +29,8 @@ const dispatch = store.dispatch;
const getState = store.getState;
import {fetchMyChannelsAndMembers, joinChannel} from 'mattermost-redux/actions/channels';
import {getMyTeamUnreads} from 'mattermost-redux/actions/teams';
import {getUser, getUserByUsername, getUserByEmail} from 'mattermost-redux/actions/users';
function onChannelEnter(nextState, replace, callback) {
doChannelChange(nextState, replace, callback);
@@ -111,7 +111,7 @@ function preNeedsTeam(nextState, replace, callback) {
if (nextState.location.pathname.indexOf('/channels/') > -1 ||
nextState.location.pathname.indexOf('/pl/') > -1 ||
nextState.location.pathname.indexOf('/messages/') > -1) {
AsyncClient.getMyTeamsUnread();
getMyTeamUnreads()(dispatch, getState);
fetchMyChannelsAndMembers(team.id)(dispatch, getState);
}
@@ -172,13 +172,14 @@ function onChannelByIdentifierEnter(state, replace, callback) {
replace(`/${state.params.team}/messages/@${teammate.username}`);
callback();
} else {
Client.getUser(
userId,
getUser(userId)(dispatch, getState).then(
(profile) => {
replace(`/${state.params.team}/messages/@${profile.username}`);
callback();
}, () => {
handleError(state, replace, callback);
if (profile) {
replace(`/${state.params.team}/messages/@${profile.username}`);
callback();
} else if (profile == null) {
handleError(state, replace, callback);
}
}
);
}
@@ -224,7 +225,16 @@ function onChannelByIdentifierEnter(state, replace, callback) {
if (teammate) {
directChannelToUser(teammate, state, replace, callback);
} else {
Client.getByUsername(username, success, error);
getUserByUsername(username)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.users.getUserByUsername.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}
} else if (identifier.indexOf('@') > 0) { // email identifier
const email = identifier;
@@ -232,7 +242,16 @@ function onChannelByIdentifierEnter(state, replace, callback) {
if (teammate) {
directChannelToUser(teammate, state, replace, callback);
} else {
Client.getByEmail(email, success, error);
getUserByEmail(email)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.users.getUser.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}
}
}
@@ -242,10 +261,6 @@ function directChannelToUser(profile, state, replace, callback) {
openDirectChannelToUser(
profile.id,
(channel) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_CHANNEL,
channel
});
GlobalActions.emitChannelClickEvent(channel);
callback();
},

View File

@@ -1,19 +1,31 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
import EventEmitter from 'events';
import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
const CHANGE_EVENT = 'change';
import store from 'stores/redux_store.jsx';
class AnalyticsStoreClass extends EventEmitter {
constructor() {
super();
this.systemStats = {};
this.teamStats = {};
this.entities = {};
store.subscribe(() => {
const newEntities = store.getState().entities.admin;
if (newEntities.analytics !== this.entities.analytics) {
this.emitChange();
}
if (newEntities.teamAnalytics !== this.entities.teamAnalytics) {
this.emitChange();
}
this.entities = newEntities;
});
}
emitChange() {
@@ -29,57 +41,18 @@ class AnalyticsStoreClass extends EventEmitter {
}
getAllSystem() {
return JSON.parse(JSON.stringify(this.systemStats));
return JSON.parse(JSON.stringify(store.getState().entities.admin.analytics));
}
getAllTeam(id) {
if (id in this.teamStats) {
return JSON.parse(JSON.stringify(this.teamStats[id]));
const teamStats = store.getState().entities.admin.teamAnalytics[id];
if (teamStats) {
return JSON.parse(JSON.stringify(teamStats));
}
return {};
}
storeSystemStats(newStats) {
for (const stat in newStats) {
if (!newStats.hasOwnProperty(stat)) {
continue;
}
this.systemStats[stat] = newStats[stat];
}
}
storeTeamStats(id, newStats) {
if (!(id in this.teamStats)) {
this.teamStats[id] = {};
}
for (const stat in newStats) {
if (!newStats.hasOwnProperty(stat)) {
continue;
}
this.teamStats[id][stat] = newStats[stat];
}
}
}
var AnalyticsStore = new AnalyticsStoreClass();
AnalyticsStore.dispatchToken = AppDispatcher.register((payload) => {
var action = payload.action;
switch (action.type) {
case ActionTypes.RECEIVED_ANALYTICS:
if (action.teamId == null) {
AnalyticsStore.storeSystemStats(action.stats);
} else {
AnalyticsStore.storeTeamStats(action.teamId, action.stats);
}
AnalyticsStore.emitChange();
break;
default:
}
});
export default AnalyticsStore;

View File

@@ -1,12 +1,15 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import Client from '../client/web_client.jsx';
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import Constants from 'utils/constants.jsx';
import EventEmitter from 'events';
import * as Emoji from 'utils/emoji.jsx';
import store from 'stores/redux_store.jsx';
import {getCustomEmojisByName} from 'mattermost-redux/selectors/entities/emojis';
import {Client4} from 'mattermost-redux/client';
const ActionTypes = Constants.ActionTypes;
const CHANGE_EVENT = 'changed';
@@ -72,10 +75,20 @@ class EmojiStore extends EventEmitter {
this.setMaxListeners(600);
this.receivedCustomEmojis = false;
this.customEmojis = new Map();
this.map = new EmojiMap(getCustomEmojisByName(store.getState()));
this.map = new EmojiMap(this.customEmojis);
this.entities = {};
store.subscribe(() => {
const newEntities = store.getState().entities.emojis.customEmoji;
if (newEntities !== this.entities) {
this.map = new EmojiMap(getCustomEmojisByName(store.getState()));
this.emitChange();
}
this.entities = newEntities;
});
}
addChangeListener(callback) {
@@ -90,41 +103,12 @@ class EmojiStore extends EventEmitter {
this.emit(CHANGE_EVENT);
}
hasReceivedCustomEmojis() {
return this.receivedCustomEmojis;
}
setCustomEmojis(customEmojis) {
customEmojis.sort((a, b) => a.name.localeCompare(b.name));
this.customEmojis = new Map();
for (const emoji of customEmojis) {
this.addCustomEmoji(emoji);
}
this.map = new EmojiMap(this.customEmojis);
}
addCustomEmoji(emoji) {
this.customEmojis.set(emoji.name, emoji);
}
removeCustomEmoji(id) {
for (const [name, emoji] of this.customEmojis) {
if (emoji.id === id) {
this.customEmojis.delete(name);
break;
}
}
}
hasSystemEmoji(name) {
return Emoji.EmojiIndicesByAlias.has(name);
}
getCustomEmojiMap() {
return this.customEmojis;
return getCustomEmojisByName(store.getState());
}
getEmojis() {
@@ -202,7 +186,7 @@ class EmojiStore extends EventEmitter {
getEmojiImageUrl(emoji) {
if (emoji.id) {
return Client.getCustomEmojiImageUrl(emoji.id);
return Client4.getUrlVersion() + '/emoji/' + emoji.id + '/image';
}
const filename = emoji.filename || emoji.aliases[0];
@@ -214,20 +198,6 @@ class EmojiStore extends EventEmitter {
const action = payload.action;
switch (action.type) {
case ActionTypes.RECEIVED_CUSTOM_EMOJIS:
this.setCustomEmojis(action.emojis);
this.receivedCustomEmojis = true;
this.emitChange();
break;
case ActionTypes.RECEIVED_CUSTOM_EMOJI:
this.addCustomEmoji(action.emoji);
this.emitChange();
break;
case ActionTypes.REMOVED_CUSTOM_EMOJI:
this.removeCustomEmoji(action.id);
this.removeRecentEmoji(action.id);
this.emitChange();
break;
case ActionTypes.EMOJI_POSTED:
this.addRecentEmoji(action.alias);
this.emitChange();

View File

@@ -3,9 +3,6 @@
import EventEmitter from 'events';
import ChannelStore from 'stores/channel_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import Constants from 'utils/constants.jsx';
const UserStatuses = Constants.UserStatuses;
@@ -23,6 +20,9 @@ import store from 'stores/redux_store.jsx';
import * as Selectors from 'mattermost-redux/selectors/entities/users';
import {UserTypes} from 'mattermost-redux/action_types';
import ChannelStore from 'stores/channel_store.jsx';
import TeamStore from 'stores/team_store.jsx';
var Utils;
class UserStoreClass extends EventEmitter {

View File

@@ -1,291 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.Admin', function() {
test('Admin.reloadConfig', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().reloadConfig(
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.recycleDatabaseConnection', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().recycleDatabaseConnection(
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.getComplianceReports', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().getComplianceReports(
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.saveComplianceReports', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var job = {};
job.desc = 'desc';
job.emails = '';
job.keywords = 'test';
job.start_at = new Date();
job.end_at = new Date();
TestHelper.basicClient().saveComplianceReports(
job,
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.getLogs', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().getLogs(
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.getServerAudits', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().getServerAudits(
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.getConfig', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().getConfig(
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.getAnalytics', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().getAnalytics(
'standard',
null,
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.getTeamAnalytics', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().getTeamAnalytics(
TestHelper.basicTeam().id,
'standard',
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.saveConfig', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var config = {};
config.site_name = 'test';
TestHelper.basicClient().saveConfig(
config,
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.testEmail', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var config = {};
config.site_name = 'test';
TestHelper.basicClient().testEmail(
config,
function() {
done.fail(new Error('should need system admin permissions'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.adminResetMfa', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().adminResetMfa(
TestHelper.basicUser().id,
function() {
done.fail(new Error('should need a license'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.adminResetPassword', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var user = TestHelper.basicUser();
TestHelper.basicClient().resetPassword(
user.id,
'new_password',
function() {
throw Error('shouldnt work');
},
function(err) {
// this should fail since you're not a system admin
expect(err.id).toBe('api.context.invalid_param.app_error');
done();
}
);
});
});
test('License.getClientLicenceConfig', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getClientLicenceConfig(
function(data) {
expect(data.IsLicensed).toBe('false');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('License.removeLicenseFile', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().removeLicenseFile(
function() {
done.fail(new Error('not enabled'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
test('Admin.ldapSyncNow', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().ldapSyncNow(
function() {
throw Error('shouldnt work');
},
function() {
// this should fail since you're not a system admin
done();
}
);
});
});
test.skip('License.uploadLicenseFile', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().uploadLicenseFile(
'form data',
function() {
done.fail(new Error('not enabled'));
},
function(err) {
expect(err.id).toBe('api.context.permissions.app_error');
done();
}
);
});
});
});

View File

@@ -1,457 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.Channels', function() {
test('createChannel', function(done) {
TestHelper.initBasic(done, () => {
var channel = TestHelper.fakeChannel();
channel.team_id = TestHelper.basicTeam().id;
TestHelper.basicClient().createChannel(
channel,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
expect(data.name).toBe(channel.name);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('createDirectChannel', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().createUser(
TestHelper.fakeUser(),
function(user2) {
TestHelper.basicClient().createDirectChannel(
user2.id,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('createGroupChannel', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().createUser(
TestHelper.fakeUser(),
(user1) => {
TestHelper.basicClient().createUser(
TestHelper.fakeUser(),
function(user2) {
TestHelper.basicClient().createGroupChannel(
[user2.id, user1.id],
function(data) {
expect(data.id.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateChannel', function(done) {
TestHelper.initBasic(done, () => {
var channel = TestHelper.basicChannel();
channel.display_name = 'changed';
TestHelper.basicClient().updateChannel(
channel,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
expect(data.display_name).toEqual('changed');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateChannelHeader', function(done) {
TestHelper.initBasic(done, () => {
var channel = TestHelper.basicChannel();
channel.display_name = 'changed';
TestHelper.basicClient().updateChannelHeader(
channel.id,
'new header',
function(data) {
expect(data.id.length).toBeGreaterThan(0);
expect(data.header).toBe('new header');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateChannelPurpose', function(done) {
TestHelper.initBasic(done, () => {
var channel = TestHelper.basicChannel();
channel.display_name = 'changed';
TestHelper.basicClient().updateChannelPurpose(
channel.id,
'new purpose',
function(data) {
expect(data.id.length).toBeGreaterThan(0);
expect(data.purpose).toEqual('new purpose');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateChannelNotifyProps', function(done) {
TestHelper.initBasic(done, () => {
var props = {};
props.channel_id = TestHelper.basicChannel().id;
props.user_id = TestHelper.basicUser().id;
props.desktop = 'all';
TestHelper.basicClient().updateChannelNotifyProps(
props,
function(data) {
expect(data.desktop).toEqual('all');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('leaveChannel', function(done) {
TestHelper.initBasic(done, () => {
var channel = TestHelper.basicChannel();
TestHelper.basicClient().leaveChannel(
channel.id,
function(data) {
expect(data.id).toEqual(channel.id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('joinChannel', function(done) {
TestHelper.initBasic(done, () => {
var channel = TestHelper.basicChannel();
TestHelper.basicClient().leaveChannel(
channel.id,
function() {
TestHelper.basicClient().joinChannel(
channel.id,
function() {
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('joinChannelByName', function(done) {
TestHelper.initBasic(done, () => {
var channel = TestHelper.basicChannel();
TestHelper.basicClient().leaveChannel(
channel.id,
function() {
TestHelper.basicClient().joinChannelByName(
channel.name,
function() {
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('deleteChannel', function(done) {
TestHelper.initBasic(done, () => {
var channel = TestHelper.basicChannel();
TestHelper.basicClient().deleteChannel(
channel.id,
function(data) {
expect(data.id).toEqual(channel.id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('viewChannel', function(done) {
TestHelper.initBasic(done, () => {
var channel = TestHelper.basicChannel();
TestHelper.basicClient().viewChannel(
channel.id,
'',
0,
function() {
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getChannels', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getChannels(
function(data) {
expect(data.length).toBe(3);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getChannel', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getChannel(
TestHelper.basicChannel().id,
function(data) {
expect(TestHelper.basicChannel().id).toEqual(data.channel.id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getMoreChannelsPage', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getMoreChannelsPage(
0,
100,
function(data) {
expect(data.length).toBe(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('searchMoreChannels', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().searchMoreChannels(
'blargh',
function(data) {
expect(data.length).toBe(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('autocompleteChannels', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().autocompleteChannels(
TestHelper.basicChannel().name,
function(data) {
expect(data).not.toBeNull();
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getChannelCounts', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getChannelCounts(
function(data) {
expect(data.counts[TestHelper.basicChannel().id]).toBe(1);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getMyChannelMembers', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getMyChannelMembers(
function(data) {
expect(data.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getMyChannelMembersForTeam', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getMyChannelMembersForTeam(
TestHelper.basicTeam().id,
function(data) {
expect(data.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getChannelStats', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getChannelStats(
TestHelper.basicChannel().id,
function(data) {
expect(data.member_count).toBe(1);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getChannelMember', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getChannelMember(
TestHelper.basicChannel().id,
TestHelper.basicUser().id,
function(data) {
expect(data.channel_id).toEqual(TestHelper.basicChannel().id);
expect(data.user_id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('addChannelMember', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().createUserWithInvite(
TestHelper.fakeUser(),
null,
null,
TestHelper.basicTeam().invite_id,
function(user2) {
TestHelper.basicClient().addChannelMember(
TestHelper.basicChannel().id,
user2.id,
function(data) {
expect(data.channel_id.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('removeChannelMember', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().removeChannelMember(
TestHelper.basicChannel().id,
TestHelper.basicUser().id,
function(data) {
expect(data.channel_id.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getChannelByName', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getChannelByName(
TestHelper.basicChannel().name,
function(data) {
expect(data.name).toEqual(TestHelper.basicChannel().name);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
});

View File

@@ -1,142 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.Commands', function() {
test('listCommands', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().listCommands(
function(data) {
expect(data.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('listTeamCommands', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().listTeamCommands(
function() {
done.fail(new Error('cmds not enabled'));
},
function(err) {
expect(err.id).toEqual('api.command.disabled.app_error');
done();
}
);
});
});
test('executeCommand', function(done) {
TestHelper.initBasic(done, () => {
const args = {};
args.channel_id = TestHelper.basicChannel().id;
TestHelper.basicClient().executeCommand(
'/shrug',
args,
function(data) {
expect(data.response_type).toEqual('in_channel');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('addCommand', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var cmd = {};
cmd.url = 'http://www.gonowhere.com';
cmd.trigger = '/hello';
cmd.method = 'P';
cmd.username = '';
cmd.icon_url = '';
cmd.auto_complete = false;
cmd.auto_complete_desc = '';
cmd.auto_complete_hint = '';
cmd.display_name = 'Unit Test';
TestHelper.basicClient().addCommand(
cmd,
function() {
done.fail(new Error('cmds not enabled'));
},
function(err) {
expect(err.id).toEqual('api.command.disabled.app_error');
done();
}
);
});
});
test('editCommand', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var cmd = {};
cmd.url = 'http://www.gonowhere.com';
cmd.trigger = '/hello';
cmd.method = 'P';
cmd.username = '';
cmd.icon_url = '';
cmd.auto_complete = false;
cmd.auto_complete_desc = '';
cmd.auto_complete_hint = '';
cmd.display_name = 'Unit Test';
TestHelper.basicClient().editCommand(
cmd,
function() {
done.fail(new Error('cmds not enabled'));
},
function(err) {
expect(err.id).toEqual('api.command.disabled.app_error');
done();
}
);
});
});
test('deleteCommand', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().deleteCommand(
TestHelper.generateId(),
function() {
done.fail(new Error('cmds not enabled'));
},
function(err) {
expect(err.id).toEqual('api.command.disabled.app_error');
done();
}
);
});
});
test('regenCommandToken', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().regenCommandToken(
TestHelper.generateId(),
function() {
done.fail(new Error('cmds not enabled'));
},
function(err) {
expect(err.id).toEqual('api.command.disabled.app_error');
done();
}
);
});
});
});

View File

@@ -1,102 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
const fs = require('fs');
describe('Client.Emoji', function() {
const testGifFileName = 'testEmoji.gif';
beforeAll(function() {
// write a temporary file so that we have something to upload for testing
const buffer = new Buffer('R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=', 'base64');
const testGif = fs.openSync(testGifFileName, 'w+');
fs.writeFileSync(testGif, buffer);
});
afterAll(function() {
fs.unlinkSync(testGifFileName);
});
test('addEmoji', function(done) {
TestHelper.initBasic(done, () => {
const name = TestHelper.generateId();
TestHelper.basicClient().addEmoji(
{creator_id: TestHelper.basicUser().id, name},
fs.createReadStream(testGifFileName),
function(data) {
expect(data.name).toEqual(name);
expect(data.id).not.toBeNull();
//TestHelper.basicClient().deleteEmoji(data.id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('deleteEmoji', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().addEmoji(
{creator_id: TestHelper.basicUser().id, name: TestHelper.generateId()},
fs.createReadStream(testGifFileName),
function(data) {
TestHelper.basicClient().deleteEmoji(
data.id,
function() {
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('listEmoji', function(done) {
TestHelper.initBasic(done, () => {
const name = TestHelper.generateId();
TestHelper.basicClient().addEmoji(
{creator_id: TestHelper.basicUser().id, name},
fs.createReadStream(testGifFileName),
function() {
TestHelper.basicClient().listEmoji(
function(data) {
expect(data.length).toBeGreaterThan(0);
let found = false;
for (const emoji of data) {
if (emoji.name === name) {
found = true;
break;
}
}
if (found) {
done();
} else {
done.fail(new Error('test emoji wasn\'t returned'));
}
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
});

View File

@@ -1,248 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
const fs = require('fs');
describe('Client.File', function() {
const testGifFileName = 'testFile.gif';
beforeAll(function() {
// write a temporary file so that we have something to upload for testing
const buffer = new Buffer('R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=', 'base64');
const testGif = fs.openSync(testGifFileName, 'w+');
fs.writeFileSync(testGif, buffer);
});
afterAll(function() {
fs.unlinkSync(testGifFileName);
});
test('uploadFile', function(done) {
TestHelper.initBasic(done, () => {
const clientId = TestHelper.generateId();
TestHelper.basicClient().uploadFile(
fs.createReadStream(testGifFileName),
testGifFileName,
TestHelper.basicChannel().id,
clientId,
function(resp) {
expect(resp.file_infos.length).toBe(1);
expect(resp.client_ids.length).toBe(1);
expect(resp.client_ids[0]).toEqual(clientId);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getFile', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().uploadFile(
fs.createReadStream(testGifFileName),
testGifFileName,
TestHelper.basicChannel().id,
'',
function(resp) {
TestHelper.basicClient().getFile(
resp.file_infos[0].id,
function() {
done();
},
function(err2) {
done.fail(new Error(err2.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getFileThumbnail', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().uploadFile(
fs.createReadStream(testGifFileName),
testGifFileName,
TestHelper.basicChannel().id,
'',
function(resp) {
TestHelper.basicClient().getFileThumbnail(
resp.file_infos[0].id,
function() {
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getFilePreview', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().uploadFile(
fs.createReadStream(testGifFileName),
testGifFileName,
TestHelper.basicChannel().id,
'',
function(resp) {
TestHelper.basicClient().getFilePreview(
resp.file_infos[0].id,
function() {
done();
},
function(err2) {
done.fail(new Error(err2.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getFileInfo', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().uploadFile(
fs.createReadStream(testGifFileName),
testGifFileName,
TestHelper.basicChannel().id,
'',
function(resp) {
const fileId = resp.file_infos[0].id;
TestHelper.basicClient().getFileInfo(
fileId,
function(info) {
expect(info.id).toEqual(fileId);
expect(info.name).toEqual(testGifFileName);
done();
},
function(err2) {
done.fail(new Error(err2.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getPublicLink', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().uploadFile(
fs.createReadStream(testGifFileName),
testGifFileName,
TestHelper.basicChannel().id,
'',
function(resp) {
const post = TestHelper.fakePost();
post.channel_id = TestHelper.basicChannel().id;
post.file_ids = resp.file_infos.map((info) => info.id);
TestHelper.basicClient().createPost(
post,
function(data) {
expect(data.file_ids).toEqual(post.file_ids);
TestHelper.basicClient().getPublicLink(
post.file_ids[0],
function() {
done.fail(new Error('public links should be disabled by default'));
// request.
// get(link).
// end(TestHelper.basicChannel().handleResponse.bind(
// this,
// 'getPublicLink',
// function() {
// done();
// },
// function(err4) {
// done.fail(new Error(err4.message));
// }
// ));
},
function() {
done();
// done.fail(new Error(err3.message));
}
);
},
function(err2) {
done.fail(new Error(err2.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getFileInfosForPost', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().uploadFile(
fs.createReadStream(testGifFileName),
testGifFileName,
TestHelper.basicChannel().id,
'',
function(resp) {
const post = TestHelper.fakePost();
post.channel_id = TestHelper.basicChannel().id;
post.file_ids = resp.file_infos.map((info) => info.id);
TestHelper.basicClient().createPost(
post,
function(data) {
expect(data.file_ids).toEqual(post.file_ids);
TestHelper.basicClient().getFileInfosForPost(
post.channel_id,
data.id,
function(files) {
expect(files.length).toBe(1);
expect(files[0].id).toEqual(resp.file_infos[0].id);
done();
},
function(err3) {
done.fail(new Error(err3.message));
}
);
},
function(err2) {
done.fail(new Error(err2.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
});

View File

@@ -1,44 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.General', function() {
test('General.getClientConfig', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getClientConfig(
function(data) {
expect(data.SiteName).toEqual('Mattermost');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('General.getPing', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getPing(
function(data) {
expect(data.version.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('General.logClientError', function(done) {
TestHelper.initBasic(done, () => {
var config = {};
config.site_name = 'test';
TestHelper.basicClient().logClientError('this is a test');
done();
});
});
});

View File

@@ -1,173 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.Hooks', function() {
test('addIncomingHook', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var hook = {};
hook.channel_id = TestHelper.basicChannel().id;
hook.description = 'desc';
hook.display_name = 'Unit Test';
TestHelper.basicClient().addIncomingHook(
hook,
function() {
done.fail(new Error('hooks not enabled'));
},
function(err) {
expect(err.id).toBe('api.incoming_webhook.disabled.app_error');
done();
}
);
});
});
test('updateIncomingHook', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var hook = {};
hook.channel_id = TestHelper.basicChannel().id;
hook.description = 'desc';
hook.display_name = 'Unit Test';
TestHelper.basicClient().updateIncomingHook(
hook,
function() {
done.fail(new Error('hooks not enabled'));
},
function(err) {
expect(err.id).toBe('api.incoming_webhook.disabled.app_error');
done();
}
);
});
});
test('deleteIncomingHook', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().deleteIncomingHook(
TestHelper.generateId(),
function() {
done.fail(new Error('hooks not enabled'));
},
function(err) {
expect(err.id).toBe('api.incoming_webhook.disabled.app_error');
done();
}
);
});
});
test('listIncomingHooks', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().listIncomingHooks(
function() {
done.fail(new Error('hooks not enabled'));
},
function(err) {
expect(err.id).toBe('api.incoming_webhook.disabled.app_error');
done();
}
);
});
});
test('addOutgoingHook', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var hook = {};
hook.channel_id = TestHelper.basicChannel().id;
hook.description = 'desc';
hook.display_name = 'Unit Test';
TestHelper.basicClient().addOutgoingHook(
hook,
function() {
done.fail(new Error('hooks not enabled'));
},
function(err) {
expect(err.id).toBe('api.outgoing_webhook.disabled.app_error');
done();
}
);
});
});
test('deleteOutgoingHook', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().deleteOutgoingHook(
TestHelper.generateId(),
function() {
done.fail(new Error('hooks not enabled'));
},
function(err) {
expect(err.id).toBe('api.outgoing_webhook.disabled.app_error');
done();
}
);
});
});
test('listOutgoingHooks', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().listOutgoingHooks(
function() {
done.fail(new Error('hooks not enabled'));
},
function(err) {
expect(err.id).toBe('api.outgoing_webhook.disabled.app_error');
done();
}
);
});
});
test('regenOutgoingHookToken', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().regenOutgoingHookToken(
TestHelper.generateId(),
function() {
done.fail(new Error('hooks not enabled'));
},
function(err) {
expect(err.id).toBe('api.outgoing_webhook.disabled.app_error');
done();
}
);
});
});
test('updateOutgoingHook', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var hook = {};
hook.channel_id = TestHelper.basicChannel().id;
hook.description = 'desc';
hook.display_name = 'Unit Test';
TestHelper.basicClient().updateOutgoingHook(
hook,
function() {
done.fail(new Error('hooks not enabled'));
},
function(err) {
expect(err.id).toBe('api.outgoing_webhook.disabled.app_error');
done();
}
);
});
});
});

View File

@@ -1,50 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.OAuth', function() {
test('registerOAuthApp', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var app = {};
app.name = 'test';
app.homepage = 'homepage';
app.description = 'desc';
app.callback_urls = [''];
TestHelper.basicClient().registerOAuthApp(
app,
function() {
done.fail(new Error('not enabled'));
},
function(err) {
expect(err.id).toBe('api.oauth.register_oauth_app.turn_off.app_error');
done();
}
);
});
});
test('allowOAuth2', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().allowOAuth2(
'GET',
'12345678901234567890123456',
'http://nowhere.com',
'state',
'scope',
function() {
done.fail(new Error('not enabled'));
},
function(err) {
expect(err.id).toBe('api.oauth.allow_oauth.turn_off.app_error');
done();
}
);
});
});
});

View File

@@ -1,233 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.Posts', function() {
test('createPost', function(done) {
TestHelper.initBasic(done, () => {
var post = TestHelper.fakePost();
post.channel_id = TestHelper.basicChannel().id;
TestHelper.basicClient().createPost(
post,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getPostById', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getPostById(
TestHelper.basicPost().id,
function(data) {
expect(data.order[0]).toEqual(TestHelper.basicPost().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getPost', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getPost(
TestHelper.basicChannel().id,
TestHelper.basicPost().id,
function(data) {
expect(data.order[0]).toEqual(TestHelper.basicPost().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updatePost', function(done) {
TestHelper.initBasic(done, () => {
var post = TestHelper.basicPost();
post.message = 'new message';
post.channel_id = TestHelper.basicChannel().id;
TestHelper.basicClient().updatePost(
post,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('deletePost', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().deletePost(
TestHelper.basicChannel().id,
TestHelper.basicPost().id,
function(data) {
expect(data.id).toEqual(TestHelper.basicPost().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('searchPost', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().search(
'unit test',
false,
function(data) {
expect(data.order[0]).toEqual(TestHelper.basicPost().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getPostsPage', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getPostsPage(
TestHelper.basicChannel().id,
0,
10,
function(data) {
expect(data.order[0]).toEqual(TestHelper.basicPost().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getPosts', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getPosts(
TestHelper.basicChannel().id,
0,
function(data) {
expect(data.order[0]).toEqual(TestHelper.basicPost().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getPostsBefore', function(done) {
TestHelper.initBasic(done, () => {
var post = TestHelper.fakePost();
post.channel_id = TestHelper.basicChannel().id;
TestHelper.basicClient().createPost(
post,
function(rpost) {
TestHelper.basicClient().getPostsBefore(
TestHelper.basicChannel().id,
rpost.id,
0,
10,
function(data) {
expect(data.order[0]).toEqual(TestHelper.basicPost().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getPostsAfter', function(done) {
TestHelper.initBasic(done, () => {
var post = TestHelper.fakePost();
post.channel_id = TestHelper.basicChannel().id;
TestHelper.basicClient().createPost(
post,
function(rpost) {
TestHelper.basicClient().getPostsAfter(
TestHelper.basicChannel().id,
TestHelper.basicPost().id,
0,
10,
function(data) {
expect(data.order[0]).toEqual(rpost.id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getFlaggedPosts', function(done) {
TestHelper.initBasic(done, () => {
var pref = {};
pref.user_id = TestHelper.basicUser().id;
pref.category = 'flagged_post';
pref.name = TestHelper.basicPost().id;
pref.value = 'true';
var prefs = [];
prefs.push(pref);
TestHelper.basicClient().savePreferences(
prefs,
function() {
TestHelper.basicClient().getFlaggedPosts(
0,
2,
function(data) {
expect(data.order[0]).toEqual(TestHelper.basicPost().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
// getFileInfosForPost is tested in client_files.test.jsx
});

View File

@@ -1,62 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.Preferences', function() {
test('getAllPreferences', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getAllPreferences(
function(data) {
expect(data[0].category).toBe('tutorial_step');
expect(data[0].user_id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('savePreferences', function(done) {
TestHelper.initBasic(done, () => {
var perf = {};
perf.user_id = TestHelper.basicUser().id;
perf.category = 'test';
perf.name = 'name';
perf.value = 'value';
var perfs = [];
perfs.push(perf);
TestHelper.basicClient().savePreferences(
perfs,
function(data) {
expect(data).toBe(true);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getPreferenceCategory', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getPreferenceCategory(
'tutorial_step',
function(data) {
expect(data[0].category).toBe('tutorial_step');
expect(data[0].user_id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
});

View File

@@ -1,79 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.Reaction', function() {
test('saveListReaction', function(done) {
TestHelper.initBasic(done, () => {
const channelId = TestHelper.basicChannel().id;
const postId = TestHelper.basicPost().id;
const reaction = {
post_id: postId,
user_id: TestHelper.basicUser().id,
emoji_name: 'upside_down_face'
};
TestHelper.basicClient().saveReaction(
channelId,
reaction,
function() {
TestHelper.basicClient().listReactions(
channelId,
postId,
function(reactions) {
if (reactions.length === 1 &&
reactions[0].post_id === reaction.post_id &&
reactions[0].user_id === reaction.user_id &&
reactions[0].emoji_name === reaction.emoji_name) {
done();
} else {
done.fail(new Error('test reaction wasn\'t returned'));
}
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('deleteReaction', function(done) {
TestHelper.initBasic(done, () => {
const channelId = TestHelper.basicChannel().id;
const postId = TestHelper.basicPost().id;
const reaction = {
post_id: postId,
user_id: TestHelper.basicUser().id,
emoji_name: 'upside_down_face'
};
TestHelper.basicClient().saveReaction(
channelId,
reaction,
function() {
TestHelper.basicClient().deleteReaction(
channelId,
reaction,
function() {
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
});

View File

@@ -1,309 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.Team', function() {
test('findTeamByName', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().findTeamByName(
TestHelper.basicTeam().name,
function(data) {
expect(data).toBe(true);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('createTeam', function(done) {
var team = TestHelper.fakeTeam();
TestHelper.initBasic(done, () => {
TestHelper.basicClient().createTeam(
team,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
expect(data.name).toEqual(team.name);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getAllTeams', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getAllTeams(
function(data) {
expect(data[TestHelper.basicTeam().id].name).toEqual(TestHelper.basicTeam().name);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getAllTeamListings', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getAllTeamListings(
function(data) {
expect(data).not.toBeNull();
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getMyTeam', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getMyTeam(
function(data) {
expect(data.name).toEqual(TestHelper.basicTeam().name);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getMyTeamMembers', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getMyTeamMembers(
function(data) {
expect(data.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getTeamMembers', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getTeamMembers(
TestHelper.basicTeam().id,
0,
100,
function(data) {
expect(data.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getTeamMember', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getTeamMember(
TestHelper.basicTeam().id,
TestHelper.basicUser().id,
function(data) {
expect(data.user_id).toEqual(TestHelper.basicUser().id);
expect(data.team_id).toEqual(TestHelper.basicTeam().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getTeamStats', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getTeamStats(
TestHelper.basicTeam().id,
function(data) {
expect(data.total_member_count).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getTeamMembersByIds', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getTeamMembersByIds(
TestHelper.basicTeam().id,
[TestHelper.basicUser().id],
function(data) {
expect(data[0].user_id).toEqual(TestHelper.basicUser().id);
expect(data[0].team_id).toEqual(TestHelper.basicTeam().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('inviteMembers', function(done) {
TestHelper.initBasic(done, () => {
var data = {};
data.invites = [];
var invite = {};
invite.email = TestHelper.fakeEmail();
invite.firstName = 'first';
invite.lastName = 'last';
data.invites.push(invite);
TestHelper.basicClient().inviteMembers(
data,
function(dataBack) {
expect(dataBack.invites.length).toBe(1);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateTeam', function(done) {
TestHelper.initBasic(done, () => {
var team = TestHelper.basicTeam();
team.display_name = 'test_updated';
TestHelper.basicClient().updateTeam(
team,
function(data) {
expect(data.display_name).toBe('test_updated');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateTeamDescription', function(done) {
TestHelper.initBasic(done, () => {
var team = TestHelper.basicTeam();
team.description = 'test_updated';
TestHelper.basicClient().updateTeam(
team,
function(data) {
expect(data.description).toBe('test_updated');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('addUserToTeam', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().createUser(
TestHelper.fakeUser(),
function(user2) {
TestHelper.basicClient().addUserToTeam(
'',
user2.id,
function(data) {
expect(data.user_id).toEqual(user2.id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('removeUserFromTeam', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().removeUserFromTeam(
'',
TestHelper.basicUser().id,
function(data) {
expect(data.user_id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getInviteInfo', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getInviteInfo(
TestHelper.basicTeam().invite_id,
function(data) {
expect(data.display_name.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateTeamMemberRoles', function(done) {
TestHelper.initBasic(done, () => {
var user = TestHelper.basicUser();
var team = TestHelper.basicTeam();
TestHelper.basicClient().updateTeamMemberRoles(
team.id,
user.id,
'',
function() {
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getTeamByName', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getTeamByName(
TestHelper.basicTeam().name,
function(data) {
expect(data.name).toEqual(TestHelper.basicTeam().name);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
});

View File

@@ -1,700 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe('Client.User', function() {
test('getMe', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getMe(
function(data) {
expect(data.id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getUser', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getUser(
TestHelper.basicUser().id,
function(data) {
expect(data.id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getByUsername', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getByUsername(
TestHelper.basicUser().username,
function(data) {
expect(data.username).toEqual(TestHelper.basicUser().username);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getByEmail', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getByEmail(
TestHelper.basicUser().email,
function(data) {
expect(data.email).toEqual(TestHelper.basicUser().email);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getInitialLoad', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getInitialLoad(
function(data) {
expect(data.user.id.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('createUser', function(done) {
var client = TestHelper.createClient();
var user = TestHelper.fakeUser();
client.createUser(
user,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
expect(data.email).toEqual(user.email);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
test('loginByEmail', function(done) {
var client = TestHelper.createClient();
var user = TestHelper.fakeUser();
client.createUser(
user,
function() {
client.login(
user.email,
user.password,
null,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
expect(data.email).toEqual(user.email);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
test('loginById', function(done) {
var client = TestHelper.createClient();
var user = TestHelper.fakeUser();
client.createUser(
user,
function(newUser) {
expect(user.email).toEqual(newUser.email);
client.loginById(
newUser.id,
user.password,
null,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
expect(data.email).toEqual(user.email);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
test('loginByUsername', function(done) {
var client = TestHelper.createClient();
var user = TestHelper.fakeUser();
client.createUser(
user,
function() {
client.login(
user.username,
user.password,
null,
function(data) {
expect(data.id.length).toBeGreaterThan(0);
expect(data.email).toEqual(user.email);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
test('updateUser', function(done) {
TestHelper.initBasic(done, () => {
var user = TestHelper.basicUser();
user.nickname = 'updated';
TestHelper.basicClient().updateUser(
user, null,
function(data) {
expect(data.nickname).toBe('updated');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updatePassword', function(done) {
TestHelper.initBasic(done, () => {
var user = TestHelper.basicUser();
TestHelper.basicClient().updatePassword(
user.id,
user.password,
'update_password',
function(data) {
expect(data.user_id).toEqual(user.id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateUserNotifyProps', function(done) {
TestHelper.initBasic(done, () => {
var user = TestHelper.basicUser();
var notifyProps = {
all: 'true',
channel: 'true',
desktop: 'all',
desktop_sound: 'true',
email: 'false',
first_name: 'false',
mention_keys: '',
comments: 'any',
user_id: user.id
};
TestHelper.basicClient().updateUserNotifyProps(
notifyProps,
function(data) {
expect(data.notify_props.email).toBe('false');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateUserRoles', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var user = TestHelper.basicUser();
TestHelper.basicClient().updateUserRoles(
user.id,
'',
function() {
done.fail(new Error('Not supposed to work'));
},
function() {
done();
}
);
});
});
test('updateActive', function(done) {
TestHelper.initBasic(done, () => {
const user = TestHelper.basicUser();
TestHelper.basicClient().updateActive(
user.id,
false,
function(data) {
expect(data.delete_at).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('sendPasswordReset', function(done) {
TestHelper.initBasic(done, () => {
var user = TestHelper.basicUser();
TestHelper.basicClient().sendPasswordReset(
user.email,
function(data) {
expect(data.email).toEqual(user.email);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('resetPassword', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().resetPassword(
'',
'new_password',
function() {
throw Error('shouldnt work');
},
function(err) {
// this should fail since you're not a system admin
expect(err.id).toBe('api.context.invalid_param.app_error');
done();
}
);
});
});
test('emailToOAuth', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var user = TestHelper.basicUser();
TestHelper.basicClient().emailToOAuth(
user.email,
'new_password',
'',
'gitlab',
function() {
throw Error('shouldnt work');
},
function(err) {
// this should fail since you're not a system admin
expect(err.id).toBe('api.user.check_user_password.invalid.app_error');
done();
}
);
});
});
test('oauthToEmail', function(done) {
TestHelper.initBasic(done, () => {
var user = TestHelper.basicUser();
TestHelper.basicClient().oauthToEmail(
user.email,
'new_password',
function(data) {
expect(data.follow_link.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('emailToLdap', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var user = TestHelper.basicUser();
TestHelper.basicClient().emailToLdap(
user.email,
user.password,
'',
'unknown_id',
'unknown_pwd',
function() {
throw Error('shouldnt work');
},
function() {
done();
}
);
});
});
test('ldapToEmail', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var user = TestHelper.basicUser();
TestHelper.basicClient().ldapToEmail(
user.email,
'new_password',
'',
'new_password',
function() {
throw Error('shouldnt work');
},
function(err) {
expect(err.id).toBe('api.user.ldap_to_email.not_ldap_account.app_error');
done();
}
);
});
});
test('logout', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().logout(
function(data) {
expect(data.user_id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('checkMfa', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().checkMfa(
TestHelper.generateId(),
function(data) {
expect(data.mfa_required).toBe('false');
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('generateMfaSecret', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().generateMfaSecret(
function() {
done.fail(new Error('not enabled'));
},
function() {
done();
}
);
});
});
test('getSessions', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getSessions(
TestHelper.basicUser().id,
function(data) {
expect(data[0].user_id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('revokeSession', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getSessions(
TestHelper.basicUser().id,
function(sessions) {
TestHelper.basicClient().revokeSession(
sessions[0].id,
function(data) {
expect(data.id).toEqual(sessions[0].id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getAudits', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getAudits(
TestHelper.basicUser().id,
function(data) {
expect(data[0].user_id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getProfiles', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getProfiles(
0,
100,
function(data) {
expect(Object.keys(data).length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getProfilesInTeam', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getProfilesInTeam(
TestHelper.basicTeam().id,
0,
100,
function(data) {
expect(data[TestHelper.basicUser().id].id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getProfilesByIds', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getProfilesByIds(
[TestHelper.basicUser().id],
function(data) {
expect(data[TestHelper.basicUser().id].id).toEqual(TestHelper.basicUser().id);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getProfilesInChannel', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getProfilesInChannel(
TestHelper.basicChannel().id,
0,
100,
function(data) {
expect(Object.keys(data).length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getProfilesNotInChannel', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().getProfilesNotInChannel(
TestHelper.basicChannel().id,
0,
100,
function(data) {
expect(Object.keys(data).length).not.toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('searchUsers', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().searchUsers(
'uid',
TestHelper.basicTeam().id,
{},
function(data) {
expect(data.length).toBeGreaterThan(0);
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('autocompleteUsersInChannel', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().autocompleteUsersInChannel(
'uid',
TestHelper.basicChannel().id,
function(data) {
expect(data).not.toBeNull();
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('autocompleteUsersInTeam', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().autocompleteUsersInTeam(
'uid',
function(data) {
expect(data).not.toBeNull();
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('autocompleteUsers', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().autocompleteUsers(
'uid',
function(data) {
expect(data).not.toBeNull();
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('getStatusesByIds', function(done) {
TestHelper.initBasic(done, () => {
var ids = [];
ids.push(TestHelper.basicUser().id);
TestHelper.basicClient().getStatusesByIds(
ids,
function(data) {
expect(data[TestHelper.basicUser().id]).not.toBeNull();
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('verifyEmail', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().verifyEmail(
'junk',
function() {
done.fail(new Error('should be invalid'));
},
function(err) {
expect(err.id).toBe('api.context.invalid_body_param.app_error');
done();
}
);
});
});
test('resendVerification', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().resendVerification(
TestHelper.basicUser().email,
function() {
done();
},
function(err) {
done.fail(new Error(err.message));
}
);
});
});
test('updateMfa', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
TestHelper.basicClient().updateMfa(
'junk',
true,
function() {
done.fail(new Error('not enabled'));
},
function() {
done();
}
);
});
});
});

View File

@@ -1,46 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import TestHelper from 'tests/helpers/client-test-helper.jsx';
describe.skip('Client.WebSocket', function() {
test('WebSocket.getStatusesByIds', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicWebSocketClient().getStatusesByIds(
[TestHelper.basicUser().id],
function(resp) {
TestHelper.basicWebSocketClient().close();
expect(resp.data[TestHelper.basicUser().id]).toBe('online');
done();
}
);
}, true);
});
test('WebSocket.getStatuses', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicWebSocketClient().getStatuses(
function(resp) {
TestHelper.basicWebSocketClient().close();
expect(resp.data).not.toBe(null);
done();
}
);
}, true);
});
test('WebSocket.userTyping', function(done) {
TestHelper.initBasic(done, () => {
TestHelper.basicWebSocketClient().userTyping(
TestHelper.basicChannel().id,
'',
function(resp) {
TestHelper.basicWebSocketClient().close();
expect(resp.status).toBe('OK');
done();
}
);
}, true);
});
});

View File

@@ -1,889 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import UserStore from 'stores/user_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import Client from 'client/web_client.jsx';
import * as utils from 'utils/utils.jsx';
import * as UserAgent from 'utils/user_agent.jsx';
import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
const StatTypes = Constants.StatTypes;
// Used to track in progress async calls
const callTracker = {};
const ASYNC_CLIENT_TIMEOUT = 5000;
// Redux actions
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {setServerVersion} from 'mattermost-redux/actions/general';
export function dispatchError(err, method) {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_ERROR,
err,
method
});
}
function isCallInProgress(callName) {
if (!(callName in callTracker)) {
return false;
}
if (callTracker[callName] === 0) {
return false;
}
if (utils.getTimestamp() - callTracker[callName] > ASYNC_CLIENT_TIMEOUT) {
//console.log('AsyncClient call ' + callName + ' expired after more than 5 seconds');
return false;
}
return true;
}
export function checkVersion() {
setServerVersion(Client.getServerVersion())(dispatch, getState);
}
export function getUser(userId, success, error) {
const callName = `getUser${userId}`;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.getUser(
userId,
(data) => {
callTracker[callName] = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_PROFILE,
profile: data
});
if (success) {
success(data);
}
},
(err) => {
if (error) {
error(err);
} else {
callTracker[callName] = 0;
dispatchError(err, 'getUser');
}
}
);
}
export function getLogs() {
if (isCallInProgress('getLogs')) {
return;
}
callTracker.getLogs = utils.getTimestamp();
Client.getLogs(
(data) => {
callTracker.getLogs = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_LOGS,
logs: data
});
},
(err) => {
callTracker.getLogs = 0;
dispatchError(err, 'getLogs');
}
);
}
export function getServerAudits() {
if (isCallInProgress('getServerAudits')) {
return;
}
callTracker.getServerAudits = utils.getTimestamp();
Client.getServerAudits(
(data) => {
callTracker.getServerAudits = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_SERVER_AUDITS,
audits: data
});
},
(err) => {
callTracker.getServerAudits = 0;
dispatchError(err, 'getServerAudits');
}
);
}
export function getComplianceReports() {
if (isCallInProgress('getComplianceReports')) {
return;
}
callTracker.getComplianceReports = utils.getTimestamp();
Client.getComplianceReports(
(data) => {
callTracker.getComplianceReports = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_SERVER_COMPLIANCE_REPORTS,
complianceReports: data
});
},
(err) => {
callTracker.getComplianceReports = 0;
dispatchError(err, 'getComplianceReports');
}
);
}
export function getConfig(success, error) {
if (isCallInProgress('getConfig')) {
return;
}
callTracker.getConfig = utils.getTimestamp();
Client.getConfig(
(data) => {
callTracker.getConfig = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_CONFIG,
config: data,
clusterId: Client.clusterId
});
if (success) {
success(data);
}
},
(err) => {
callTracker.getConfig = 0;
if (!error) {
dispatchError(err, 'getConfig');
}
}
);
}
export function search(terms, isOrSearch) {
if (isCallInProgress('search_' + String(terms))) {
return;
}
callTracker['search_' + String(terms)] = utils.getTimestamp();
Client.search(
terms,
isOrSearch,
(data) => {
callTracker['search_' + String(terms)] = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_SEARCH,
results: data
});
},
(err) => {
callTracker['search_' + String(terms)] = 0;
dispatchError(err, 'search');
}
);
}
export function getFileInfosForPost(channelId, postId) {
const callName = 'getFileInfosForPost' + postId;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.getFileInfosForPost(
channelId,
postId,
(data) => {
callTracker[callName] = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_FILE_INFOS,
postId,
infos: data
});
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'getPostFile');
}
);
}
export function getMe() {
if (isCallInProgress('getMe')) {
return null;
}
callTracker.getMe = utils.getTimestamp();
return Client.getMe(
(data) => {
callTracker.getMe = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_ME,
me: data
});
GlobalActions.newLocalizationSelected(data.locale);
},
(err) => {
callTracker.getMe = 0;
dispatchError(err, 'getMe');
}
);
}
export function getStatuses() {
if (isCallInProgress('getStatuses')) {
return;
}
callTracker.getStatuses = utils.getTimestamp();
Client.getStatuses(
(data) => {
callTracker.getStatuses = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_STATUSES,
statuses: data
});
},
(err) => {
callTracker.getStatuses = 0;
dispatchError(err, 'getStatuses');
}
);
}
export function getMyTeamsUnread(teamId) {
const members = TeamStore.getMyTeamMembers();
if (members.length > 1) {
const callName = 'getMyTeamsUnread';
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.getMyTeamsUnread(
teamId,
(data) => {
callTracker[callName] = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_MY_TEAMS_UNREAD,
team_members: data
});
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'getMyTeamsUnread');
}
);
}
}
export function getAllPreferences() {
if (isCallInProgress('getAllPreferences')) {
return;
}
callTracker.getAllPreferences = utils.getTimestamp();
Client.getAllPreferences(
(data) => {
callTracker.getAllPreferences = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_PREFERENCES,
preferences: data
});
},
(err) => {
callTracker.getAllPreferences = 0;
dispatchError(err, 'getAllPreferences');
}
);
}
export function savePreference(category, name, value, success, error) {
const preference = {
user_id: UserStore.getCurrentId(),
category,
name,
value
};
savePreferences([preference], success, error);
}
export function savePreferences(preferences, success, error) {
Client.savePreferences(
preferences,
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_PREFERENCES,
preferences
});
if (success) {
success(data);
}
},
(err) => {
dispatchError(err, 'savePreferences');
if (error) {
error();
}
}
);
}
export function deletePreferences(preferences, success, error) {
Client.deletePreferences(
preferences,
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.DELETED_PREFERENCES,
preferences
});
if (success) {
success(data);
}
},
(err) => {
dispatchError(err, 'deletePreferences');
if (error) {
error();
}
}
);
}
export function getSuggestedCommands(command, suggestionId, component) {
Client.listCommands(
(data) => {
var matches = [];
data.forEach((cmd) => {
if (cmd.trigger !== 'shortcuts' || !UserAgent.isMobile()) {
if (('/' + cmd.trigger).indexOf(command) === 0) {
const s = '/' + cmd.trigger;
let hint = '';
if (cmd.auto_complete_hint && cmd.auto_complete_hint.length !== 0) {
hint = cmd.auto_complete_hint;
}
matches.push({
suggestion: s,
hint,
description: cmd.auto_complete_desc
});
}
}
});
matches = matches.sort((a, b) => a.suggestion.localeCompare(b.suggestion));
// pull out the suggested commands from the returned data
const terms = matches.map((suggestion) => suggestion.suggestion);
if (terms.length > 0) {
AppDispatcher.handleServerAction({
type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS,
id: suggestionId,
matchedPretext: command,
terms,
items: matches,
component
});
}
},
(err) => {
dispatchError(err, 'getSuggestedCommands');
}
);
}
export function getStandardAnalytics(teamId) {
const callName = 'getStandardAnaytics' + teamId;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.getAnalytics(
'standard',
teamId,
(data) => {
callTracker[callName] = 0;
const stats = {};
for (const index in data) {
if (data[index].name === 'channel_open_count') {
stats[StatTypes.TOTAL_PUBLIC_CHANNELS] = data[index].value;
}
if (data[index].name === 'channel_private_count') {
stats[StatTypes.TOTAL_PRIVATE_GROUPS] = data[index].value;
}
if (data[index].name === 'post_count') {
stats[StatTypes.TOTAL_POSTS] = data[index].value;
}
if (data[index].name === 'unique_user_count') {
stats[StatTypes.TOTAL_USERS] = data[index].value;
}
if (data[index].name === 'team_count' && teamId == null) {
stats[StatTypes.TOTAL_TEAMS] = data[index].value;
}
if (data[index].name === 'total_websocket_connections') {
stats[StatTypes.TOTAL_WEBSOCKET_CONNECTIONS] = data[index].value;
}
if (data[index].name === 'total_master_db_connections') {
stats[StatTypes.TOTAL_MASTER_DB_CONNECTIONS] = data[index].value;
}
if (data[index].name === 'total_read_db_connections') {
stats[StatTypes.TOTAL_READ_DB_CONNECTIONS] = data[index].value;
}
if (data[index].name === 'daily_active_users') {
stats[StatTypes.DAILY_ACTIVE_USERS] = data[index].value;
}
if (data[index].name === 'monthly_active_users') {
stats[StatTypes.MONTHLY_ACTIVE_USERS] = data[index].value;
}
}
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_ANALYTICS,
teamId,
stats
});
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'getStandardAnalytics');
}
);
}
export function getAdvancedAnalytics(teamId) {
const callName = 'getAdvancedAnalytics' + teamId;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.getAnalytics(
'extra_counts',
teamId,
(data) => {
callTracker[callName] = 0;
const stats = {};
for (const index in data) {
if (data[index].name === 'file_post_count') {
stats[StatTypes.TOTAL_FILE_POSTS] = data[index].value;
}
if (data[index].name === 'hashtag_post_count') {
stats[StatTypes.TOTAL_HASHTAG_POSTS] = data[index].value;
}
if (data[index].name === 'incoming_webhook_count') {
stats[StatTypes.TOTAL_IHOOKS] = data[index].value;
}
if (data[index].name === 'outgoing_webhook_count') {
stats[StatTypes.TOTAL_OHOOKS] = data[index].value;
}
if (data[index].name === 'command_count') {
stats[StatTypes.TOTAL_COMMANDS] = data[index].value;
}
if (data[index].name === 'session_count') {
stats[StatTypes.TOTAL_SESSIONS] = data[index].value;
}
}
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_ANALYTICS,
teamId,
stats
});
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'getAdvancedAnalytics');
}
);
}
export function getPostsPerDayAnalytics(teamId) {
const callName = 'getPostsPerDayAnalytics' + teamId;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.getAnalytics(
'post_counts_day',
teamId,
(data) => {
callTracker[callName] = 0;
data.reverse();
const stats = {};
stats[StatTypes.POST_PER_DAY] = data;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_ANALYTICS,
teamId,
stats
});
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'getPostsPerDayAnalytics');
}
);
}
export function getUsersPerDayAnalytics(teamId) {
const callName = 'getUsersPerDayAnalytics' + teamId;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.getAnalytics(
'user_counts_with_posts_day',
teamId,
(data) => {
callTracker[callName] = 0;
data.reverse();
const stats = {};
stats[StatTypes.USERS_WITH_POSTS_PER_DAY] = data;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_ANALYTICS,
teamId,
stats
});
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'getUsersPerDayAnalytics');
}
);
}
export function getRecentAndNewUsersAnalytics(teamId) {
const callName = 'getRecentAndNewUsersAnalytics' + teamId;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.getRecentlyActiveUsers(
teamId,
(users) => {
const stats = {};
const usersList = [];
for (const id in users) {
if (users.hasOwnProperty(id)) {
usersList.push(users[id]);
}
}
usersList.sort((a, b) => {
if (a.last_activity_at < b.last_activity_at) {
return 1;
}
if (a.last_activity_at > b.last_activity_at) {
return -1;
}
return 0;
});
const recentActive = [];
for (let i = 0; i < usersList.length; i++) {
if (usersList[i].last_activity_at == null) {
continue;
}
recentActive.push(usersList[i]);
if (i >= Constants.STAT_MAX_ACTIVE_USERS) {
break;
}
}
stats[StatTypes.RECENTLY_ACTIVE_USERS] = recentActive;
usersList.sort((a, b) => {
if (a.create_at < b.create_at) {
return 1;
}
if (a.create_at > b.create_at) {
return -1;
}
return 0;
});
var newlyCreated = [];
for (let i = 0; i < usersList.length; i++) {
newlyCreated.push(usersList[i]);
if (i >= Constants.STAT_MAX_NEW_USERS) {
break;
}
}
stats[StatTypes.NEWLY_CREATED_USERS] = newlyCreated;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_ANALYTICS,
teamId,
stats
});
callTracker[callName] = 0;
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'getRecentAndNewUsersAnalytics');
}
);
}
export function getPublicLink(fileId, success, error) {
const callName = 'getPublicLink' + fileId;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.getPublicLink(
fileId,
(link) => {
callTracker[callName] = 0;
success(link);
},
(err) => {
callTracker[callName] = 0;
if (error) {
error(err);
} else {
dispatchError(err, 'getPublicLink');
}
}
);
}
export function addEmoji(emoji, image, success, error) {
const callName = 'addEmoji' + emoji.name;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.addEmoji(
emoji,
image,
(data) => {
callTracker[callName] = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_CUSTOM_EMOJI,
emoji: data
});
if (success) {
success();
}
},
(err) => {
callTracker[callName] = 0;
if (error) {
error(err);
} else {
dispatchError(err, 'addEmoji');
}
}
);
}
export function deleteEmoji(id) {
const callName = 'deleteEmoji' + id;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.deleteEmoji(
id,
() => {
callTracker[callName] = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.REMOVED_CUSTOM_EMOJI,
id
});
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'deleteEmoji');
}
);
}
export function pinPost(channelId, reaction) {
Client.pinPost(
channelId,
reaction,
() => {
// the "post_edited" websocket event take cares of updating the posts
// the action below is mostly dispatched for the RHS to update
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_POST_PINNED,
reaction
});
},
(err) => {
dispatchError(err, 'pinPost');
}
);
}
export function unpinPost(channelId, reaction) {
Client.unpinPost(
channelId,
reaction,
() => {
// the "post_edited" websocket event take cares of updating the posts
// the action below is mostly dispatched for the RHS to update
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_POST_UNPINNED,
reaction
});
},
(err) => {
dispatchError(err, 'unpinPost');
}
);
}
export function saveReaction(channelId, reaction) {
Client.saveReaction(
channelId,
reaction,
null, // the added reaction will be sent over the websocket
(err) => {
dispatchError(err, 'saveReaction');
}
);
}
export function deleteReaction(channelId, reaction) {
Client.deleteReaction(
channelId,
reaction,
null, // the removed reaction will be sent over the websocket
(err) => {
dispatchError(err, 'deleteReaction');
}
);
}
export function listReactions(channelId, postId) {
const callName = 'deleteEmoji' + postId;
if (isCallInProgress(callName)) {
return;
}
callTracker[callName] = utils.getTimestamp();
Client.listReactions(
channelId,
postId,
(data) => {
callTracker[callName] = 0;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_REACTIONS,
postId,
reactions: data
});
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'listReactions');
}
);
}

View File

@@ -11,9 +11,10 @@ import UserStore from 'stores/user_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import Constants from 'utils/constants.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import Client from 'client/web_client.jsx';
import ProfilePicture from 'components/profile_picture.jsx';
import {Client4} from 'mattermost-redux/client';
import {showManagementOptions} from './channel_utils.jsx';
import React from 'react';
@@ -51,7 +52,7 @@ export function createGMIntroMessage(channel, centeredIntro) {
pictures.push(
<ProfilePicture
key={'introprofilepicture' + profile.id}
src={Client.getUsersRoute() + '/' + profile.id + '/image?time=' + profile.last_picture_update}
src={Client4.getUsersRoute() + '/' + profile.id + '/image?time=' + profile.last_picture_update}
width='50'
height='50'
user={profile}
@@ -111,7 +112,7 @@ export function createDMIntroMessage(channel, centeredIntro) {
<div className={'channel-intro ' + centeredIntro}>
<div className='post-profile-img__container channel-intro-img'>
<ProfilePicture
src={Client.getUsersRoute() + '/' + teammate.id + '/image?time=' + teammate.last_picture_update}
src={Client4.getUsersRoute() + '/' + teammate.id + '/image?time=' + teammate.last_picture_update}
width='50'
height='50'
user={teammate}

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import Client from 'client/web_client.jsx';
import {Client4} from 'mattermost-redux/client';
import Constants from 'utils/constants.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -33,7 +33,7 @@ export function isEdited(post) {
}
export function getProfilePicSrcForPost(post, timestamp) {
let src = Client.getUsersRoute() + '/' + post.user_id + '/image?time=' + timestamp;
let src = Client4.getUsersRoute() + '/' + post.user_id + '/image?time=' + timestamp;
if (post.props && post.props.from_webhook && global.window.mm_config.EnablePostIconOverride === 'true') {
if (post.props.override_icon_url) {
src = post.props.override_icon_url;

View File

@@ -10,9 +10,9 @@ import PreferenceStore from 'stores/preference_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import Constants from 'utils/constants.jsx';
var ActionTypes = Constants.ActionTypes;
import Client from 'client/web_client.jsx';
import * as UserAgent from 'utils/user_agent.jsx';
import {Posts} from 'mattermost-redux/constants';
import {Client4} from 'mattermost-redux/client';
import {browserHistory} from 'react-router/es6';
import {FormattedMessage} from 'react-intl';
@@ -1116,12 +1116,7 @@ export function isDirectChannelForUser(otherUserId, channel) {
}
export function importSlack(file, success, error) {
var formData = new FormData();
formData.append('file', file, file.name);
formData.append('filesize', file.size);
formData.append('importFrom', 'slack');
Client.importSlack(formData, success, error);
Client4.importTeam(file, 'slack').then(success).catch(error);
}
export function windowWidth() {

View File

@@ -5043,7 +5043,7 @@ math-expression-evaluator@^1.2.14:
mattermost-redux@mattermost/mattermost-redux#webapp-master:
version "0.0.1"
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/de4fb87089a0cfb68af04ac0b16cc96481710d88"
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/0b619e5bef097ac0440f0dd9121f3a82eb6a8e70"
dependencies:
deep-equal "1.0.1"
harmony-reflect "1.5.1"