Refactor rest client class to use mixin and a bit of cleanup (#5318)
This commit is contained in:
parent
154b2e6adb
commit
13eab98143
161 changed files with 2261 additions and 7960 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {ActionFunc} from '@mm-redux/types/actions';
|
||||
import {AppCallResponse, AppForm, AppCallRequest, AppCallType} from '@mm-redux/types/apps';
|
||||
import {AppCallTypes, AppCallResponseTypes} from '@mm-redux/constants/apps';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/* eslint-disable no-import-assign */
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import {Preferences} from '@mm-redux/constants';
|
||||
import {PreferenceTypes} from '@mm-redux/action_types';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import {ChannelTypes, PreferenceTypes, RoleTypes, UserTypes} from '@mm-redux/action_types';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General, Preferences} from '@mm-redux/constants';
|
||||
import {getCurrentChannelId, getRedirectChannelNameForTeam, getChannelsNameMapInTeam} from '@mm-redux/selectors/entities/channels';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import {
|
|||
import {savePreferences} from '@mm-redux/actions/preferences';
|
||||
import {getLicense} from '@mm-redux/selectors/entities/general';
|
||||
import {addUserToTeam, getTeamByName, removeUserFromTeam, selectTeam} from '@mm-redux/actions/teams';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General, Preferences} from '@mm-redux/constants';
|
||||
import {getPostIdsInChannel} from '@mm-redux/selectors/entities/posts';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {batchActions} from 'redux-batched-actions';
|
|||
|
||||
import {EmojiTypes} from '@mm-redux/action_types';
|
||||
import {addReaction as serviceAddReaction, getNeededCustomEmojis} from '@mm-redux/actions/posts';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {getPostIdsInCurrentChannel, makeGetPostIdsForThread} from '@mm-redux/selectors/entities/posts';
|
||||
|
||||
import {ViewTypes} from 'app/constants';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {getDataRetentionPolicy} from '@mm-redux/actions/general';
|
|||
import {GeneralTypes} from '@mm-redux/action_types';
|
||||
import {getSessions} from '@mm-redux/actions/users';
|
||||
import {autoUpdateTimezone} from '@mm-redux/actions/timezone';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {getConfig, getLicense} from '@mm-redux/selectors/entities/general';
|
||||
import {isTimezoneEnabled} from '@mm-redux/selectors/entities/timezone';
|
||||
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import configureStore from 'redux-mock-store';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import {handleSuccessfulLogin} from 'app/actions/views/login';
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import {
|
|||
receivedPostsSince,
|
||||
receivedPostsInThread,
|
||||
} from '@mm-redux/actions/posts';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {Posts} from '@mm-redux/constants';
|
||||
import {getPost as selectPost, getPostIdsInChannel} from '@mm-redux/selectors/entities/posts';
|
||||
import {getCurrentChannelId} from '@mm-redux/selectors/entities/channels';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import configureStore from 'redux-mock-store';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {PostTypes, UserTypes} from '@mm-redux/action_types';
|
||||
|
||||
import * as PostSelectors from '@mm-redux/selectors/entities/posts';
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {fetchMyChannelsAndMembers, getChannelAndMyMember} from '@mm-redux/action
|
|||
import {getDataRetentionPolicy} from '@mm-redux/actions/general';
|
||||
import {receivedNewPost} from '@mm-redux/actions/posts';
|
||||
import {getMyTeams, getMyTeamMembers} from '@mm-redux/actions/teams';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import initialState from '@store/initial_state';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import moment from 'moment-timezone';
|
||||
|
||||
import {getSessions} from '@mm-redux/actions/users';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {GeneralTypes, RoleTypes, UserTypes} from '@mm-redux/action_types';
|
|||
import {getDataRetentionPolicy} from '@mm-redux/actions/general';
|
||||
import * as HelperActions from '@mm-redux/actions/helpers';
|
||||
import {autoUpdateTimezone} from '@mm-redux/actions/timezone';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import {getConfig, getLicense} from '@mm-redux/selectors/entities/general';
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import configureMockStore from 'redux-mock-store';
|
|||
import {ChannelTypes, RoleTypes} from '@mm-redux/action_types';
|
||||
import * as ChannelActions from '@mm-redux/actions/channels';
|
||||
import * as TeamActions from '@mm-redux/actions/teams';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General} from '@mm-redux/constants';
|
||||
|
||||
import * as Actions from '@actions/websocket';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {fetchChannelAndMyMember} from '@actions/helpers/channels';
|
|||
import {loadChannelsForTeam} from '@actions/views/channel';
|
||||
import {WebsocketEvents} from '@constants';
|
||||
import {markChannelAsRead} from '@mm-redux/actions/channels';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {ChannelTypes, TeamTypes, RoleTypes} from '@mm-redux/action_types';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import assert from 'assert';
|
||||
import {Server, WebSocket as MockWebSocket} from 'mock-socket';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import * as Actions from '@actions/websocket';
|
||||
import {WebsocketEvents} from '@constants';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {loadMe} from '@actions/views/user';
|
|||
import {WebsocketEvents} from '@constants';
|
||||
import {ChannelTypes, GeneralTypes, PreferenceTypes, TeamTypes, UserTypes, RoleTypes} from '@mm-redux/action_types';
|
||||
import {getProfilesByIds, getStatusesByIds} from '@mm-redux/actions/users';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import {getCurrentChannelId, getCurrentChannelStats} from '@mm-redux/selectors/entities/channels';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import assert from 'assert';
|
||||
import {Server, WebSocket as MockWebSocket} from 'mock-socket';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import * as Actions from '@actions/websocket';
|
||||
import {WebsocketEvents} from '@constants';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {Server, WebSocket as MockWebSocket} from 'mock-socket';
|
|||
|
||||
import * as ChannelActions from '@mm-redux/actions/channels';
|
||||
import * as PostActions from '@mm-redux/actions/posts';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General, Posts} from '@mm-redux/constants';
|
||||
import * as PostSelectors from '@mm-redux/selectors/entities/posts';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import assert from 'assert';
|
||||
import {Server, WebSocket as MockWebSocket} from 'mock-socket';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import * as Actions from '@actions/websocket';
|
||||
import {WebsocketEvents} from '@constants';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {Server, WebSocket as MockWebSocket} from 'mock-socket';
|
|||
import {batchActions} from 'redux-batched-actions';
|
||||
|
||||
import {TeamTypes, UserTypes} from '@mm-redux/action_types';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import * as Actions from '@actions/websocket';
|
||||
import {WebsocketEvents} from '@constants';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import {RoleTypes, TeamTypes} from '@mm-redux/action_types';
|
||||
import {notVisibleUsersActions} from '@mm-redux/actions/helpers';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {getCurrentTeamId, getTeams as getTeamsSelector} from '@mm-redux/selectors/entities/teams';
|
||||
import {getCurrentUser} from '@mm-redux/selectors/entities/users';
|
||||
import {ActionResult, DispatchFunc, GenericAction, GetStateFunc, batchActions} from '@mm-redux/types/actions';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import assert from 'assert';
|
|||
import {Server, WebSocket as MockWebSocket} from 'mock-socket';
|
||||
import {batchActions} from 'redux-batched-actions';
|
||||
import {TeamTypes, UserTypes} from '@mm-redux/action_types';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import * as Actions from '@actions/websocket';
|
||||
import {WebsocketEvents} from '@constants';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {loadChannelsForTeam} from '@actions/views/channel';
|
|||
import {getMe} from '@actions/views/user';
|
||||
import {ChannelTypes, TeamTypes, UserTypes, RoleTypes} from '@mm-redux/action_types';
|
||||
import {notVisibleUsersActions} from '@mm-redux/actions/helpers';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import {getAllChannels, getCurrentChannelId, getChannelMembersInChannels} from '@mm-redux/selectors/entities/channels';
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
|
|
@ -171,7 +171,7 @@ export function handleUserRoleUpdated(msg: WebSocketMessage) {
|
|||
|
||||
dispatch({
|
||||
type: RoleTypes.RECEIVED_ROLES,
|
||||
data: data.roles,
|
||||
data,
|
||||
});
|
||||
} catch {
|
||||
// do nothing
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import configureMockStore from 'redux-mock-store';
|
|||
|
||||
import {GeneralTypes, UserTypes} from '@mm-redux/action_types';
|
||||
import {notVisibleUsersActions} from '@mm-redux/actions/helpers';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General, Posts, RequestStatus} from '@mm-redux/constants';
|
||||
|
||||
import * as Actions from '@actions/websocket';
|
||||
|
|
|
|||
36
app/client/rest/apps.ts
Normal file
36
app/client/rest/apps.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {AppBinding, AppCallRequest, AppCallResponse, AppCallType} from '@mm-redux/types/apps';
|
||||
|
||||
export interface ClientAppsMix {
|
||||
executeAppCall: (call: AppCallRequest, type: AppCallType) => Promise<AppCallResponse>;
|
||||
getAppsBindings: (userID: string, channelID: string) => Promise<AppBinding[]>;
|
||||
}
|
||||
|
||||
const ClientApps = (superclass: any) => class extends superclass {
|
||||
executeAppCall = async (call: AppCallRequest, type: AppCallType) => {
|
||||
const callCopy = {
|
||||
...call,
|
||||
path: `${call.path}/${type}`,
|
||||
context: {
|
||||
...call.context,
|
||||
user_agent: 'mobile',
|
||||
},
|
||||
};
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getAppsProxyRoute()}/api/v1/call`,
|
||||
{method: 'post', body: JSON.stringify(callCopy)},
|
||||
);
|
||||
}
|
||||
|
||||
getAppsBindings = async (userID: string, channelID: string) => {
|
||||
return this.doFetch(
|
||||
this.getAppsProxyRoute() + `/api/v1/bindings?user_id=${userID}&channel_id=${channelID}&user_agent_type=mobile`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ClientApps;
|
||||
373
app/client/rest/base.ts
Normal file
373
app/client/rest/base.ts
Normal file
|
|
@ -0,0 +1,373 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {RNFetchBlobFetchRepsonse} from 'rn-fetch-blob';
|
||||
import urlParse from 'url-parse';
|
||||
|
||||
import {Options} from '@mm-redux/types/client4';
|
||||
|
||||
import * as ClientConstants from './constants';
|
||||
import ClientError from './error';
|
||||
|
||||
export default class ClientBase {
|
||||
clusterId = '';
|
||||
csrf = '';
|
||||
defaultHeaders: {[x: string]: string} = {};
|
||||
diagnosticId = '';
|
||||
enableLogging = false;
|
||||
includeCookies = true;
|
||||
logToConsole = false;
|
||||
managedConfig: any = null;
|
||||
serverVersion = '';
|
||||
token = '';
|
||||
translations = {
|
||||
connectionError: 'There appears to be a problem with your internet connection.',
|
||||
unknownError: 'We received an unexpected status code from the server.',
|
||||
};
|
||||
userAgent: string|null = null;
|
||||
url = '';
|
||||
urlVersion = '/api/v4';
|
||||
|
||||
getAbsoluteUrl(baseUrl: string) {
|
||||
if (typeof baseUrl !== 'string' || !baseUrl.startsWith('/')) {
|
||||
return baseUrl;
|
||||
}
|
||||
return this.getUrl() + baseUrl;
|
||||
}
|
||||
|
||||
getOptions(options: Options) {
|
||||
const newOptions: Options = {...options};
|
||||
|
||||
const headers: {[x: string]: string} = {
|
||||
[ClientConstants.HEADER_REQUESTED_WITH]: 'XMLHttpRequest',
|
||||
...this.defaultHeaders,
|
||||
};
|
||||
|
||||
if (this.token) {
|
||||
headers[ClientConstants.HEADER_AUTH] = `${ClientConstants.HEADER_BEARER} ${this.token}`;
|
||||
}
|
||||
|
||||
const csrfToken = this.csrf || '';
|
||||
if (options.method && options.method.toLowerCase() !== 'get' && csrfToken) {
|
||||
headers[ClientConstants.HEADER_X_CSRF_TOKEN] = csrfToken;
|
||||
}
|
||||
|
||||
if (this.includeCookies) {
|
||||
newOptions.credentials = 'include';
|
||||
}
|
||||
|
||||
if (this.userAgent) {
|
||||
headers[ClientConstants.HEADER_USER_AGENT] = this.userAgent;
|
||||
}
|
||||
|
||||
if (newOptions.headers) {
|
||||
Object.assign(headers, newOptions.headers);
|
||||
}
|
||||
|
||||
return {
|
||||
...newOptions,
|
||||
headers,
|
||||
};
|
||||
}
|
||||
|
||||
getServerVersion() {
|
||||
return this.serverVersion;
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
getUrl() {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
getUrlVersion() {
|
||||
return this.urlVersion;
|
||||
}
|
||||
|
||||
getWebSocketUrl = () => {
|
||||
return `${this.getBaseRoute()}/websocket`;
|
||||
}
|
||||
|
||||
setAcceptLanguage(locale: string) {
|
||||
this.defaultHeaders['Accept-Language'] = locale;
|
||||
}
|
||||
|
||||
setCSRF(csrfToken: string) {
|
||||
this.csrf = csrfToken;
|
||||
}
|
||||
|
||||
setDiagnosticId(diagnosticId: string) {
|
||||
this.diagnosticId = diagnosticId;
|
||||
}
|
||||
|
||||
setEnableLogging(enable: boolean) {
|
||||
this.enableLogging = enable;
|
||||
}
|
||||
|
||||
setIncludeCookies(include: boolean) {
|
||||
this.includeCookies = include;
|
||||
}
|
||||
|
||||
setManagedConfig(config: any) {
|
||||
this.managedConfig = config;
|
||||
}
|
||||
|
||||
setUserAgent(userAgent: string) {
|
||||
this.userAgent = userAgent;
|
||||
}
|
||||
|
||||
setToken(token: string) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
setUrl(url: string) {
|
||||
this.url = url.replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
// Routes
|
||||
getBaseRoute() {
|
||||
return `${this.url}${this.urlVersion}`;
|
||||
}
|
||||
|
||||
getUsersRoute() {
|
||||
return `${this.getBaseRoute()}/users`;
|
||||
}
|
||||
|
||||
getUserRoute(userId: string) {
|
||||
return `${this.getUsersRoute()}/${userId}`;
|
||||
}
|
||||
|
||||
getTeamsRoute() {
|
||||
return `${this.getBaseRoute()}/teams`;
|
||||
}
|
||||
|
||||
getTeamRoute(teamId: string) {
|
||||
return `${this.getTeamsRoute()}/${teamId}`;
|
||||
}
|
||||
|
||||
getTeamNameRoute(teamName: string) {
|
||||
return `${this.getTeamsRoute()}/name/${teamName}`;
|
||||
}
|
||||
|
||||
getTeamMembersRoute(teamId: string) {
|
||||
return `${this.getTeamRoute(teamId)}/members`;
|
||||
}
|
||||
|
||||
getTeamMemberRoute(teamId: string, userId: string) {
|
||||
return `${this.getTeamMembersRoute(teamId)}/${userId}`;
|
||||
}
|
||||
|
||||
getChannelsRoute() {
|
||||
return `${this.getBaseRoute()}/channels`;
|
||||
}
|
||||
|
||||
getChannelRoute(channelId: string) {
|
||||
return `${this.getChannelsRoute()}/${channelId}`;
|
||||
}
|
||||
|
||||
getChannelMembersRoute(channelId: string) {
|
||||
return `${this.getChannelRoute(channelId)}/members`;
|
||||
}
|
||||
|
||||
getChannelMemberRoute(channelId: string, userId: string) {
|
||||
return `${this.getChannelMembersRoute(channelId)}/${userId}`;
|
||||
}
|
||||
|
||||
getPostsRoute() {
|
||||
return `${this.getBaseRoute()}/posts`;
|
||||
}
|
||||
|
||||
getPostRoute(postId: string) {
|
||||
return `${this.getPostsRoute()}/${postId}`;
|
||||
}
|
||||
|
||||
getReactionsRoute() {
|
||||
return `${this.getBaseRoute()}/reactions`;
|
||||
}
|
||||
|
||||
getCommandsRoute() {
|
||||
return `${this.getBaseRoute()}/commands`;
|
||||
}
|
||||
|
||||
getFilesRoute() {
|
||||
return `${this.getBaseRoute()}/files`;
|
||||
}
|
||||
|
||||
getFileRoute(fileId: string) {
|
||||
return `${this.getFilesRoute()}/${fileId}`;
|
||||
}
|
||||
|
||||
getPreferencesRoute(userId: string) {
|
||||
return `${this.getUserRoute(userId)}/preferences`;
|
||||
}
|
||||
|
||||
getIncomingHooksRoute() {
|
||||
return `${this.getBaseRoute()}/hooks/incoming`;
|
||||
}
|
||||
|
||||
getIncomingHookRoute(hookId: string) {
|
||||
return `${this.getBaseRoute()}/hooks/incoming/${hookId}`;
|
||||
}
|
||||
|
||||
getOutgoingHooksRoute() {
|
||||
return `${this.getBaseRoute()}/hooks/outgoing`;
|
||||
}
|
||||
|
||||
getOutgoingHookRoute(hookId: string) {
|
||||
return `${this.getBaseRoute()}/hooks/outgoing/${hookId}`;
|
||||
}
|
||||
|
||||
getOAuthRoute() {
|
||||
return `${this.url}/oauth`;
|
||||
}
|
||||
|
||||
getOAuthAppsRoute() {
|
||||
return `${this.getBaseRoute()}/oauth/apps`;
|
||||
}
|
||||
|
||||
getOAuthAppRoute(appId: string) {
|
||||
return `${this.getOAuthAppsRoute()}/${appId}`;
|
||||
}
|
||||
|
||||
getEmojisRoute() {
|
||||
return `${this.getBaseRoute()}/emoji`;
|
||||
}
|
||||
|
||||
getEmojiRoute(emojiId: string) {
|
||||
return `${this.getEmojisRoute()}/${emojiId}`;
|
||||
}
|
||||
|
||||
getBrandRoute() {
|
||||
return `${this.getBaseRoute()}/brand`;
|
||||
}
|
||||
|
||||
getBrandImageUrl(timestamp: string) {
|
||||
return `${this.getBrandRoute()}/image?t=${timestamp}`;
|
||||
}
|
||||
|
||||
getDataRetentionRoute() {
|
||||
return `${this.getBaseRoute()}/data_retention`;
|
||||
}
|
||||
|
||||
getRolesRoute() {
|
||||
return `${this.getBaseRoute()}/roles`;
|
||||
}
|
||||
|
||||
getTimezonesRoute() {
|
||||
return `${this.getBaseRoute()}/system/timezones`;
|
||||
}
|
||||
|
||||
getRedirectLocationRoute() {
|
||||
return `${this.getBaseRoute()}/redirect_location`;
|
||||
}
|
||||
|
||||
getBotsRoute() {
|
||||
return `${this.getBaseRoute()}/bots`;
|
||||
}
|
||||
|
||||
getBotRoute(botUserId: string) {
|
||||
return `${this.getBotsRoute()}/${botUserId}`;
|
||||
}
|
||||
|
||||
getAppsProxyRoute() {
|
||||
return `${this.url}/plugins/com.mattermost.apps`;
|
||||
}
|
||||
|
||||
// Client Helpers
|
||||
handleRedirectProtocol = (url: string, response: RNFetchBlobFetchRepsonse) => {
|
||||
const serverUrl = this.getUrl();
|
||||
const parsed = urlParse(url);
|
||||
const {redirects} = response.rnfbRespInfo;
|
||||
if (redirects) {
|
||||
const redirectUrl = urlParse(redirects[redirects.length - 1]);
|
||||
|
||||
if (serverUrl === parsed.origin && parsed.host === redirectUrl.host && parsed.protocol !== redirectUrl.protocol) {
|
||||
this.setUrl(serverUrl.replace(parsed.protocol, redirectUrl.protocol));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
doFetch = async (url: string, options: Options) => {
|
||||
const {data} = await this.doFetchWithResponse(url, options);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
doFetchWithResponse = async (url: string, options: Options) => {
|
||||
const response = await fetch(url, this.getOptions(options));
|
||||
const headers = parseAndMergeNestedHeaders(response.headers);
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = await response.json();
|
||||
} catch (err) {
|
||||
throw new ClientError(this.getUrl(), {
|
||||
message: 'Received invalid response from the server.',
|
||||
intl: {
|
||||
id: 'mobile.request.invalid_response',
|
||||
defaultMessage: 'Received invalid response from the server.',
|
||||
},
|
||||
url,
|
||||
});
|
||||
}
|
||||
|
||||
if (headers.has(ClientConstants.HEADER_X_VERSION_ID) && !headers.get('Cache-Control')) {
|
||||
const serverVersion = headers.get(ClientConstants.HEADER_X_VERSION_ID);
|
||||
if (serverVersion && this.serverVersion !== serverVersion) {
|
||||
this.serverVersion = serverVersion;
|
||||
}
|
||||
}
|
||||
|
||||
if (headers.has(ClientConstants.HEADER_X_CLUSTER_ID)) {
|
||||
const clusterId = headers.get(ClientConstants.HEADER_X_CLUSTER_ID);
|
||||
if (clusterId && this.clusterId !== clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
}
|
||||
|
||||
if (response.ok) {
|
||||
return {
|
||||
response,
|
||||
headers,
|
||||
data,
|
||||
};
|
||||
}
|
||||
|
||||
const msg = data.message || '';
|
||||
|
||||
if (this.logToConsole) {
|
||||
console.error(msg); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
throw new ClientError(this.getUrl(), {
|
||||
message: msg,
|
||||
server_error_id: data.id,
|
||||
status_code: data.status_code,
|
||||
url,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function parseAndMergeNestedHeaders(originalHeaders: any) {
|
||||
const headers = new Map();
|
||||
let nestedHeaders = new Map();
|
||||
originalHeaders.forEach((val: string, key: string) => {
|
||||
const capitalizedKey = key.replace(/\b[a-z]/g, (l) => l.toUpperCase());
|
||||
let realVal = val;
|
||||
if (val && val.match(/\n\S+:\s\S+/)) {
|
||||
const nestedHeaderStrings = val.split('\n');
|
||||
realVal = nestedHeaderStrings.shift() as string;
|
||||
const moreNestedHeaders = new Map(
|
||||
nestedHeaderStrings.map((h: any) => h.split(/:\s/)),
|
||||
);
|
||||
nestedHeaders = new Map([...nestedHeaders, ...moreNestedHeaders]);
|
||||
}
|
||||
headers.set(capitalizedKey, realVal);
|
||||
});
|
||||
return new Map([...headers, ...nestedHeaders]);
|
||||
}
|
||||
39
app/client/rest/bots.ts
Normal file
39
app/client/rest/bots.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {buildQueryString} from '@mm-redux/utils/helpers';
|
||||
|
||||
import type {Bot} from '@mm-redux/types/bots';
|
||||
|
||||
export interface ClientBotsMix {
|
||||
getBot: (botUserId: string) => Promise<Bot>;
|
||||
getBots: (page?: number, perPage?: number) => Promise<Bot[]>;
|
||||
getBotsIncludeDeleted: (page?: number, perPage?: number) => Promise<Bot[]>;
|
||||
}
|
||||
|
||||
const PER_PAGE_DEFAULT = 60;
|
||||
|
||||
const ClientBots = (superclass: any) => class extends superclass {
|
||||
getBot = async (botUserId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getBotRoute(botUserId)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
|
||||
getBots = async (page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getBotsRoute()}${buildQueryString({page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
|
||||
getBotsIncludeDeleted = async (page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getBotsRoute()}${buildQueryString({include_deleted: true, page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ClientBots;
|
||||
308
app/client/rest/channels.ts
Normal file
308
app/client/rest/channels.ts
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {analytics} from '@init/analytics';
|
||||
import {Channel, ChannelMemberCountByGroup, ChannelMembership, ChannelNotifyProps, ChannelStats} from '@mm-redux/types/channels';
|
||||
import {buildQueryString} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {PER_PAGE_DEFAULT} from './constants';
|
||||
|
||||
export interface ClientChannelsMix {
|
||||
getAllChannels: (page?: number, perPage?: number, notAssociatedToGroup?: string, excludeDefaultChannels?: boolean, includeTotalCount?: boolean) => Promise<any>;
|
||||
createChannel: (channel: Channel) => Promise<Channel>;
|
||||
createDirectChannel: (userIds: string[]) => Promise<Channel>;
|
||||
createGroupChannel: (userIds: string[]) => Promise<Channel>;
|
||||
deleteChannel: (channelId: string) => Promise<any>;
|
||||
unarchiveChannel: (channelId: string) => Promise<Channel>;
|
||||
updateChannel: (channel: Channel) => Promise<Channel>;
|
||||
convertChannelToPrivate: (channelId: string) => Promise<Channel>;
|
||||
updateChannelPrivacy: (channelId: string, privacy: any) => Promise<Channel>;
|
||||
patchChannel: (channelId: string, channelPatch: Partial<Channel>) => Promise<Channel>;
|
||||
updateChannelNotifyProps: (props: ChannelNotifyProps & {channel_id: string, user_id: string}) => Promise<any>;
|
||||
getChannel: (channelId: string) => Promise<Channel>;
|
||||
getChannelByName: (teamId: string, channelName: string, includeDeleted?: boolean) => Promise<Channel>;
|
||||
getChannelByNameAndTeamName: (teamName: string, channelName: string, includeDeleted?: boolean) => Promise<Channel>;
|
||||
getChannels: (teamId: string, page?: number, perPage?: number) => Promise<Channel[]>;
|
||||
getArchivedChannels: (teamId: string, page?: number, perPage?: number) => Promise<Channel[]>;
|
||||
getMyChannels: (teamId: string, includeDeleted?: boolean) => Promise<Channel[]>;
|
||||
getMyChannelMember: (channelId: string) => Promise<ChannelMembership>;
|
||||
getMyChannelMembers: (teamId: string) => Promise<ChannelMembership[]>;
|
||||
getChannelMembers: (channelId: string, page?: number, perPage?: number) => Promise<ChannelMembership[]>;
|
||||
getChannelTimezones: (channelId: string) => Promise<string[]>;
|
||||
getChannelMember: (channelId: string, userId: string) => Promise<ChannelMembership>;
|
||||
getChannelMembersByIds: (channelId: string, userIds: string[]) => Promise<ChannelMembership[]>;
|
||||
addToChannel: (userId: string, channelId: string, postRootId?: string) => Promise<ChannelMembership>;
|
||||
removeFromChannel: (userId: string, channelId: string) => Promise<any>;
|
||||
getChannelStats: (channelId: string) => Promise<ChannelStats>;
|
||||
getChannelMemberCountsByGroup: (channelId: string, includeTimezones: boolean) => Promise<ChannelMemberCountByGroup[]>;
|
||||
viewMyChannel: (channelId: string, prevChannelId?: string) => Promise<any>;
|
||||
autocompleteChannels: (teamId: string, name: string) => Promise<Channel[]>;
|
||||
autocompleteChannelsForSearch: (teamId: string, name: string) => Promise<Channel[]>;
|
||||
searchChannels: (teamId: string, term: string) => Promise<Channel[]>;
|
||||
searchArchivedChannels: (teamId: string, term: string) => Promise<Channel[]>;
|
||||
}
|
||||
|
||||
const ClientChannels = (superclass: any) => class extends superclass {
|
||||
getAllChannels = async (page = 0, perPage = PER_PAGE_DEFAULT, notAssociatedToGroup = '', excludeDefaultChannels = false, includeTotalCount = false) => {
|
||||
const queryData = {
|
||||
page,
|
||||
per_page: perPage,
|
||||
not_associated_to_group: notAssociatedToGroup,
|
||||
exclude_default_channels: excludeDefaultChannels,
|
||||
include_total_count: includeTotalCount,
|
||||
};
|
||||
return this.doFetch(
|
||||
`${this.getChannelsRoute()}${buildQueryString(queryData)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
createChannel = async (channel: Channel) => {
|
||||
analytics.trackAPI('api_channels_create', {team_id: channel.team_id});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelsRoute()}`,
|
||||
{method: 'post', body: JSON.stringify(channel)},
|
||||
);
|
||||
};
|
||||
|
||||
createDirectChannel = async (userIds: string[]) => {
|
||||
analytics.trackAPI('api_channels_create_direct');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelsRoute()}/direct`,
|
||||
{method: 'post', body: JSON.stringify(userIds)},
|
||||
);
|
||||
};
|
||||
|
||||
createGroupChannel = async (userIds: string[]) => {
|
||||
analytics.trackAPI('api_channels_create_group');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelsRoute()}/group`,
|
||||
{method: 'post', body: JSON.stringify(userIds)},
|
||||
);
|
||||
};
|
||||
|
||||
deleteChannel = async (channelId: string) => {
|
||||
analytics.trackAPI('api_channels_delete', {channel_id: channelId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}`,
|
||||
{method: 'delete'},
|
||||
);
|
||||
};
|
||||
|
||||
unarchiveChannel = async (channelId: string) => {
|
||||
analytics.trackAPI('api_channels_unarchive', {channel_id: channelId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/restore`,
|
||||
{method: 'post'},
|
||||
);
|
||||
};
|
||||
|
||||
updateChannel = async (channel: Channel) => {
|
||||
analytics.trackAPI('api_channels_update', {channel_id: channel.id});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channel.id)}`,
|
||||
{method: 'put', body: JSON.stringify(channel)},
|
||||
);
|
||||
};
|
||||
|
||||
convertChannelToPrivate = async (channelId: string) => {
|
||||
analytics.trackAPI('api_channels_convert_to_private', {channel_id: channelId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/convert`,
|
||||
{method: 'post'},
|
||||
);
|
||||
};
|
||||
|
||||
updateChannelPrivacy = async (channelId: string, privacy: any) => {
|
||||
analytics.trackAPI('api_channels_update_privacy', {channel_id: channelId, privacy});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/privacy`,
|
||||
{method: 'put', body: JSON.stringify({privacy})},
|
||||
);
|
||||
};
|
||||
|
||||
patchChannel = async (channelId: string, channelPatch: Partial<Channel>) => {
|
||||
analytics.trackAPI('api_channels_patch', {channel_id: channelId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/patch`,
|
||||
{method: 'put', body: JSON.stringify(channelPatch)},
|
||||
);
|
||||
};
|
||||
|
||||
updateChannelNotifyProps = async (props: ChannelNotifyProps & {channel_id: string, user_id: string}) => {
|
||||
analytics.trackAPI('api_users_update_channel_notifications', {channel_id: props.channel_id});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelMemberRoute(props.channel_id, props.user_id)}/notify_props`,
|
||||
{method: 'put', body: JSON.stringify(props)},
|
||||
);
|
||||
};
|
||||
|
||||
getChannel = async (channelId: string) => {
|
||||
analytics.trackAPI('api_channel_get', {channel_id: channelId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getChannelByName = async (teamId: string, channelName: string, includeDeleted = false) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/channels/name/${channelName}?include_deleted=${includeDeleted}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getChannelByNameAndTeamName = async (teamName: string, channelName: string, includeDeleted = false) => {
|
||||
analytics.trackAPI('api_channel_get_by_name_and_teamName', {channel_name: channelName, team_name: teamName, include_deleted: includeDeleted});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getTeamNameRoute(teamName)}/channels/name/${channelName}?include_deleted=${includeDeleted}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getChannels = async (teamId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/channels${buildQueryString({page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getArchivedChannels = async (teamId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/channels/deleted${buildQueryString({page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getMyChannels = async (teamId: string, includeDeleted = false) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute('me')}/teams/${teamId}/channels${buildQueryString({include_deleted: includeDeleted})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getMyChannelMember = async (channelId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getChannelMemberRoute(channelId, 'me')}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getMyChannelMembers = async (teamId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute('me')}/teams/${teamId}/channels/members`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getChannelMembers = async (channelId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getChannelMembersRoute(channelId)}${buildQueryString({page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getChannelTimezones = async (channelId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/timezones`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getChannelMember = async (channelId: string, userId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getChannelMemberRoute(channelId, userId)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getChannelMembersByIds = async (channelId: string, userIds: string[]) => {
|
||||
return this.doFetch(
|
||||
`${this.getChannelMembersRoute(channelId)}/ids`,
|
||||
{method: 'post', body: JSON.stringify(userIds)},
|
||||
);
|
||||
};
|
||||
|
||||
addToChannel = async (userId: string, channelId: string, postRootId = '') => {
|
||||
analytics.trackAPI('api_channels_add_member', {channel_id: channelId});
|
||||
|
||||
const member = {user_id: userId, channel_id: channelId, post_root_id: postRootId};
|
||||
return this.doFetch(
|
||||
`${this.getChannelMembersRoute(channelId)}`,
|
||||
{method: 'post', body: JSON.stringify(member)},
|
||||
);
|
||||
};
|
||||
|
||||
removeFromChannel = async (userId: string, channelId: string) => {
|
||||
analytics.trackAPI('api_channels_remove_member', {channel_id: channelId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelMemberRoute(channelId, userId)}`,
|
||||
{method: 'delete'},
|
||||
);
|
||||
};
|
||||
|
||||
getChannelStats = async (channelId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/stats`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getChannelMemberCountsByGroup = async (channelId: string, includeTimezones: boolean) => {
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/member_counts_by_group?include_timezones=${includeTimezones}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
viewMyChannel = async (channelId: string, prevChannelId?: string) => {
|
||||
const data = {channel_id: channelId, prev_channel_id: prevChannelId};
|
||||
return this.doFetch(
|
||||
`${this.getChannelsRoute()}/members/me/view`,
|
||||
{method: 'post', body: JSON.stringify(data)},
|
||||
);
|
||||
};
|
||||
|
||||
autocompleteChannels = async (teamId: string, name: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/channels/autocomplete${buildQueryString({name})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
autocompleteChannelsForSearch = async (teamId: string, name: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/channels/search_autocomplete${buildQueryString({name})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
searchChannels = async (teamId: string, term: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/channels/search`,
|
||||
{method: 'post', body: JSON.stringify({term})},
|
||||
);
|
||||
};
|
||||
|
||||
searchArchivedChannels = async (teamId: string, term: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/channels/search_archived`,
|
||||
{method: 'post', body: JSON.stringify({term})},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientChannels;
|
||||
14
app/client/rest/constants.ts
Normal file
14
app/client/rest/constants.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export const HEADER_AUTH = 'Authorization';
|
||||
export const HEADER_BEARER = 'BEARER';
|
||||
export const HEADER_REQUESTED_WITH = 'X-Requested-With';
|
||||
export const HEADER_USER_AGENT = 'User-Agent';
|
||||
export const HEADER_X_CLUSTER_ID = 'X-Cluster-Id';
|
||||
export const HEADER_X_CSRF_TOKEN = 'X-CSRF-Token';
|
||||
export const HEADER_TOKEN = 'Token';
|
||||
export const HEADER_X_VERSION_ID = 'X-Version-Id';
|
||||
export const DEFAULT_LIMIT_BEFORE = 30;
|
||||
export const DEFAULT_LIMIT_AFTER = 30;
|
||||
export const PER_PAGE_DEFAULT = 60;
|
||||
101
app/client/rest/emojis.ts
Normal file
101
app/client/rest/emojis.ts
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import FormData from 'form-data';
|
||||
|
||||
import {analytics} from '@init/analytics';
|
||||
import {CustomEmoji} from '@mm-redux/types/emojis';
|
||||
import {buildQueryString} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {PER_PAGE_DEFAULT} from './constants';
|
||||
|
||||
export interface ClientEmojisMix {
|
||||
createCustomEmoji: (emoji: CustomEmoji, imageData: any) => Promise<CustomEmoji>;
|
||||
getCustomEmoji: (id: string) => Promise<CustomEmoji>;
|
||||
getCustomEmojiByName: (name: string) => Promise<CustomEmoji>;
|
||||
getCustomEmojis: (page?: number, perPage?: number, sort?: string) => Promise<CustomEmoji[]>;
|
||||
deleteCustomEmoji: (emojiId: string) => Promise<any>;
|
||||
getSystemEmojiImageUrl: (filename: string) => string;
|
||||
getCustomEmojiImageUrl: (id: string) => string;
|
||||
searchCustomEmoji: (term: string, options?: Record<string, any>) => Promise<CustomEmoji[]>;
|
||||
autocompleteCustomEmoji: (name: string) => Promise<CustomEmoji[]>;
|
||||
}
|
||||
|
||||
const ClientEmojis = (superclass: any) => class extends superclass {
|
||||
createCustomEmoji = async (emoji: CustomEmoji, imageData: any) => {
|
||||
analytics.trackAPI('api_emoji_custom_add');
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('image', imageData);
|
||||
formData.append('emoji', JSON.stringify(emoji));
|
||||
const request: any = {
|
||||
method: 'post',
|
||||
body: formData,
|
||||
};
|
||||
|
||||
if (formData.getBoundary) {
|
||||
request.headers = {
|
||||
'Content-Type': `multipart/form-data; boundary=${formData.getBoundary()}`,
|
||||
};
|
||||
}
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getEmojisRoute()}`,
|
||||
request,
|
||||
);
|
||||
};
|
||||
|
||||
getCustomEmoji = async (id: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getEmojisRoute()}/${id}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getCustomEmojiByName = async (name: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getEmojisRoute()}/name/${name}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getCustomEmojis = async (page = 0, perPage = PER_PAGE_DEFAULT, sort = '') => {
|
||||
return this.doFetch(
|
||||
`${this.getEmojisRoute()}${buildQueryString({page, per_page: perPage, sort})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
deleteCustomEmoji = async (emojiId: string) => {
|
||||
analytics.trackAPI('api_emoji_custom_delete');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getEmojiRoute(emojiId)}`,
|
||||
{method: 'delete'},
|
||||
);
|
||||
};
|
||||
|
||||
getSystemEmojiImageUrl = (filename: string) => {
|
||||
return `${this.url}/static/emoji/${filename}.png`;
|
||||
};
|
||||
|
||||
getCustomEmojiImageUrl = (id: string) => {
|
||||
return `${this.getEmojiRoute(id)}/image`;
|
||||
};
|
||||
|
||||
searchCustomEmoji = async (term: string, options = {}) => {
|
||||
return this.doFetch(
|
||||
`${this.getEmojisRoute()}/search`,
|
||||
{method: 'post', body: JSON.stringify({term, ...options})},
|
||||
);
|
||||
};
|
||||
|
||||
autocompleteCustomEmoji = async (name: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getEmojisRoute()}/autocomplete${buildQueryString({name})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientEmojis;
|
||||
26
app/client/rest/error.ts
Normal file
26
app/client/rest/error.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {cleanUrlForLogging} from '@mm-redux/utils/sentry';
|
||||
|
||||
export default class ClientError extends Error {
|
||||
url: string;
|
||||
intl: { defaultMessage: string; id: string } | { defaultMessage: string; id: string } | { id: string; defaultMessage: string; values: any } | { id: string; defaultMessage: string };
|
||||
server_error_id: any;
|
||||
status_code: any;
|
||||
details: Error;
|
||||
constructor(baseUrl: string, data: any) {
|
||||
super(data.message + ': ' + cleanUrlForLogging(baseUrl, data.url));
|
||||
|
||||
this.message = data.message;
|
||||
this.url = data.url;
|
||||
this.intl = data.intl;
|
||||
this.server_error_id = data.server_error_id;
|
||||
this.status_code = data.status_code;
|
||||
this.details = data.details;
|
||||
|
||||
// Ensure message is treated as a property of this class when object spreading. Without this,
|
||||
// copying the object by using `{...error}` would not include the message.
|
||||
Object.defineProperty(this, 'message', {enumerable: true});
|
||||
}
|
||||
}
|
||||
47
app/client/rest/files.ts
Normal file
47
app/client/rest/files.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export interface ClientFilesMix {
|
||||
getFileUrl: (fileId: string, timestamp: number) => string;
|
||||
getFileThumbnailUrl: (fileId: string, timestamp: number) => string;
|
||||
getFilePreviewUrl: (fileId: string, timestamp: number) => string;
|
||||
getFilePublicLink: (fileId: string) => Promise<any>;
|
||||
}
|
||||
|
||||
const ClientFiles = (superclass: any) => class extends superclass {
|
||||
getFileUrl(fileId: string, timestamp: number) {
|
||||
let url = `${this.getFileRoute(fileId)}`;
|
||||
if (timestamp) {
|
||||
url += `?${timestamp}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
getFileThumbnailUrl(fileId: string, timestamp: number) {
|
||||
let url = `${this.getFileRoute(fileId)}/thumbnail`;
|
||||
if (timestamp) {
|
||||
url += `?${timestamp}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
getFilePreviewUrl(fileId: string, timestamp: number) {
|
||||
let url = `${this.getFileRoute(fileId)}/preview`;
|
||||
if (timestamp) {
|
||||
url += `?${timestamp}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
getFilePublicLink = async (fileId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getFileRoute(fileId)}/link`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ClientFiles;
|
||||
98
app/client/rest/general.ts
Normal file
98
app/client/rest/general.ts
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Config} from '@mm-redux/types/config';
|
||||
import {Role} from '@mm-redux/types/roles';
|
||||
import {Dictionary} from '@mm-redux/types/utilities';
|
||||
import {buildQueryString} from '@mm-redux/utils/helpers';
|
||||
|
||||
import ClientError from './error';
|
||||
|
||||
export interface ClientGeneralMix {
|
||||
getOpenGraphMetadata: (url: string) => Promise<any>;
|
||||
ping: () => Promise<any>;
|
||||
logClientError: (message: string, level?: string) => Promise<any>;
|
||||
getClientConfigOld: () => Promise<Config>;
|
||||
getClientLicenseOld: () => Promise<any>;
|
||||
getTimezones: () => Promise<string[]>;
|
||||
getDataRetentionPolicy: () => Promise<any>;
|
||||
getRolesByNames: (rolesNames: string[]) => Promise<Role[]>;
|
||||
getRedirectLocation: (urlParam: string) => Promise<Dictionary<string>>;
|
||||
}
|
||||
|
||||
const ClientGeneral = (superclass: any) => class extends superclass {
|
||||
getOpenGraphMetadata = async (url: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/opengraph`,
|
||||
{method: 'post', body: JSON.stringify({url})},
|
||||
);
|
||||
};
|
||||
|
||||
ping = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/system/ping?time=${Date.now()}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
logClientError = async (message: string, level = 'ERROR') => {
|
||||
const url = `${this.getBaseRoute()}/logs`;
|
||||
|
||||
if (!this.enableLogging) {
|
||||
throw new ClientError(this.getUrl(), {
|
||||
message: 'Logging disabled.',
|
||||
url,
|
||||
});
|
||||
}
|
||||
|
||||
return this.doFetch(
|
||||
url,
|
||||
{method: 'post', body: JSON.stringify({message, level})},
|
||||
);
|
||||
};
|
||||
|
||||
getClientConfigOld = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/config/client?format=old`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getClientLicenseOld = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/license/client?format=old`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getTimezones = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getTimezonesRoute()}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getDataRetentionPolicy = () => {
|
||||
return this.doFetch(
|
||||
`${this.getDataRetentionRoute()}/policy`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getRolesByNames = async (rolesNames: string[]) => {
|
||||
return this.doFetch(
|
||||
`${this.getRolesRoute()}/names`,
|
||||
{method: 'post', body: JSON.stringify(rolesNames)},
|
||||
);
|
||||
};
|
||||
|
||||
getRedirectLocation = async (urlParam: string) => {
|
||||
if (!urlParam.length) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const url = `${this.getRedirectLocationRoute()}${buildQueryString({url: urlParam})}`;
|
||||
return this.doFetch(url, {method: 'get'});
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientGeneral;
|
||||
53
app/client/rest/groups.ts
Normal file
53
app/client/rest/groups.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Group} from '@mm-redux/types/groups';
|
||||
import {buildQueryString} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {PER_PAGE_DEFAULT} from './constants';
|
||||
|
||||
export interface ClientGroupsMix {
|
||||
getGroups: (filterAllowReference?: boolean, page?: number, perPage?: number) => Promise<Group[]>;
|
||||
getGroupsByUserId: (userID: string) => Promise<Group[]>;
|
||||
getAllGroupsAssociatedToTeam: (teamID: string, filterAllowReference?: boolean) => Promise<Group[]>;
|
||||
getAllGroupsAssociatedToChannelsInTeam: (teamID: string, filterAllowReference?: boolean) => Promise<Group[]>;
|
||||
getAllGroupsAssociatedToChannel: (channelID: string, filterAllowReference?: boolean) => Promise<Group[]>;
|
||||
}
|
||||
|
||||
const ClientGroups = (superclass: any) => class extends superclass {
|
||||
getGroups = async (filterAllowReference = false, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/groups${buildQueryString({filter_allow_reference: filterAllowReference, page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getGroupsByUserId = async (userID: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/${userID}/groups`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
getAllGroupsAssociatedToTeam = async (teamID: string, filterAllowReference = false) => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/teams/${teamID}/groups${buildQueryString({paginate: false, filter_allow_reference: filterAllowReference})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getAllGroupsAssociatedToChannelsInTeam = async (teamID: string, filterAllowReference = false) => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/teams/${teamID}/groups_by_channels${buildQueryString({paginate: false, filter_allow_reference: filterAllowReference})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getAllGroupsAssociatedToChannel = async (channelID: string, filterAllowReference = false) => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/channels/${channelID}/groups${buildQueryString({paginate: false, filter_allow_reference: filterAllowReference})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientGroups;
|
||||
|
|
@ -4,7 +4,8 @@
|
|||
import assert from 'assert';
|
||||
import nock from 'nock';
|
||||
|
||||
import {ClientError, HEADER_X_VERSION_ID} from '@mm-redux/client/client4';
|
||||
import {HEADER_X_VERSION_ID} from '@client/rest/constants';
|
||||
import ClientError from '@client/rest/error';
|
||||
import TestHelper from 'test/test_helper';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
||||
56
app/client/rest/index.ts
Normal file
56
app/client/rest/index.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import mix from '@utils/mix';
|
||||
|
||||
import {DEFAULT_LIMIT_AFTER, DEFAULT_LIMIT_BEFORE, HEADER_X_VERSION_ID} from './constants';
|
||||
import ClientApps, {ClientAppsMix} from './apps';
|
||||
import ClientBase from './base';
|
||||
import ClientBots, {ClientBotsMix} from './bots';
|
||||
import ClientChannels, {ClientChannelsMix} from './channels';
|
||||
import ClientEmojis, {ClientEmojisMix} from './emojis';
|
||||
import ClientFiles, {ClientFilesMix} from './files';
|
||||
import ClientGeneral, {ClientGeneralMix} from './general';
|
||||
import ClientGroups, {ClientGroupsMix} from './groups';
|
||||
import ClientIntegrations, {ClientIntegrationsMix} from './integrations';
|
||||
import ClientPosts, {ClientPostsMix} from './posts';
|
||||
import ClientPreferences, {ClientPreferencesMix} from './preferences';
|
||||
import ClientTeams, {ClientTeamsMix} from './teams';
|
||||
import ClientTos, {ClientTosMix} from './tos';
|
||||
import ClientUsers, {ClientUsersMix} from './users';
|
||||
|
||||
interface Client extends ClientBase,
|
||||
ClientAppsMix,
|
||||
ClientBotsMix,
|
||||
ClientChannelsMix,
|
||||
ClientEmojisMix,
|
||||
ClientFilesMix,
|
||||
ClientGeneralMix,
|
||||
ClientGroupsMix,
|
||||
ClientIntegrationsMix,
|
||||
ClientPostsMix,
|
||||
ClientPreferencesMix,
|
||||
ClientTeamsMix,
|
||||
ClientTosMix,
|
||||
ClientUsersMix
|
||||
{}
|
||||
|
||||
class Client extends mix(ClientBase).with(
|
||||
ClientApps,
|
||||
ClientBots,
|
||||
ClientChannels,
|
||||
ClientEmojis,
|
||||
ClientFiles,
|
||||
ClientGeneral,
|
||||
ClientGroups,
|
||||
ClientIntegrations,
|
||||
ClientPosts,
|
||||
ClientPreferences,
|
||||
ClientTeams,
|
||||
ClientTos,
|
||||
ClientUsers,
|
||||
) {}
|
||||
|
||||
const Client4 = new Client();
|
||||
|
||||
export {Client4, Client, DEFAULT_LIMIT_AFTER, DEFAULT_LIMIT_BEFORE, HEADER_X_VERSION_ID};
|
||||
68
app/client/rest/integrations.ts
Normal file
68
app/client/rest/integrations.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {analytics} from '@init/analytics';
|
||||
import {Command, DialogSubmission} from '@mm-redux/types/integrations';
|
||||
import {buildQueryString} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {PER_PAGE_DEFAULT} from './constants';
|
||||
|
||||
export interface ClientIntegrationsMix {
|
||||
getCommandsList: (teamId: string) => Promise<Command[]>;
|
||||
getCommandAutocompleteSuggestionsList: (userInput: string, teamId: string, commandArgs?: Record<string, any>) => Promise<Command[]>;
|
||||
getAutocompleteCommandsList: (teamId: string, page?: number, perPage?: number) => Promise<Command[]>;
|
||||
executeCommand: (command: Command, commandArgs?: Record<string, any>) => Promise<any>;
|
||||
addCommand: (command: Command) => Promise<Command>;
|
||||
submitInteractiveDialog: (data: DialogSubmission) => Promise<any>;
|
||||
}
|
||||
|
||||
const ClientIntegrations = (superclass: any) => class extends superclass {
|
||||
getCommandsList = async (teamId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getCommandsRoute()}?team_id=${teamId}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getCommandAutocompleteSuggestionsList = async (userInput: string, teamId: string, commandArgs: {}) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/commands/autocomplete_suggestions${buildQueryString({...commandArgs, user_input: userInput})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getAutocompleteCommandsList = async (teamId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/commands/autocomplete${buildQueryString({page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
executeCommand = async (command: Command, commandArgs = {}) => {
|
||||
analytics.trackAPI('api_integrations_used');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getCommandsRoute()}/execute`,
|
||||
{method: 'post', body: JSON.stringify({command, ...commandArgs})},
|
||||
);
|
||||
};
|
||||
|
||||
addCommand = async (command: Command) => {
|
||||
analytics.trackAPI('api_integrations_created');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getCommandsRoute()}`,
|
||||
{method: 'post', body: JSON.stringify(command)},
|
||||
);
|
||||
};
|
||||
|
||||
submitInteractiveDialog = async (data: DialogSubmission) => {
|
||||
analytics.trackAPI('api_interactive_messages_dialog_submitted');
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/actions/dialogs/submit`,
|
||||
{method: 'post', body: JSON.stringify(data)},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientIntegrations;
|
||||
237
app/client/rest/posts.ts
Normal file
237
app/client/rest/posts.ts
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {analytics} from '@init/analytics';
|
||||
import {FileInfo} from '@mm-redux/types/files';
|
||||
import {Post} from '@mm-redux/types/posts';
|
||||
import {buildQueryString} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {PER_PAGE_DEFAULT} from './constants';
|
||||
|
||||
export interface ClientPostsMix {
|
||||
createPost: (post: Post) => Promise<Post>;
|
||||
updatePost: (post: Post) => Promise<Post>;
|
||||
getPost: (postId: string) => Promise<Post>;
|
||||
patchPost: (postPatch: Partial<Post> & {id: string}) => Promise<Post>;
|
||||
deletePost: (postId: string) => Promise<any>;
|
||||
getPostThread: (postId: string) => Promise<any>;
|
||||
getPosts: (channelId: string, page?: number, perPage?: number) => Promise<any>;
|
||||
getPostsSince: (channelId: string, since: number) => Promise<any>;
|
||||
getPostsBefore: (channelId: string, postId: string, page?: number, perPage?: number) => Promise<any>;
|
||||
getPostsAfter: (channelId: string, postId: string, page?: number, perPage?: number) => Promise<any>;
|
||||
getFileInfosForPost: (postId: string) => Promise<FileInfo[]>;
|
||||
getFlaggedPosts: (userId: string, channelId?: string, teamId?: string, page?: number, perPage?: number) => Promise<any>;
|
||||
getPinnedPosts: (channelId: string) => Promise<any>;
|
||||
markPostAsUnread: (userId: string, postId: string) => Promise<any>;
|
||||
pinPost: (postId: string) => Promise<any>;
|
||||
unpinPost: (postId: string) => Promise<any>;
|
||||
addReaction: (userId: string, postId: string, emojiName: string) => Promise<any>;
|
||||
removeReaction: (userId: string, postId: string, emojiName: string) => Promise<any>;
|
||||
getReactionsForPost: (postId: string) => Promise<any>;
|
||||
searchPostsWithParams: (teamId: string, params: any) => Promise<any>;
|
||||
searchPosts: (teamId: string, terms: string, isOrSearch: boolean) => Promise<any>;
|
||||
doPostAction: (postId: string, actionId: string, selectedOption?: string) => Promise<any>;
|
||||
doPostActionWithCookie: (postId: string, actionId: string, actionCookie: string, selectedOption?: string) => Promise<any>;
|
||||
}
|
||||
|
||||
const ClientPosts = (superclass: any) => class extends superclass {
|
||||
createPost = async (post: Post) => {
|
||||
analytics.trackAPI('api_posts_create', {channel_id: post.channel_id});
|
||||
|
||||
if (post.root_id != null && post.root_id !== '') {
|
||||
analytics.trackAPI('api_posts_replied', {channel_id: post.channel_id});
|
||||
}
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute()}`,
|
||||
{method: 'post', body: JSON.stringify(post)},
|
||||
);
|
||||
};
|
||||
|
||||
updatePost = async (post: Post) => {
|
||||
analytics.trackAPI('api_posts_update', {channel_id: post.channel_id});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(post.id)}`,
|
||||
{method: 'put', body: JSON.stringify(post)},
|
||||
);
|
||||
};
|
||||
|
||||
getPost = async (postId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(postId)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
patchPost = async (postPatch: Partial<Post> & {id: string}) => {
|
||||
analytics.trackAPI('api_posts_patch', {channel_id: postPatch.channel_id});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(postPatch.id)}/patch`,
|
||||
{method: 'put', body: JSON.stringify(postPatch)},
|
||||
);
|
||||
};
|
||||
|
||||
deletePost = async (postId: string) => {
|
||||
analytics.trackAPI('api_posts_delete');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(postId)}`,
|
||||
{method: 'delete'},
|
||||
);
|
||||
};
|
||||
|
||||
getPostThread = async (postId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(postId)}/thread`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getPosts = async (channelId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/posts${buildQueryString({page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getPostsSince = async (channelId: string, since: number) => {
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/posts${buildQueryString({since})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getPostsBefore = async (channelId: string, postId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
analytics.trackAPI('api_posts_get_before', {channel_id: channelId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/posts${buildQueryString({before: postId, page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getPostsAfter = async (channelId: string, postId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
analytics.trackAPI('api_posts_get_after', {channel_id: channelId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/posts${buildQueryString({after: postId, page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getFileInfosForPost = async (postId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(postId)}/files/info`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getFlaggedPosts = async (userId: string, channelId = '', teamId = '', page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
analytics.trackAPI('api_posts_get_flagged', {team_id: teamId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userId)}/posts/flagged${buildQueryString({channel_id: channelId, team_id: teamId, page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getPinnedPosts = async (channelId: string) => {
|
||||
analytics.trackAPI('api_posts_get_pinned', {channel_id: channelId});
|
||||
return this.doFetch(
|
||||
`${this.getChannelRoute(channelId)}/pinned`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
markPostAsUnread = async (userId: string, postId: string) => {
|
||||
analytics.trackAPI('api_post_set_unread_post');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userId)}/posts/${postId}/set_unread`,
|
||||
{method: 'post'},
|
||||
);
|
||||
}
|
||||
|
||||
pinPost = async (postId: string) => {
|
||||
analytics.trackAPI('api_posts_pin');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(postId)}/pin`,
|
||||
{method: 'post'},
|
||||
);
|
||||
};
|
||||
|
||||
unpinPost = async (postId: string) => {
|
||||
analytics.trackAPI('api_posts_unpin');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(postId)}/unpin`,
|
||||
{method: 'post'},
|
||||
);
|
||||
};
|
||||
|
||||
addReaction = async (userId: string, postId: string, emojiName: string) => {
|
||||
analytics.trackAPI('api_reactions_save', {post_id: postId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getReactionsRoute()}`,
|
||||
{method: 'post', body: JSON.stringify({user_id: userId, post_id: postId, emoji_name: emojiName})},
|
||||
);
|
||||
};
|
||||
|
||||
removeReaction = async (userId: string, postId: string, emojiName: string) => {
|
||||
analytics.trackAPI('api_reactions_delete', {post_id: postId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userId)}/posts/${postId}/reactions/${emojiName}`,
|
||||
{method: 'delete'},
|
||||
);
|
||||
};
|
||||
|
||||
getReactionsForPost = async (postId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(postId)}/reactions`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
searchPostsWithParams = async (teamId: string, params: any) => {
|
||||
analytics.trackAPI('api_posts_search', {team_id: teamId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/posts/search`,
|
||||
{method: 'post', body: JSON.stringify(params)},
|
||||
);
|
||||
};
|
||||
|
||||
searchPosts = async (teamId: string, terms: string, isOrSearch: boolean) => {
|
||||
return this.searchPostsWithParams(teamId, {terms, is_or_search: isOrSearch});
|
||||
};
|
||||
|
||||
doPostAction = async (postId: string, actionId: string, selectedOption = '') => {
|
||||
return this.doPostActionWithCookie(postId, actionId, '', selectedOption);
|
||||
};
|
||||
|
||||
doPostActionWithCookie = async (postId: string, actionId: string, actionCookie: string, selectedOption = '') => {
|
||||
if (selectedOption) {
|
||||
analytics.trackAPI('api_interactive_messages_menu_selected');
|
||||
} else {
|
||||
analytics.trackAPI('api_interactive_messages_button_clicked');
|
||||
}
|
||||
|
||||
const msg: any = {
|
||||
selected_option: selectedOption,
|
||||
};
|
||||
if (actionCookie !== '') {
|
||||
msg.cookie = actionCookie;
|
||||
}
|
||||
return this.doFetch(
|
||||
`${this.getPostRoute(postId)}/actions/${encodeURIComponent(actionId)}`,
|
||||
{method: 'post', body: JSON.stringify(msg)},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientPosts;
|
||||
35
app/client/rest/preferences.ts
Normal file
35
app/client/rest/preferences.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {PreferenceType} from '@mm-redux/types/preferences';
|
||||
|
||||
export interface ClientPreferencesMix {
|
||||
savePreferences: (userId: string, preferences: PreferenceType[]) => Promise<any>;
|
||||
deletePreferences: (userId: string, preferences: PreferenceType[]) => Promise<any>;
|
||||
getMyPreferences: () => Promise<PreferenceType>;
|
||||
}
|
||||
|
||||
const ClientPreferences = (superclass: any) => class extends superclass {
|
||||
savePreferences = async (userId: string, preferences: PreferenceType[]) => {
|
||||
return this.doFetch(
|
||||
`${this.getPreferencesRoute(userId)}`,
|
||||
{method: 'put', body: JSON.stringify(preferences)},
|
||||
);
|
||||
};
|
||||
|
||||
getMyPreferences = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getPreferencesRoute('me')}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
deletePreferences = async (userId: string, preferences: PreferenceType[]) => {
|
||||
return this.doFetch(
|
||||
`${this.getPreferencesRoute(userId)}/delete`,
|
||||
{method: 'post', body: JSON.stringify(preferences)},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientPreferences;
|
||||
177
app/client/rest/teams.ts
Normal file
177
app/client/rest/teams.ts
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {analytics} from '@init/analytics';
|
||||
import {Team, TeamMembership, TeamUnread} from '@mm-redux/types/teams';
|
||||
import {buildQueryString} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {PER_PAGE_DEFAULT} from './constants';
|
||||
|
||||
export interface ClientTeamsMix {
|
||||
createTeam: (team: Team) => Promise<Team>;
|
||||
deleteTeam: (teamId: string) => Promise<any>;
|
||||
updateTeam: (team: Team) => Promise<Team>;
|
||||
patchTeam: (team: Partial<Team> & {id: string}) => Promise<Team>;
|
||||
getTeams: (page?: number, perPage?: number, includeTotalCount?: boolean) => Promise<any>;
|
||||
getTeam: (teamId: string) => Promise<Team>;
|
||||
getTeamByName: (teamName: string) => Promise<Team>;
|
||||
getMyTeams: () => Promise<Team[]>;
|
||||
getTeamsForUser: (userId: string) => Promise<Team[]>;
|
||||
getMyTeamMembers: () => Promise<TeamMembership[]>;
|
||||
getMyTeamUnreads: () => Promise<TeamUnread[]>;
|
||||
getTeamMembers: (teamId: string, page?: number, perPage?: number) => Promise<TeamMembership[]>;
|
||||
getTeamMember: (teamId: string, userId: string) => Promise<TeamMembership>;
|
||||
addToTeam: (teamId: string, userId: string) => Promise<TeamMembership>;
|
||||
joinTeam: (inviteId: string) => Promise<TeamMembership>;
|
||||
removeFromTeam: (teamId: string, userId: string) => Promise<any>;
|
||||
getTeamStats: (teamId: string) => Promise<any>;
|
||||
getTeamIconUrl: (teamId: string, lastTeamIconUpdate: number) => string;
|
||||
}
|
||||
|
||||
const ClientTeams = (superclass: any) => class extends superclass {
|
||||
createTeam = async (team: Team) => {
|
||||
analytics.trackAPI('api_teams_create');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getTeamsRoute()}`,
|
||||
{method: 'post', body: JSON.stringify(team)},
|
||||
);
|
||||
};
|
||||
|
||||
deleteTeam = async (teamId: string) => {
|
||||
analytics.trackAPI('api_teams_delete');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}`,
|
||||
{method: 'delete'},
|
||||
);
|
||||
};
|
||||
|
||||
updateTeam = async (team: Team) => {
|
||||
analytics.trackAPI('api_teams_update_name', {team_id: team.id});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(team.id)}`,
|
||||
{method: 'put', body: JSON.stringify(team)},
|
||||
);
|
||||
};
|
||||
|
||||
patchTeam = async (team: Partial<Team> & {id: string}) => {
|
||||
analytics.trackAPI('api_teams_patch_name', {team_id: team.id});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(team.id)}/patch`,
|
||||
{method: 'put', body: JSON.stringify(team)},
|
||||
);
|
||||
};
|
||||
|
||||
getTeams = async (page = 0, perPage = PER_PAGE_DEFAULT, includeTotalCount = false) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamsRoute()}${buildQueryString({page, per_page: perPage, include_total_count: includeTotalCount})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getTeam = async (teamId: string) => {
|
||||
return this.doFetch(
|
||||
this.getTeamRoute(teamId),
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getTeamByName = async (teamName: string) => {
|
||||
analytics.trackAPI('api_teams_get_team_by_name');
|
||||
|
||||
return this.doFetch(
|
||||
this.getTeamNameRoute(teamName),
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getMyTeams = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute('me')}/teams`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getTeamsForUser = async (userId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userId)}/teams`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getMyTeamMembers = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute('me')}/teams/members`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getMyTeamUnreads = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute('me')}/teams/unread`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getTeamMembers = async (teamId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamMembersRoute(teamId)}${buildQueryString({page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getTeamMember = async (teamId: string, userId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamMemberRoute(teamId, userId)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
addToTeam = async (teamId: string, userId: string) => {
|
||||
analytics.trackAPI('api_teams_invite_members', {team_id: teamId});
|
||||
|
||||
const member = {user_id: userId, team_id: teamId};
|
||||
return this.doFetch(
|
||||
`${this.getTeamMembersRoute(teamId)}`,
|
||||
{method: 'post', body: JSON.stringify(member)},
|
||||
);
|
||||
};
|
||||
|
||||
joinTeam = async (inviteId: string) => {
|
||||
const query = buildQueryString({invite_id: inviteId});
|
||||
return this.doFetch(
|
||||
`${this.getTeamsRoute()}/members/invite${query}`,
|
||||
{method: 'post'},
|
||||
);
|
||||
};
|
||||
|
||||
removeFromTeam = async (teamId: string, userId: string) => {
|
||||
analytics.trackAPI('api_teams_remove_members', {team_id: teamId});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getTeamMemberRoute(teamId, userId)}`,
|
||||
{method: 'delete'},
|
||||
);
|
||||
};
|
||||
|
||||
getTeamStats = async (teamId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getTeamRoute(teamId)}/stats`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getTeamIconUrl = (teamId: string, lastTeamIconUpdate: number) => {
|
||||
const params: any = {};
|
||||
if (lastTeamIconUpdate) {
|
||||
params._ = lastTeamIconUpdate;
|
||||
}
|
||||
|
||||
return `${this.getTeamRoute(teamId)}/image${buildQueryString(params)}`;
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientTeams;
|
||||
25
app/client/rest/tos.ts
Normal file
25
app/client/rest/tos.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export interface ClientTosMix {
|
||||
updateMyTermsOfServiceStatus: (termsOfServiceId: string, accepted: boolean) => Promise<any>;
|
||||
getTermsOfService: () => Promise<any>;
|
||||
}
|
||||
|
||||
const ClientTos = (superclass: any) => class extends superclass {
|
||||
updateMyTermsOfServiceStatus = async (termsOfServiceId: string, accepted: boolean) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute('me')}/terms_of_service`,
|
||||
{method: 'post', body: JSON.stringify({termsOfServiceId, accepted})},
|
||||
);
|
||||
}
|
||||
|
||||
getTermsOfService = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/terms_of_service`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ClientTos;
|
||||
398
app/client/rest/users.ts
Normal file
398
app/client/rest/users.ts
Normal file
|
|
@ -0,0 +1,398 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {analytics} from '@init/analytics';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import {UserProfile, UserStatus} from '@mm-redux/types/users';
|
||||
import {buildQueryString, isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {PER_PAGE_DEFAULT} from './constants';
|
||||
|
||||
export interface ClientUsersMix {
|
||||
createUser: (user: UserProfile, token: string, inviteId: string) => Promise<UserProfile>;
|
||||
patchMe: (userPatch: Partial<UserProfile>) => Promise<UserProfile>;
|
||||
patchUser: (userPatch: Partial<UserProfile> & {id: string}) => Promise<UserProfile>;
|
||||
updateUser: (user: UserProfile) => Promise<UserProfile>;
|
||||
demoteUserToGuest: (userId: string) => Promise<any>;
|
||||
getKnownUsers: () => Promise<string[]>;
|
||||
sendPasswordResetEmail: (email: string) => Promise<any>;
|
||||
setDefaultProfileImage: (userId: string) => Promise<any>;
|
||||
login: (loginId: string, password: string, token?: string, deviceId?: string, ldapOnly?: boolean) => Promise<UserProfile>;
|
||||
loginById: (id: string, password: string, token?: string, deviceId?: string) => Promise<UserProfile>;
|
||||
logout: () => Promise<any>;
|
||||
getProfiles: (page?: number, perPage?: number, options?: Record<string, any>) => Promise<UserProfile[]>;
|
||||
getProfilesByIds: (userIds: string[], options?: Record<string, any>) => Promise<UserProfile[]>;
|
||||
getProfilesByUsernames: (usernames: string[]) => Promise<UserProfile[]>;
|
||||
getProfilesInTeam: (teamId: string, page?: number, perPage?: number, sort?: string, options?: Record<string, any>) => Promise<UserProfile[]>;
|
||||
getProfilesNotInTeam: (teamId: string, groupConstrained: boolean, page?: number, perPage?: number) => Promise<UserProfile[]>;
|
||||
getProfilesWithoutTeam: (page?: number, perPage?: number, options?: Record<string, any>) => Promise<UserProfile[]>;
|
||||
getProfilesInChannel: (channelId: string, page?: number, perPage?: number, sort?: string) => Promise<UserProfile[]>;
|
||||
getProfilesInGroupChannels: (channelsIds: string[]) => Promise<{[x: string]: UserProfile[]}>;
|
||||
getProfilesNotInChannel: (teamId: string, channelId: string, groupConstrained: boolean, page?: number, perPage?: number) => Promise<UserProfile[]>;
|
||||
getMe: () => Promise<UserProfile>;
|
||||
getUser: (userId: string) => Promise<UserProfile>;
|
||||
getUserByUsername: (username: string) => Promise<UserProfile>;
|
||||
getUserByEmail: (email: string) => Promise<UserProfile>;
|
||||
getProfilePictureUrl: (userId: string, lastPictureUpdate: number) => string;
|
||||
getDefaultProfilePictureUrl: (userId: string) => string;
|
||||
autocompleteUsers: (name: string, teamId: string, channelId: string, options?: Record<string, any>) => Promise<{users: UserProfile[], out_of_channel?: UserProfile[]}>;
|
||||
getSessions: (userId: string) => Promise<any>;
|
||||
checkUserMfa: (loginId: string) => Promise<{mfa_required: boolean}>;
|
||||
attachDevice: (deviceId: string) => Promise<any>;
|
||||
searchUsers: (term: string, options: any) => Promise<UserProfile[]>;
|
||||
getStatusesByIds: (userIds: string[]) => Promise<UserStatus[]>;
|
||||
getStatus: (userId: string) => Promise<UserStatus>;
|
||||
updateStatus: (status: UserStatus) => Promise<UserStatus>;
|
||||
}
|
||||
|
||||
const ClientUsers = (superclass: any) => class extends superclass {
|
||||
createUser = async (user: UserProfile, token: string, inviteId: string) => {
|
||||
analytics.trackAPI('api_users_create');
|
||||
|
||||
const queryParams: any = {};
|
||||
|
||||
if (token) {
|
||||
queryParams.t = token;
|
||||
}
|
||||
|
||||
if (inviteId) {
|
||||
queryParams.iid = inviteId;
|
||||
}
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}${buildQueryString(queryParams)}`,
|
||||
{method: 'post', body: JSON.stringify(user)},
|
||||
);
|
||||
}
|
||||
|
||||
patchMe = async (userPatch: Partial<UserProfile>) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute('me')}/patch`,
|
||||
{method: 'put', body: JSON.stringify(userPatch)},
|
||||
);
|
||||
}
|
||||
|
||||
patchUser = async (userPatch: Partial<UserProfile> & {id: string}) => {
|
||||
analytics.trackAPI('api_users_patch');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userPatch.id)}/patch`,
|
||||
{method: 'put', body: JSON.stringify(userPatch)},
|
||||
);
|
||||
}
|
||||
|
||||
updateUser = async (user: UserProfile) => {
|
||||
analytics.trackAPI('api_users_update');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(user.id)}`,
|
||||
{method: 'put', body: JSON.stringify(user)},
|
||||
);
|
||||
}
|
||||
|
||||
demoteUserToGuest = async (userId: string) => {
|
||||
analytics.trackAPI('api_users_demote_user_to_guest');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userId)}/demote`,
|
||||
{method: 'post'},
|
||||
);
|
||||
}
|
||||
|
||||
getKnownUsers = async () => {
|
||||
analytics.trackAPI('api_get_known_users');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/known`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
|
||||
sendPasswordResetEmail = async (email: string) => {
|
||||
analytics.trackAPI('api_users_send_password_reset');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/password/reset/send`,
|
||||
{method: 'post', body: JSON.stringify({email})},
|
||||
);
|
||||
}
|
||||
|
||||
setDefaultProfileImage = async (userId: string) => {
|
||||
analytics.trackAPI('api_users_set_default_profile_picture');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userId)}/image`,
|
||||
{method: 'delete'},
|
||||
);
|
||||
};
|
||||
|
||||
login = async (loginId: string, password: string, token = '', deviceId = '', ldapOnly = false) => {
|
||||
analytics.trackAPI('api_users_login');
|
||||
|
||||
if (ldapOnly) {
|
||||
analytics.trackAPI('api_users_login_ldap');
|
||||
}
|
||||
|
||||
const body: any = {
|
||||
device_id: deviceId,
|
||||
login_id: loginId,
|
||||
password,
|
||||
token,
|
||||
};
|
||||
|
||||
if (ldapOnly) {
|
||||
body.ldap_only = 'true';
|
||||
}
|
||||
|
||||
const {data} = await this.doFetchWithResponse(
|
||||
`${this.getUsersRoute()}/login`,
|
||||
{
|
||||
method: 'post',
|
||||
body: JSON.stringify(body),
|
||||
headers: {'Cache-Control': 'no-store'},
|
||||
},
|
||||
);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
loginById = async (id: string, password: string, token = '', deviceId = '') => {
|
||||
analytics.trackAPI('api_users_login');
|
||||
const body: any = {
|
||||
device_id: deviceId,
|
||||
id,
|
||||
password,
|
||||
token,
|
||||
};
|
||||
|
||||
const {data} = await this.doFetchWithResponse(
|
||||
`${this.getUsersRoute()}/login`,
|
||||
{method: 'post', body: JSON.stringify(body)},
|
||||
);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
logout = async () => {
|
||||
analytics.trackAPI('api_users_logout');
|
||||
|
||||
const {response} = await this.doFetchWithResponse(
|
||||
`${this.getUsersRoute()}/logout`,
|
||||
{method: 'post'},
|
||||
);
|
||||
|
||||
if (response.ok) {
|
||||
this.token = '';
|
||||
}
|
||||
|
||||
this.serverVersion = '';
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
getProfiles = async (page = 0, perPage = PER_PAGE_DEFAULT, options = {}) => {
|
||||
analytics.trackAPI('api_profiles_get');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}${buildQueryString({page, per_page: perPage, ...options})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getProfilesByIds = async (userIds: string[], options = {}) => {
|
||||
analytics.trackAPI('api_profiles_get_by_ids');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/ids${buildQueryString(options)}`,
|
||||
{method: 'post', body: JSON.stringify(userIds)},
|
||||
);
|
||||
};
|
||||
|
||||
getProfilesByUsernames = async (usernames: string[]) => {
|
||||
analytics.trackAPI('api_profiles_get_by_usernames');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/usernames`,
|
||||
{method: 'post', body: JSON.stringify(usernames)},
|
||||
);
|
||||
};
|
||||
|
||||
getProfilesInTeam = async (teamId: string, page = 0, perPage = PER_PAGE_DEFAULT, sort = '', options = {}) => {
|
||||
analytics.trackAPI('api_profiles_get_in_team', {team_id: teamId, sort});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}${buildQueryString({...options, in_team: teamId, page, per_page: perPage, sort})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getProfilesNotInTeam = async (teamId: string, groupConstrained: boolean, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
analytics.trackAPI('api_profiles_get_not_in_team', {team_id: teamId, group_constrained: groupConstrained});
|
||||
|
||||
const queryStringObj: any = {not_in_team: teamId, page, per_page: perPage};
|
||||
if (groupConstrained) {
|
||||
queryStringObj.group_constrained = true;
|
||||
}
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}${buildQueryString(queryStringObj)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getProfilesWithoutTeam = async (page = 0, perPage = PER_PAGE_DEFAULT, options = {}) => {
|
||||
analytics.trackAPI('api_profiles_get_without_team');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}${buildQueryString({...options, without_team: 1, page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getProfilesInChannel = async (channelId: string, page = 0, perPage = PER_PAGE_DEFAULT, sort = '') => {
|
||||
analytics.trackAPI('api_profiles_get_in_channel', {channel_id: channelId});
|
||||
|
||||
const serverVersion = this.getServerVersion();
|
||||
let queryStringObj;
|
||||
if (isMinimumServerVersion(serverVersion, 4, 7)) {
|
||||
queryStringObj = {in_channel: channelId, page, per_page: perPage, sort};
|
||||
} else {
|
||||
queryStringObj = {in_channel: channelId, page, per_page: perPage};
|
||||
}
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}${buildQueryString(queryStringObj)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getProfilesInGroupChannels = async (channelsIds: string[]) => {
|
||||
analytics.trackAPI('api_profiles_get_in_group_channels', {channelsIds});
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/group_channels`,
|
||||
{method: 'post', body: JSON.stringify(channelsIds)},
|
||||
);
|
||||
};
|
||||
|
||||
getProfilesNotInChannel = async (teamId: string, channelId: string, groupConstrained: boolean, page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
analytics.trackAPI('api_profiles_get_not_in_channel', {team_id: teamId, channel_id: channelId, group_constrained: groupConstrained});
|
||||
|
||||
const queryStringObj: any = {in_team: teamId, not_in_channel: channelId, page, per_page: perPage};
|
||||
if (groupConstrained) {
|
||||
queryStringObj.group_constrained = true;
|
||||
}
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}${buildQueryString(queryStringObj)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getMe = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute('me')}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getUser = async (userId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userId)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getUserByUsername = async (username: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/username/${username}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getUserByEmail = async (email: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/email/${email}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
getProfilePictureUrl = (userId: string, lastPictureUpdate: number) => {
|
||||
const params: any = {};
|
||||
|
||||
if (lastPictureUpdate) {
|
||||
params._ = lastPictureUpdate;
|
||||
}
|
||||
|
||||
return `${this.getUserRoute(userId)}/image${buildQueryString(params)}`;
|
||||
};
|
||||
|
||||
getDefaultProfilePictureUrl = (userId: string) => {
|
||||
return `${this.getUserRoute(userId)}/image/default`;
|
||||
};
|
||||
|
||||
autocompleteUsers = async (name: string, teamId: string, channelId: string, options = {
|
||||
limit: General.AUTOCOMPLETE_LIMIT_DEFAULT,
|
||||
}) => {
|
||||
return this.doFetch(`${this.getUsersRoute()}/autocomplete${buildQueryString({
|
||||
in_team: teamId,
|
||||
in_channel: channelId,
|
||||
name,
|
||||
limit: options.limit,
|
||||
})}`, {
|
||||
method: 'get',
|
||||
});
|
||||
};
|
||||
|
||||
getSessions = async (userId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userId)}/sessions`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
checkUserMfa = async (loginId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/mfa`,
|
||||
{method: 'post', body: JSON.stringify({login_id: loginId})},
|
||||
);
|
||||
};
|
||||
|
||||
attachDevice = async (deviceId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/sessions/device`,
|
||||
{method: 'put', body: JSON.stringify({device_id: deviceId})},
|
||||
);
|
||||
};
|
||||
|
||||
searchUsers = async (term: string, options: any) => {
|
||||
analytics.trackAPI('api_search_users');
|
||||
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/search`,
|
||||
{method: 'post', body: JSON.stringify({term, ...options})},
|
||||
);
|
||||
};
|
||||
|
||||
getStatusesByIds = async (userIds: string[]) => {
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/status/ids`,
|
||||
{method: 'post', body: JSON.stringify(userIds)},
|
||||
);
|
||||
};
|
||||
|
||||
getStatus = async (userId: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(userId)}/status`,
|
||||
{method: 'get'},
|
||||
);
|
||||
};
|
||||
|
||||
updateStatus = async (status: UserStatus) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute(status.user_id)}/status`,
|
||||
{method: 'put', body: JSON.stringify(status)},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientUsers;
|
||||
|
|
@ -6,7 +6,7 @@ export {thunk};
|
|||
const configureStore = require('redux-mock-store').default;
|
||||
export {configureStore};
|
||||
|
||||
export {Client4} from '@mm-redux/client';
|
||||
export {Client4} from '@client/rest';
|
||||
|
||||
export type {AppBinding, AppForm} from '@mm-redux/types/apps';
|
||||
export {AppFieldTypes} from '@mm-redux/constants/apps';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
} from 'react-native';
|
||||
|
||||
import {analytics} from '@init/analytics';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {Command, AutocompleteSuggestion, CommandArgs} from '@mm-redux/types/integrations';
|
||||
import {Theme} from '@mm-redux/types/preferences';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {connect} from 'react-redux';
|
|||
import {getCustomEmojisByName} from '@mm-redux/selectors/entities/emojis';
|
||||
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {BuiltInEmojis, EmojiIndicesByAlias, Emojis} from 'app/utils/emojis';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
} from 'react-native';
|
||||
|
||||
import ProgressiveImage from '@components/progressive_image';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {changeOpacity} from '@utils/theme';
|
||||
|
||||
import FileAttachmentIcon from './file_attachment_icon';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import FileAttachmentImage from './file_attachment_image.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
|
|||
import {StyleSheet, View, DeviceEventEmitter} from 'react-native';
|
||||
|
||||
import ImageViewPort from '@components/image_viewport';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {isDocument, isGif, isImage, isVideo} from '@utils/file';
|
||||
import {getViewPortWidth, openGalleryAtIndex} from '@utils/images';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
|
|||
import {StyleSheet, TouchableOpacity, View} from 'react-native';
|
||||
import RNFetchBlob from 'rn-fetch-blob';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import mattermostBucket from 'app/mattermost_bucket';
|
||||
import FileAttachmentImage from '@components/file_attachment_list/file_attachment_image';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import {connect} from 'react-redux';
|
||||
|
||||
import {isSystemMessage} from '@mm-redux/utils/post_utils';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
|
|||
import {Platform, View} from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import UserStatus from '@components/user_status';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import {t} from 'app/utils/i18n';
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Preferences from '@mm-redux/constants/preferences';
|
|||
|
||||
import ProfilePictureButton from './profile_picture_button.js';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
describe('profile_picture_button', () => {
|
||||
const baseProps = {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
|
|||
import {IntlProvider} from 'react-intl';
|
||||
import {Platform} from 'react-native';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
|
||||
import {resetToTeams} from 'app/actions/navigation';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
|
|||
import {Text, View} from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import {makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import * as KeyChain from 'react-native-keychain';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import mattermostManaged from 'app/mattermost_managed';
|
||||
import EphemeralStore from 'app/store/ephemeral_store';
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ import RNFetchBlob from 'rn-fetch-blob';
|
|||
import urlParse from 'url-parse';
|
||||
|
||||
import LocalConfig from '@assets/config';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {ClientError, HEADER_X_VERSION_ID} from '@mm-redux/client/client4';
|
||||
import {Client4} from '@client/rest';
|
||||
import {HEADER_TOKEN, HEADER_X_CLUSTER_ID, HEADER_X_VERSION_ID} from '@client/rest/constants';
|
||||
import ClientError from '@client/rest/error';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import {t} from '@utils/i18n';
|
||||
|
|
@ -18,8 +19,6 @@ import mattermostManaged from 'app/mattermost_managed';
|
|||
|
||||
/* eslint-disable no-throw-literal */
|
||||
|
||||
export const HEADER_X_CLUSTER_ID = 'X-Cluster-Id';
|
||||
export const HEADER_TOKEN = 'Token';
|
||||
const DEFAULT_TIMEOUT = 10000;
|
||||
|
||||
let managedConfig;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {HEADER_X_VERSION_ID} from '@mm-redux/client/client4';
|
||||
import '@init/fetch';
|
||||
import {Client4} from '@client/rest';
|
||||
import {HEADER_X_CLUSTER_ID, HEADER_X_VERSION_ID, HEADER_TOKEN} from '@client/rest/constants';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import {General} from '@mm-redux/constants';
|
||||
|
||||
import {
|
||||
HEADER_X_CLUSTER_ID,
|
||||
HEADER_TOKEN,
|
||||
} from 'app/init/fetch';
|
||||
|
||||
describe('Fetch', () => {
|
||||
beforeAll(() => {
|
||||
global.fetch = jest.fn(() => Promise.resolve());
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import {setAppState, setServerVersion} from '@mm-redux/actions/general';
|
|||
import {getTeams} from '@mm-redux/actions/teams';
|
||||
import {autoUpdateTimezone} from '@mm-redux/actions/timezone';
|
||||
import {close as closeWebSocket} from '@actions/websocket';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {getCurrentChannelId} from '@mm-redux/selectors/entities/channels';
|
||||
|
|
|
|||
|
|
@ -71,13 +71,6 @@ export default keyMirror({
|
|||
INCREMENT_UNREAD_MENTION_COUNT: null,
|
||||
DECREMENT_UNREAD_MENTION_COUNT: null,
|
||||
|
||||
UPDATED_CHANNEL_SCHEME: null,
|
||||
UPDATED_CHANNEL_MEMBER_SCHEME_ROLES: null,
|
||||
|
||||
RECEIVED_CHANNEL_MEMBERS_MINUS_GROUP_MEMBERS: null,
|
||||
|
||||
RECEIVED_CHANNEL_MODERATIONS: null,
|
||||
|
||||
RECEIVED_CHANNEL_MEMBER_COUNTS_BY_GROUP: null,
|
||||
|
||||
RECEIVED_TOTAL_CHANNEL_COUNT: null,
|
||||
|
|
|
|||
|
|
@ -12,10 +12,8 @@ import PreferenceTypes from './preferences';
|
|||
import IntegrationTypes from './integrations';
|
||||
import EmojiTypes from './emojis';
|
||||
import GifTypes from './gifs';
|
||||
import JobTypes from './jobs';
|
||||
import SearchTypes from './search';
|
||||
import RoleTypes from './roles';
|
||||
import SchemeTypes from './schemes';
|
||||
import GroupTypes from './groups';
|
||||
import BotTypes from './bots';
|
||||
import PluginTypes from './plugins';
|
||||
|
|
@ -34,10 +32,8 @@ export {
|
|||
IntegrationTypes,
|
||||
EmojiTypes,
|
||||
GifTypes,
|
||||
JobTypes,
|
||||
SearchTypes,
|
||||
RoleTypes,
|
||||
SchemeTypes,
|
||||
GroupTypes,
|
||||
BotTypes,
|
||||
PluginTypes,
|
||||
|
|
|
|||
|
|
@ -4,22 +4,12 @@ import keyMirror from '@mm-redux/utils/key_mirror';
|
|||
|
||||
export default keyMirror({
|
||||
|
||||
RECEIVED_INCOMING_HOOK: null,
|
||||
RECEIVED_INCOMING_HOOKS: null,
|
||||
DELETED_INCOMING_HOOK: null,
|
||||
RECEIVED_OUTGOING_HOOK: null,
|
||||
RECEIVED_OUTGOING_HOOKS: null,
|
||||
DELETED_OUTGOING_HOOK: null,
|
||||
RECEIVED_CUSTOM_TEAM_COMMANDS: null,
|
||||
RECEIVED_COMMAND: null,
|
||||
RECEIVED_COMMANDS: null,
|
||||
RECEIVED_COMMAND_SUGGESTIONS: null,
|
||||
RECEIVED_COMMAND_SUGGESTIONS_FAILURE: null,
|
||||
RECEIVED_COMMAND_TOKEN: null,
|
||||
DELETED_COMMAND: null,
|
||||
RECEIVED_OAUTH_APP: null,
|
||||
RECEIVED_OAUTH_APPS: null,
|
||||
DELETED_OAUTH_APP: null,
|
||||
|
||||
RECEIVED_DIALOG_TRIGGER_ID: null,
|
||||
RECEIVED_DIALOG: null,
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import keyMirror from '@mm-redux/utils/key_mirror';
|
||||
|
||||
export default keyMirror({
|
||||
CREATE_JOB_REQUEST: null,
|
||||
CREATE_JOB_SUCCESS: null,
|
||||
CREATE_JOB_FAILURE: null,
|
||||
|
||||
CANCEL_JOB_REQUEST: null,
|
||||
CANCEL_JOB_SUCCESS: null,
|
||||
CANCEL_JOB_FAILURE: null,
|
||||
|
||||
GET_JOB_REQUEST: null,
|
||||
GET_JOB_SUCCESS: null,
|
||||
GET_JOB_FAILURE: null,
|
||||
|
||||
GET_JOBS_REQUEST: null,
|
||||
GET_JOBS_SUCCESS: null,
|
||||
GET_JOBS_FAILURE: null,
|
||||
|
||||
RECEIVED_JOB: null,
|
||||
RECEIVED_JOBS: null,
|
||||
RECEIVED_JOBS_BY_TYPE: null,
|
||||
});
|
||||
|
|
@ -7,18 +7,6 @@ export default keyMirror({
|
|||
ROLES_BY_NAMES_SUCCESS: null,
|
||||
ROLES_BY_NAMES_FAILURE: null,
|
||||
|
||||
ROLE_BY_NAME_REQUEST: null,
|
||||
ROLE_BY_NAME_SUCCESS: null,
|
||||
ROLE_BY_NAME_FAILURE: null,
|
||||
|
||||
ROLE_BY_ID_REQUEST: null,
|
||||
ROLE_BY_ID_SUCCESS: null,
|
||||
ROLE_BY_ID_FAILURE: null,
|
||||
|
||||
EDIT_ROLE_REQUEST: null,
|
||||
EDIT_ROLE_SUCCESS: null,
|
||||
EDIT_ROLE_FAILURE: null,
|
||||
|
||||
RECEIVED_ROLES: null,
|
||||
RECEIVED_ROLE: null,
|
||||
ROLE_DELETED: null,
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import keyMirror from '@mm-redux/utils/key_mirror';
|
||||
|
||||
export default keyMirror({
|
||||
RECEIVED_SCHEME: null,
|
||||
|
||||
RECEIVED_SCHEMES: null,
|
||||
|
||||
CREATED_SCHEME: null,
|
||||
|
||||
DELETED_SCHEME: null,
|
||||
|
||||
PATCHED_SCHEME: null,
|
||||
|
||||
RECEIVED_SCHEME_TEAMS: null,
|
||||
|
||||
RECEIVED_SCHEME_CHANNELS: null,
|
||||
});
|
||||
|
|
@ -16,10 +16,6 @@ export default keyMirror({
|
|||
CREATE_TEAM_SUCCESS: null,
|
||||
CREATE_TEAM_FAILURE: null,
|
||||
|
||||
GET_TEAM_MEMBERS_REQUEST: null,
|
||||
GET_TEAM_MEMBERS_SUCCESS: null,
|
||||
GET_TEAM_MEMBERS_FAILURE: null,
|
||||
|
||||
JOIN_TEAM_REQUEST: null,
|
||||
JOIN_TEAM_SUCCESS: null,
|
||||
JOIN_TEAM_FAILURE: null,
|
||||
|
|
@ -50,10 +46,6 @@ export default keyMirror({
|
|||
RECEIVED_TEAM_STATS: null,
|
||||
RECEIVED_MY_TEAM_UNREADS: null,
|
||||
LEAVE_TEAM: null,
|
||||
UPDATED_TEAM_SCHEME: null,
|
||||
UPDATED_TEAM_MEMBER_SCHEME_ROLES: null,
|
||||
|
||||
RECEIVED_TEAM_MEMBERS_MINUS_GROUP_MEMBERS: null,
|
||||
|
||||
RECEIVED_TOTAL_TEAM_COUNT: null,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ export default keyMirror({
|
|||
RECEIVED_PROFILE_NOT_IN_CHANNEL: null,
|
||||
RECEIVED_SESSIONS: null,
|
||||
RECEIVED_REVOKED_SESSION: null,
|
||||
RECEIVED_AUDITS: null,
|
||||
RECEIVED_STATUS: null,
|
||||
RECEIVED_STATUSES: null,
|
||||
RECEIVED_AUTOCOMPLETE_IN_CHANNEL: null,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {AppsTypes} from '@mm-redux/action_types';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import {ActionFunc} from '@mm-redux/types/actions';
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import assert from 'assert';
|
|||
import nock from 'nock';
|
||||
|
||||
import * as BotActions from '@mm-redux/actions/bots';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
|
@ -51,82 +51,4 @@ describe('Actions.Bots', () => {
|
|||
const botsResult = state.entities.bots.accounts[bot.user_id];
|
||||
assert.equal(bot.username, botsResult.username);
|
||||
});
|
||||
|
||||
it('createBot', async () => {
|
||||
const bot = TestHelper.fakeBot();
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/bots').
|
||||
reply(200, bot);
|
||||
await store.dispatch(BotActions.createBot(bot));
|
||||
|
||||
const state = store.getState();
|
||||
const botsResult = state.entities.bots.accounts[bot.user_id];
|
||||
assert.equal(bot.username, botsResult.username);
|
||||
});
|
||||
|
||||
it('patchBot', async () => {
|
||||
const bot = TestHelper.fakeBot();
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/bots').
|
||||
reply(200, bot);
|
||||
await store.dispatch(BotActions.createBot(bot));
|
||||
|
||||
bot.username = 'mynewusername';
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/bots/${bot.user_id}`).
|
||||
reply(200, bot);
|
||||
await store.dispatch(BotActions.patchBot(bot.user_id, bot));
|
||||
|
||||
const state = store.getState();
|
||||
const botsResult = state.entities.bots.accounts[bot.user_id];
|
||||
assert.equal(bot.username, botsResult.username);
|
||||
});
|
||||
|
||||
it('disableBot', async () => {
|
||||
const bot = TestHelper.fakeBot();
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/bots').
|
||||
reply(200, bot);
|
||||
await store.dispatch(BotActions.createBot(bot));
|
||||
|
||||
// Disable the bot by setting delete_at to a value > 0
|
||||
bot.delete_at = 1507840900065;
|
||||
nock(Client4.getBotRoute(bot.user_id)).
|
||||
post('/disable').
|
||||
reply(200, bot);
|
||||
await store.dispatch(BotActions.disableBot(bot.user_id));
|
||||
|
||||
const state = store.getState();
|
||||
const botsResult = state.entities.bots.accounts[bot.user_id];
|
||||
assert.equal(bot.delete_at, botsResult.delete_at);
|
||||
|
||||
bot.delete_at = 0;
|
||||
nock(Client4.getBotRoute(bot.user_id)).
|
||||
post('/enable').
|
||||
reply(200, bot);
|
||||
await store.dispatch(BotActions.enableBot(bot.user_id));
|
||||
|
||||
const state2 = store.getState();
|
||||
const botsResult2 = state2.entities.bots.accounts[bot.user_id];
|
||||
assert.equal(bot.delete_at, botsResult2.delete_at);
|
||||
});
|
||||
|
||||
it('assignBot', async () => {
|
||||
const bot = TestHelper.fakeBot();
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/bots').
|
||||
reply(200, bot);
|
||||
await store.dispatch(BotActions.createBot(bot));
|
||||
|
||||
bot.owner_id = TestHelper.generateId();
|
||||
nock(Client4.getBotRoute(bot.user_id)).
|
||||
post('/assign/' + bot.owner_id).
|
||||
reply(200, bot);
|
||||
await store.dispatch(BotActions.assignBot(bot.user_id, bot.owner_id));
|
||||
|
||||
const state = store.getState();
|
||||
const botsResult = state.entities.bots.accounts[bot.user_id];
|
||||
assert.equal(bot.owner_id, botsResult.owner_id);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,36 +1,14 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {BotTypes} from '@mm-redux/action_types';
|
||||
import {bindClientFunc} from './helpers';
|
||||
|
||||
import {ActionFunc} from '@mm-redux/types/actions';
|
||||
import {Bot, BotPatch} from '@mm-redux/types/bots';
|
||||
|
||||
const BOTS_PER_PAGE_DEFAULT = 20;
|
||||
|
||||
export function createBot(bot: Bot): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.createBot,
|
||||
onSuccess: BotTypes.RECEIVED_BOT_ACCOUNT,
|
||||
params: [
|
||||
bot,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function patchBot(botUserId: string, botPatch: BotPatch): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.patchBot,
|
||||
onSuccess: BotTypes.RECEIVED_BOT_ACCOUNT,
|
||||
params: [
|
||||
botUserId,
|
||||
botPatch,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function loadBot(botUserId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getBot,
|
||||
|
|
@ -51,34 +29,3 @@ export function loadBots(page = 0, perPage = BOTS_PER_PAGE_DEFAULT): ActionFunc
|
|||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function disableBot(botUserId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.disableBot,
|
||||
onSuccess: BotTypes.RECEIVED_BOT_ACCOUNT,
|
||||
params: [
|
||||
botUserId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function enableBot(botUserId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.enableBot,
|
||||
onSuccess: BotTypes.RECEIVED_BOT_ACCOUNT,
|
||||
params: [
|
||||
botUserId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function assignBot(botUserId: string, newOwnerId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.assignBot,
|
||||
onSuccess: BotTypes.RECEIVED_BOT_ACCOUNT,
|
||||
params: [
|
||||
botUserId,
|
||||
newOwnerId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,9 @@ import assert from 'assert';
|
|||
import nock from 'nock';
|
||||
|
||||
import * as Actions from '@mm-redux/actions/channels';
|
||||
import {addUserToTeam} from '@mm-redux/actions/teams';
|
||||
import {getProfilesByIds, login} from '@mm-redux/actions/users';
|
||||
import {createIncomingHook, createOutgoingHook} from '@mm-redux/actions/integrations';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {General, RequestStatus, Preferences, Permissions} from '../constants';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General, RequestStatus, Preferences} from '../constants';
|
||||
import {getPreferenceKey} from '@mm-redux/utils/preference_utils';
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
|
@ -450,57 +448,11 @@ describe('Actions.Channels', () => {
|
|||
|
||||
await store.dispatch(Actions.fetchMyChannelsAndMembers(TestHelper.basicTeam.id));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/incoming').
|
||||
reply(201, {
|
||||
id: TestHelper.generateId(),
|
||||
create_at: 1507840900004,
|
||||
update_at: 1507840900004,
|
||||
delete_at: 0,
|
||||
user_id: TestHelper.basicUser.id,
|
||||
channel_id: secondChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'TestIncomingHook',
|
||||
description: 'Some description.',
|
||||
});
|
||||
const incomingHook = await store.dispatch(createIncomingHook({channel_id: secondChannel.id, display_name: 'test', description: 'test'}));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/outgoing').
|
||||
reply(201, {
|
||||
id: TestHelper.generateId(),
|
||||
token: TestHelper.generateId(),
|
||||
create_at: 1507841118796,
|
||||
update_at: 1507841118796,
|
||||
delete_at: 0,
|
||||
creator_id: TestHelper.basicUser.id,
|
||||
channel_id: secondChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
trigger_words: ['testword'],
|
||||
trigger_when: 0,
|
||||
callback_urls: ['http://notarealurl'],
|
||||
display_name: 'TestOutgoingHook',
|
||||
description: '',
|
||||
content_type: 'application/x-www-form-urlencoded',
|
||||
});
|
||||
const outgoingHook = await store.dispatch(createOutgoingHook({
|
||||
channel_id: secondChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'TestOutgoingHook',
|
||||
trigger_words: [TestHelper.generateId()],
|
||||
callback_urls: ['http://notarealurl']},
|
||||
));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
delete(`/channels/${secondChannel.id}`).
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await store.dispatch(Actions.deleteChannel(secondChannel.id));
|
||||
|
||||
const {incomingHooks, outgoingHooks} = store.getState().entities.integrations;
|
||||
|
||||
assert.ifError(incomingHooks[incomingHook.id]);
|
||||
assert.ifError(outgoingHooks[outgoingHook.id]);
|
||||
});
|
||||
|
||||
it('unarchiveChannel', async () => {
|
||||
|
|
@ -550,57 +502,11 @@ describe('Actions.Channels', () => {
|
|||
|
||||
await store.dispatch(Actions.fetchMyChannelsAndMembers(TestHelper.basicTeam.id));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/incoming').
|
||||
reply(201, {
|
||||
id: TestHelper.generateId(),
|
||||
create_at: 1507840900004,
|
||||
update_at: 1507840900004,
|
||||
delete_at: 1609090954545,
|
||||
user_id: TestHelper.basicUser.id,
|
||||
channel_id: secondChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'TestIncomingHook',
|
||||
description: 'Some description.',
|
||||
});
|
||||
const incomingHook = await store.dispatch(createIncomingHook({channel_id: secondChannel.id, display_name: 'test', description: 'test'}));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/outgoing').
|
||||
reply(201, {
|
||||
id: TestHelper.generateId(),
|
||||
token: TestHelper.generateId(),
|
||||
create_at: 1507841118796,
|
||||
update_at: 1507841118796,
|
||||
delete_at: 1609090954545,
|
||||
creator_id: TestHelper.basicUser.id,
|
||||
channel_id: secondChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
trigger_words: ['testword'],
|
||||
trigger_when: 0,
|
||||
callback_urls: ['http://notarealurl'],
|
||||
display_name: 'TestOutgoingHook',
|
||||
description: '',
|
||||
content_type: 'application/x-www-form-urlencoded',
|
||||
});
|
||||
const outgoingHook = await store.dispatch(createOutgoingHook({
|
||||
channel_id: secondChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'TestOutgoingHook',
|
||||
trigger_words: [TestHelper.generateId()],
|
||||
callback_urls: ['http://notarealurl']},
|
||||
));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
delete(`/channels/${secondChannel.id}`).
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await store.dispatch(Actions.unarchiveChannel(secondChannel.id));
|
||||
|
||||
const {incomingHooks, outgoingHooks} = store.getState().entities.integrations;
|
||||
|
||||
assert.ifError(incomingHooks[incomingHook.id]);
|
||||
assert.ifError(outgoingHooks[outgoingHook.id]);
|
||||
});
|
||||
|
||||
describe('viewChannel', () => {
|
||||
|
|
@ -1615,60 +1521,6 @@ describe('Actions.Channels', () => {
|
|||
assert.ok(store.getState().entities.channels.totalCount === mockTotalCount);
|
||||
});
|
||||
|
||||
it('searchAllChannels', async () => {
|
||||
const userClient = TestHelper.createClient();
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
query(true).
|
||||
reply(201, TestHelper.fakeUserWithId());
|
||||
|
||||
const user = await TestHelper.basicClient4.createUser(
|
||||
TestHelper.fakeUser(),
|
||||
null,
|
||||
null,
|
||||
TestHelper.basicTeam.invite_id,
|
||||
);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users/login').
|
||||
reply(200, user);
|
||||
|
||||
await userClient.login(user.email, 'password1');
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/channels').
|
||||
reply(201, TestHelper.fakeChannelWithId(TestHelper.basicTeam.id));
|
||||
|
||||
const userChannel = await userClient.createChannel(
|
||||
TestHelper.fakeChannel(TestHelper.basicTeam.id),
|
||||
);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/channels/search').
|
||||
reply(200, [TestHelper.basicChannel, userChannel]);
|
||||
|
||||
await store.dispatch(Actions.searchAllChannels('test', 0));
|
||||
|
||||
const moreRequest = store.getState().requests.channels.getAllChannels;
|
||||
if (moreRequest.status === RequestStatus.FAILURE) {
|
||||
throw new Error(JSON.stringify(moreRequest.error));
|
||||
}
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/channels/search').
|
||||
reply(200, {channels: [TestHelper.basicChannel, userChannel], total_count: 2});
|
||||
|
||||
const response = await store.dispatch(Actions.searchAllChannels('test', '', false, 0, 100));
|
||||
|
||||
const paginatedRequest = store.getState().requests.channels.getAllChannels;
|
||||
if (paginatedRequest.status === RequestStatus.FAILURE) {
|
||||
throw new Error(JSON.stringify(paginatedRequest.error));
|
||||
}
|
||||
|
||||
assert.ok(response.data.channels.length === 2);
|
||||
});
|
||||
|
||||
it('searchArchivedChannels', async () => {
|
||||
const userClient = TestHelper.createClient();
|
||||
|
||||
|
|
@ -1901,38 +1753,6 @@ describe('Actions.Channels', () => {
|
|||
assert.ok(stats[channelId].member_count >= 1, 'incorrect member count for channel');
|
||||
});
|
||||
|
||||
it('updateChannelMemberRoles', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
reply(201, TestHelper.fakeUserWithId());
|
||||
|
||||
const user = await TestHelper.basicClient4.createUser(TestHelper.fakeUser());
|
||||
|
||||
nock(Client4.getTeamsRoute()).
|
||||
post(`/${TestHelper.basicChannel.id}/members`).
|
||||
reply(201, {team_id: TestHelper.basicTeam.id, roles: 'channel_user', user_id: user.id});
|
||||
|
||||
await store.dispatch(addUserToTeam(TestHelper.basicTeam.id, user.id));
|
||||
nock(Client4.getBaseRoute()).
|
||||
post(`/channels/${TestHelper.basicChannel.id}/members`).
|
||||
reply(201, {channel_id: TestHelper.basicChannel.id, roles: 'channel_user', user_id: user.id});
|
||||
|
||||
await store.dispatch(Actions.addChannelMember(TestHelper.basicChannel.id, user.id));
|
||||
|
||||
const roles = General.CHANNEL_USER_ROLE + ' ' + General.CHANNEL_ADMIN_ROLE;
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/channels/${TestHelper.basicChannel.id}/members/${user.id}/roles`).
|
||||
reply(200, {roles});
|
||||
await store.dispatch(Actions.updateChannelMemberRoles(TestHelper.basicChannel.id, user.id, roles));
|
||||
|
||||
const members = store.getState().entities.channels.membersInChannel;
|
||||
|
||||
assert.ok(members[TestHelper.basicChannel.id]);
|
||||
assert.ok(members[TestHelper.basicChannel.id][user.id]);
|
||||
assert.ok(members[TestHelper.basicChannel.id][user.id].roles === roles);
|
||||
});
|
||||
|
||||
it('updateChannelHeader', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
get(`/channels/${TestHelper.basicChannel.id}`).
|
||||
|
|
@ -2158,73 +1978,6 @@ describe('Actions.Channels', () => {
|
|||
assert.deepEqual(result, {data: [TestHelper.basicChannel]});
|
||||
});
|
||||
|
||||
it('updateChannelScheme', async () => {
|
||||
TestHelper.mockLogin();
|
||||
await store.dispatch(login(TestHelper.basicChannelMember.email, 'password1'));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/channels').
|
||||
reply(201, TestHelper.fakeChannelWithId(TestHelper.basicTeam.id));
|
||||
|
||||
await store.dispatch(Actions.createChannel(TestHelper.fakeChannel(TestHelper.basicTeam.id), TestHelper.basicUser.id));
|
||||
|
||||
const createRequest = store.getState().requests.channels.createChannel;
|
||||
|
||||
if (createRequest.status === RequestStatus.FAILURE) {
|
||||
throw new Error(JSON.stringify(createRequest.error));
|
||||
}
|
||||
|
||||
const {channels} = store.getState().entities.channels;
|
||||
const schemeId = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
|
||||
const {id} = channels[Object.keys(channels)[0]];
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put('/channels/' + id + '/scheme').
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await store.dispatch(Actions.updateChannelScheme(id, schemeId));
|
||||
const updated = store.getState().entities.channels.channels[id];
|
||||
assert.ok(updated);
|
||||
assert.equal(updated.scheme_id, schemeId);
|
||||
});
|
||||
|
||||
it('updateChannelMemberSchemeRoles', async () => {
|
||||
TestHelper.mockLogin();
|
||||
await store.dispatch(login(TestHelper.basicChannelMember.email, 'password1'));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/channels').
|
||||
reply(201, TestHelper.fakeChannelWithId(TestHelper.basicTeam.id));
|
||||
|
||||
const userId = TestHelper.basicChannelMember.id;
|
||||
|
||||
await store.dispatch(Actions.createChannel(TestHelper.fakeChannel(TestHelper.basicTeam.id), userId));
|
||||
|
||||
const {channels} = store.getState().entities.channels;
|
||||
const channelId = channels[Object.keys(channels)[0]].id;
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/channels/${channelId}/members/${userId}/schemeRoles`).
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await store.dispatch(Actions.updateChannelMemberSchemeRoles(channelId, userId, true, true));
|
||||
const update1 = store.getState().entities.channels.membersInChannel[channelId][userId];
|
||||
assert.ok(update1);
|
||||
assert.equal(update1.scheme_admin, true);
|
||||
assert.equal(update1.scheme_user, true);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/channels/${channelId}/members/${userId}/schemeRoles`).
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await store.dispatch(Actions.updateChannelMemberSchemeRoles(channelId, userId, false, false));
|
||||
|
||||
const update2 = store.getState().entities.channels.membersInChannel[channelId][userId];
|
||||
assert.ok(update2);
|
||||
assert.equal(update2.scheme_admin, false);
|
||||
assert.equal(update2.scheme_user, false);
|
||||
});
|
||||
|
||||
it('markGroupChannelOpen', async () => {
|
||||
const channelId = TestHelper.generateId();
|
||||
const now = new Date().getTime();
|
||||
|
|
@ -2266,65 +2019,6 @@ describe('Actions.Channels', () => {
|
|||
assert.deepEqual(response, data);
|
||||
});
|
||||
|
||||
it('membersMinusGroupMembers', async () => {
|
||||
const channelID = 'cid10000000000000000000000';
|
||||
const groupIDs = ['gid10000000000000000000000', 'gid20000000000000000000000'];
|
||||
const page = 7;
|
||||
const perPage = 63;
|
||||
|
||||
nock(Client4.getBaseRoute()).get(
|
||||
`/channels/${channelID}/members_minus_group_members?group_ids=${groupIDs.join(',')}&page=${page}&per_page=${perPage}`).
|
||||
reply(200, {users: [], total_count: 0});
|
||||
|
||||
const {error} = await Actions.membersMinusGroupMembers(channelID, groupIDs, page, perPage)(store.dispatch, store.getState);
|
||||
|
||||
assert.equal(error, null);
|
||||
});
|
||||
|
||||
it('getChannelModerations', async () => {
|
||||
const channelID = 'cid10000000000000000000000';
|
||||
|
||||
nock(Client4.getBaseRoute()).get(
|
||||
`/channels/${channelID}/moderations`).
|
||||
reply(200, [{
|
||||
name: Permissions.CHANNEL_MODERATED_PERMISSIONS.CREATE_POST,
|
||||
roles: {
|
||||
members: true,
|
||||
guests: false,
|
||||
},
|
||||
}]);
|
||||
|
||||
const {error} = await store.dispatch(Actions.getChannelModerations(channelID));
|
||||
const moderations = store.getState().entities.channels.channelModerations[channelID];
|
||||
|
||||
assert.equal(error, null);
|
||||
assert.equal(moderations[0].name, Permissions.CHANNEL_MODERATED_PERMISSIONS.CREATE_POST);
|
||||
assert.equal(moderations[0].roles.members, true);
|
||||
assert.equal(moderations[0].roles.guests, false);
|
||||
});
|
||||
|
||||
it('patchChannelModerations', async () => {
|
||||
const channelID = 'cid10000000000000000000000';
|
||||
|
||||
nock(Client4.getBaseRoute()).put(
|
||||
`/channels/${channelID}/moderations/patch`).
|
||||
reply(200, [{
|
||||
name: Permissions.CHANNEL_MODERATED_PERMISSIONS.CREATE_REACTIONS,
|
||||
roles: {
|
||||
members: true,
|
||||
guests: false,
|
||||
},
|
||||
}]);
|
||||
|
||||
const {error} = await store.dispatch(Actions.patchChannelModerations(channelID, {}));
|
||||
const moderations = store.getState().entities.channels.channelModerations[channelID];
|
||||
|
||||
assert.equal(error, null);
|
||||
assert.equal(moderations[0].name, Permissions.CHANNEL_MODERATED_PERMISSIONS.CREATE_REACTIONS);
|
||||
assert.equal(moderations[0].roles.members, true);
|
||||
assert.equal(moderations[0].roles.guests, false);
|
||||
});
|
||||
|
||||
it('getChannelMemberCountsByGroup', async () => {
|
||||
const channelID = 'cid10000000000000000000000';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General, Preferences} from '../constants';
|
||||
import {ChannelTypes, PreferenceTypes, TeamTypes, UserTypes} from '@mm-redux/action_types';
|
||||
import {savePreferences, deletePreferences} from './preferences';
|
||||
|
|
@ -17,7 +17,7 @@ import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
|||
|
||||
import {Action, ActionFunc, batchActions, DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
|
||||
|
||||
import {Channel, ChannelNotifyProps, ChannelMembership, ChannelModerationPatch} from '@mm-redux/types/channels';
|
||||
import {Channel, ChannelNotifyProps, ChannelMembership} from '@mm-redux/types/channels';
|
||||
|
||||
import {PreferenceType} from '@mm-redux/types/preferences';
|
||||
|
||||
|
|
@ -1102,45 +1102,6 @@ export function searchChannels(teamId: string, term: string, archived?: boolean)
|
|||
};
|
||||
}
|
||||
|
||||
export function searchAllChannels(term: string, notAssociatedToGroup = '', excludeDefaultChannels = false, page?: number, perPage?: number): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
dispatch({type: ChannelTypes.GET_ALL_CHANNELS_REQUEST, data: null});
|
||||
|
||||
let response;
|
||||
try {
|
||||
response = await Client4.searchAllChannels(term, notAssociatedToGroup, excludeDefaultChannels, page, perPage);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(batchActions([
|
||||
{type: ChannelTypes.GET_ALL_CHANNELS_FAILURE, error},
|
||||
logError(error),
|
||||
]));
|
||||
return {error};
|
||||
}
|
||||
|
||||
const channels = response.channels || response;
|
||||
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: ChannelTypes.RECEIVED_ALL_CHANNELS,
|
||||
data: channels,
|
||||
},
|
||||
{
|
||||
type: ChannelTypes.GET_ALL_CHANNELS_SUCCESS,
|
||||
},
|
||||
]));
|
||||
|
||||
return {data: response};
|
||||
};
|
||||
}
|
||||
|
||||
export function searchGroupChannels(term: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.searchGroupChannels,
|
||||
params: [term],
|
||||
});
|
||||
}
|
||||
|
||||
export function getChannelStats(channelId: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let stat;
|
||||
|
|
@ -1220,28 +1181,6 @@ export function removeChannelMember(channelId: string, userId: string): ActionFu
|
|||
};
|
||||
}
|
||||
|
||||
export function updateChannelMemberRoles(channelId: string, userId: string, roles: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
try {
|
||||
await Client4.updateChannelMemberRoles(channelId, userId, roles);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
const membersInChannel = getState().entities.channels.membersInChannel[channelId];
|
||||
if (membersInChannel && membersInChannel[userId]) {
|
||||
dispatch({
|
||||
type: ChannelTypes.RECEIVED_CHANNEL_MEMBER,
|
||||
data: {...membersInChannel[userId], roles},
|
||||
});
|
||||
}
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function updateChannelHeader(channelId: string, header: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
analytics.trackAction('action_channels_update_header', {channel_id: channelId});
|
||||
|
|
@ -1461,65 +1400,6 @@ export function unfavoriteChannel(channelId: string): ActionFunc {
|
|||
};
|
||||
}
|
||||
|
||||
export function updateChannelScheme(channelId: string, schemeId: string) {
|
||||
return bindClientFunc({
|
||||
clientFunc: async () => {
|
||||
await Client4.updateChannelScheme(channelId, schemeId);
|
||||
return {channelId, schemeId};
|
||||
},
|
||||
onSuccess: ChannelTypes.UPDATED_CHANNEL_SCHEME,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateChannelMemberSchemeRoles(channelId: string, userId: string, isSchemeUser: boolean, isSchemeAdmin: boolean) {
|
||||
return bindClientFunc({
|
||||
clientFunc: async () => {
|
||||
await Client4.updateChannelMemberSchemeRoles(channelId, userId, isSchemeUser, isSchemeAdmin);
|
||||
return {channelId, userId, isSchemeUser, isSchemeAdmin};
|
||||
},
|
||||
onSuccess: ChannelTypes.UPDATED_CHANNEL_MEMBER_SCHEME_ROLES,
|
||||
});
|
||||
}
|
||||
|
||||
export function membersMinusGroupMembers(channelID: string, groupIDs: Array<string>, page = 0, perPage: number = General.PROFILE_CHUNK_SIZE): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.channelMembersMinusGroupMembers,
|
||||
onSuccess: ChannelTypes.RECEIVED_CHANNEL_MEMBERS_MINUS_GROUP_MEMBERS,
|
||||
params: [
|
||||
channelID,
|
||||
groupIDs,
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getChannelModerations(channelId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: async () => {
|
||||
const moderations = await Client4.getChannelModerations(channelId);
|
||||
return {channelId, moderations};
|
||||
},
|
||||
onSuccess: ChannelTypes.RECEIVED_CHANNEL_MODERATIONS,
|
||||
params: [
|
||||
channelId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function patchChannelModerations(channelId: string, patch: Array<ChannelModerationPatch>): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: async () => {
|
||||
const moderations = await Client4.patchChannelModerations(channelId, patch);
|
||||
return {channelId, moderations};
|
||||
},
|
||||
onSuccess: ChannelTypes.RECEIVED_CHANNEL_MODERATIONS,
|
||||
params: [
|
||||
channelId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getChannelMemberCountsByGroup(channelId: string, includeTimezones: boolean): ActionFunc {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
let channelMemberCountsByGroup;
|
||||
|
|
@ -1562,7 +1442,6 @@ export default {
|
|||
autocompleteChannels,
|
||||
autocompleteChannelsForSearch,
|
||||
searchChannels,
|
||||
searchGroupChannels,
|
||||
getChannelStats,
|
||||
addChannelMember,
|
||||
removeChannelMember,
|
||||
|
|
@ -1572,6 +1451,4 @@ export default {
|
|||
markChannelAsUnread,
|
||||
favoriteChannel,
|
||||
unfavoriteChannel,
|
||||
membersMinusGroupMembers,
|
||||
getChannelModerations,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import assert from 'assert';
|
|||
import nock from 'nock';
|
||||
|
||||
import * as Actions from '@mm-redux/actions/emojis';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import {GeneralTypes} from '@mm-redux/action_types';
|
||||
import TestHelper from 'test/test_helper';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {EmojiTypes} from '@mm-redux/action_types';
|
||||
import {General, Emoji} from '../constants';
|
||||
import {getProfilesByIds} from './users';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import assert from 'assert';
|
|||
import nock from 'nock';
|
||||
|
||||
import {logError} from '@mm-redux/actions/errors';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
import {ErrorTypes} from '@mm-redux/action_types';
|
||||
import {serializeError, ErrorObject} from 'serialize-error';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import {DispatchFunc, ActionFunc} from '@mm-redux/types/actions';
|
||||
import {Error} from '@mm-redux/types/errors';
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import fs from 'fs';
|
||||
import assert from 'assert';
|
||||
import nock from 'nock';
|
||||
|
||||
import * as Actions from '@mm-redux/actions/files';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
||||
const FormData = require('form-data');
|
||||
|
||||
describe('Actions.Files', () => {
|
||||
let store;
|
||||
beforeAll(async () => {
|
||||
|
|
@ -26,52 +23,6 @@ describe('Actions.Files', () => {
|
|||
await TestHelper.tearDown();
|
||||
});
|
||||
|
||||
it('getFilesForPost', async () => {
|
||||
const {basicClient4, basicChannel} = TestHelper;
|
||||
const testFileName = 'test.png';
|
||||
const testImageData = fs.createReadStream(`test/assets/images/${testFileName}`);
|
||||
const clientId = TestHelper.generateId();
|
||||
|
||||
const imageFormData = new FormData();
|
||||
imageFormData.append('files', testImageData);
|
||||
imageFormData.append('channel_id', basicChannel.id);
|
||||
imageFormData.append('client_ids', clientId);
|
||||
const formBoundary = imageFormData.getBoundary();
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/files').
|
||||
reply(201, {file_infos: [{id: TestHelper.generateId(), user_id: TestHelper.basicUser.id, create_at: 1507921547541, update_at: 1507921547541, delete_at: 0, name: 'test.png', extension: 'png', size: 258428, mime_type: 'image/png', width: 600, height: 600, has_preview_image: true}], client_ids: [TestHelper.generateId()]});
|
||||
|
||||
const fileUploadResp = await basicClient4.
|
||||
uploadFile(imageFormData, formBoundary);
|
||||
const fileId = fileUploadResp.file_infos[0].id;
|
||||
|
||||
const fakePostForFile = TestHelper.fakePost(basicChannel.id);
|
||||
fakePostForFile.file_ids = [fileId];
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/posts').
|
||||
reply(201, {...TestHelper.fakePostWithId(), ...fakePostForFile});
|
||||
const postForFile = await basicClient4.createPost(fakePostForFile);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get(`/posts/${postForFile.id}/files/info`).
|
||||
reply(200, [{id: fileId, user_id: TestHelper.basicUser.id, create_at: 1507921547541, update_at: 1507921547541, delete_at: 0, name: 'test.png', extension: 'png', size: 258428, mime_type: 'image/png', width: 600, height: 600, has_preview_image: true}]);
|
||||
|
||||
await Actions.getFilesForPost(postForFile.id)(store.dispatch, store.getState);
|
||||
|
||||
const {files: allFiles, fileIdsByPostId} = store.getState().entities.files;
|
||||
|
||||
assert.ok(allFiles);
|
||||
assert.ok(allFiles[fileId]);
|
||||
assert.equal(allFiles[fileId].id, fileId);
|
||||
assert.equal(allFiles[fileId].name, testFileName);
|
||||
|
||||
assert.ok(fileIdsByPostId);
|
||||
assert.ok(fileIdsByPostId[postForFile.id]);
|
||||
assert.equal(fileIdsByPostId[postForFile.id][0], fileId);
|
||||
});
|
||||
|
||||
it('getFilePublicLink', async () => {
|
||||
const fileId = 't1izsr9uspgi3ynggqu6xxjn9y';
|
||||
nock(Client4.getBaseRoute()).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {FileTypes} from '@mm-redux/action_types';
|
||||
|
||||
import {DispatchFunc, GetStateFunc, ActionFunc} from '@mm-redux/types/actions';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import nock from 'nock';
|
|||
import {FormattedError} from './helpers.ts';
|
||||
import {GeneralTypes} from '@mm-redux/action_types';
|
||||
import * as Actions from '@mm-redux/actions/general';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import {GeneralTypes} from '@mm-redux/action_types';
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
import assert from 'assert';
|
||||
|
||||
import {forceLogoutIfNecessary} from '@mm-redux/actions/helpers';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {ClientError} from '@mm-redux/client/client4';
|
||||
import {Client4} from '@client/rest';
|
||||
import ClientError from '@client/rest/error';
|
||||
import configureStore, {mockDispatch} from 'test/test_store';
|
||||
|
||||
describe('Actions.Helpers', () => {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import {logout} from '@actions/views/user';
|
||||
import {UserTypes} from '@mm-redux/action_types';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {Client4Error} from '@mm-redux/types/client4';
|
||||
import {getCurrentUserId, getUsers} from '@mm-redux/selectors/entities/users';
|
||||
import {batchActions, Action, ActionFunc, GenericAction, DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
|
||||
|
|
|
|||
|
|
@ -10,11 +10,9 @@ import * as general from './general';
|
|||
import * as gifs from './gifs';
|
||||
import * as helpers from './helpers';
|
||||
import * as integrations from './integrations';
|
||||
import * as jobs from './jobs';
|
||||
import * as posts from './posts';
|
||||
import * as preferences from './preferences';
|
||||
import * as roles from './roles';
|
||||
import * as schemes from './schemes';
|
||||
import * as search from './search';
|
||||
import * as teams from './teams';
|
||||
import * as timezone from './timezone';
|
||||
|
|
@ -30,11 +28,9 @@ export {
|
|||
gifs,
|
||||
integrations,
|
||||
helpers,
|
||||
jobs,
|
||||
posts,
|
||||
preferences,
|
||||
roles,
|
||||
schemes,
|
||||
search,
|
||||
teams,
|
||||
timezone,
|
||||
|
|
|
|||
|
|
@ -6,13 +6,11 @@ import nock from 'nock';
|
|||
|
||||
import * as Actions from '@mm-redux/actions/integrations';
|
||||
import * as TeamsActions from '@mm-redux/actions/teams';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
||||
const OK_RESPONSE = {status: 'OK'};
|
||||
|
||||
describe('Actions.Integrations', () => {
|
||||
let store;
|
||||
beforeAll(async () => {
|
||||
|
|
@ -27,294 +25,6 @@ describe('Actions.Integrations', () => {
|
|||
await TestHelper.tearDown();
|
||||
});
|
||||
|
||||
it('createIncomingHook', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/incoming').
|
||||
reply(201, TestHelper.testIncomingHook());
|
||||
|
||||
const {data: created} = await Actions.createIncomingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
display_name: 'test',
|
||||
description: 'test',
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.incomingHooks;
|
||||
assert.ok(hooks);
|
||||
assert.ok(hooks[created.id]);
|
||||
});
|
||||
|
||||
it('getIncomingWebhook', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/incoming').
|
||||
reply(201, TestHelper.testIncomingHook());
|
||||
|
||||
const {data: created} = await Actions.createIncomingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
display_name: 'test',
|
||||
description: 'test',
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get(`/hooks/incoming/${created.id}`).
|
||||
reply(200, created);
|
||||
|
||||
await Actions.getIncomingHook(created.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.incomingHooks;
|
||||
assert.ok(hooks);
|
||||
assert.ok(hooks[created.id]);
|
||||
});
|
||||
|
||||
it('getIncomingWebhooks', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/incoming').
|
||||
reply(201, TestHelper.testIncomingHook());
|
||||
|
||||
const {data: created} = await Actions.createIncomingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
display_name: 'test',
|
||||
description: 'test',
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/hooks/incoming').
|
||||
query(true).
|
||||
reply(200, [created]);
|
||||
|
||||
await Actions.getIncomingHooks(TestHelper.basicTeam.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.incomingHooks;
|
||||
assert.ok(hooks);
|
||||
assert.ok(hooks[created.id]);
|
||||
});
|
||||
|
||||
it('removeIncomingHook', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/incoming').
|
||||
reply(201, TestHelper.testIncomingHook());
|
||||
|
||||
const {data: created} = await Actions.createIncomingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
display_name: 'test',
|
||||
description: 'test',
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
delete(`/hooks/incoming/${created.id}`).
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await Actions.removeIncomingHook(created.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.incomingHooks;
|
||||
assert.ok(!hooks[created.id]);
|
||||
});
|
||||
|
||||
it('updateIncomingHook', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/incoming').
|
||||
reply(201, TestHelper.testIncomingHook());
|
||||
|
||||
const {data: created} = await Actions.createIncomingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
display_name: 'test',
|
||||
description: 'test',
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const updated = {...created};
|
||||
updated.display_name = 'test2';
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/hooks/incoming/${created.id}`).
|
||||
reply(200, updated);
|
||||
await Actions.updateIncomingHook(updated)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.incomingHooks;
|
||||
assert.ok(hooks[created.id]);
|
||||
assert.ok(hooks[created.id].display_name === updated.display_name);
|
||||
});
|
||||
|
||||
it('createOutgoingHook', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/outgoing').
|
||||
reply(201, TestHelper.testOutgoingHook());
|
||||
|
||||
const {data: created} = await Actions.createOutgoingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'test',
|
||||
trigger_words: [TestHelper.generateId()],
|
||||
callback_urls: ['http://localhost/notarealendpoint'],
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.outgoingHooks;
|
||||
assert.ok(hooks);
|
||||
assert.ok(hooks[created.id]);
|
||||
});
|
||||
|
||||
it('getOutgoingWebhook', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/outgoing').
|
||||
reply(201, TestHelper.testOutgoingHook());
|
||||
|
||||
const {data: created} = await Actions.createOutgoingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'test',
|
||||
trigger_words: [TestHelper.generateId()],
|
||||
callback_urls: ['http://localhost/notarealendpoint'],
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get(`/hooks/outgoing/${created.id}`).
|
||||
reply(200, TestHelper.testOutgoingHook());
|
||||
|
||||
await Actions.getOutgoingHook(created.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.outgoingHooks;
|
||||
assert.ok(hooks);
|
||||
assert.ok(hooks[created.id]);
|
||||
});
|
||||
|
||||
it('getOutgoingWebhooks', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/outgoing').
|
||||
reply(201, TestHelper.testOutgoingHook());
|
||||
|
||||
const {data: created} = await Actions.createOutgoingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'test',
|
||||
trigger_words: [TestHelper.generateId()],
|
||||
callback_urls: ['http://localhost/notarealendpoint'],
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/hooks/outgoing').
|
||||
query(true).
|
||||
reply(200, [TestHelper.testOutgoingHook()]);
|
||||
|
||||
await Actions.getOutgoingHooks(TestHelper.basicChannel.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.outgoingHooks;
|
||||
assert.ok(hooks);
|
||||
assert.ok(hooks[created.id]);
|
||||
});
|
||||
|
||||
it('removeOutgoingHook', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/outgoing').
|
||||
reply(201, TestHelper.testOutgoingHook());
|
||||
|
||||
const {data: created} = await Actions.createOutgoingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'test',
|
||||
trigger_words: [TestHelper.generateId()],
|
||||
callback_urls: ['http://localhost/notarealendpoint'],
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
delete(`/hooks/outgoing/${created.id}`).
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await Actions.removeOutgoingHook(created.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.outgoingHooks;
|
||||
assert.ok(!hooks[created.id]);
|
||||
});
|
||||
|
||||
it('updateOutgoingHook', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/outgoing').
|
||||
reply(201, TestHelper.testOutgoingHook());
|
||||
|
||||
const {data: created} = await Actions.createOutgoingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'test',
|
||||
trigger_words: [TestHelper.generateId()],
|
||||
callback_urls: ['http://localhost/notarealendpoint'],
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const updated = {...created};
|
||||
updated.display_name = 'test2';
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/hooks/outgoing/${created.id}`).
|
||||
reply(200, updated);
|
||||
await Actions.updateOutgoingHook(updated)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.outgoingHooks;
|
||||
assert.ok(hooks[created.id]);
|
||||
assert.ok(hooks[created.id].display_name === updated.display_name);
|
||||
});
|
||||
|
||||
it('regenOutgoingHookToken', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/outgoing').
|
||||
reply(201, TestHelper.testOutgoingHook());
|
||||
|
||||
const {data: created} = await Actions.createOutgoingHook(
|
||||
{
|
||||
channel_id: TestHelper.basicChannel.id,
|
||||
team_id: TestHelper.basicTeam.id,
|
||||
display_name: 'test',
|
||||
trigger_words: [TestHelper.generateId()],
|
||||
callback_urls: ['http://localhost/notarealendpoint'],
|
||||
},
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post(`/hooks/outgoing/${created.id}/regen_token`).
|
||||
reply(200, {...created, token: TestHelper.generateId()});
|
||||
await Actions.regenOutgoingHookToken(created.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const hooks = state.entities.integrations.outgoingHooks;
|
||||
assert.ok(hooks[created.id]);
|
||||
assert.ok(hooks[created.id].token !== created.token);
|
||||
});
|
||||
|
||||
it('getCommands', async () => {
|
||||
const noTeamCommands = store.getState().entities.integrations.commands;
|
||||
const noSystemCommands = store.getState().entities.integrations.systemCommands;
|
||||
|
|
@ -393,54 +103,6 @@ describe('Actions.Integrations', () => {
|
|||
assert.equal(Object.keys({...teamCommands, ...systemCommands}).length, 2);
|
||||
});
|
||||
|
||||
it('getCustomTeamCommands', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams').
|
||||
reply(201, TestHelper.fakeTeamWithId());
|
||||
|
||||
const {data: team} = await TeamsActions.createTeam(
|
||||
TestHelper.fakeTeam(),
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/commands').
|
||||
query(true).
|
||||
reply(200, []);
|
||||
|
||||
await Actions.getCustomTeamCommands(
|
||||
team.id,
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const noCommands = store.getState().entities.integrations.commands;
|
||||
assert.equal(Object.keys(noCommands).length, 0);
|
||||
|
||||
const command = TestHelper.testCommand(team.id);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/commands').
|
||||
reply(201, {...command, token: TestHelper.generateId(), id: TestHelper.generateId()});
|
||||
|
||||
const {data: created} = await Actions.addCommand(
|
||||
command,
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/commands').
|
||||
query(true).
|
||||
reply(200, []);
|
||||
|
||||
await Actions.getCustomTeamCommands(
|
||||
team.id,
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const {commands} = store.getState().entities.integrations;
|
||||
assert.ok(commands[created.id]);
|
||||
assert.equal(Object.keys(commands).length, 1);
|
||||
const actual = commands[created.id];
|
||||
const expected = created;
|
||||
assert.equal(JSON.stringify(actual), JSON.stringify(expected));
|
||||
});
|
||||
|
||||
it('executeCommand', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams').
|
||||
|
|
@ -500,259 +162,6 @@ describe('Actions.Integrations', () => {
|
|||
assert.equal(actual.url, expected.url);
|
||||
});
|
||||
|
||||
it('regenCommandToken', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams').
|
||||
reply(201, TestHelper.fakeTeamWithId());
|
||||
|
||||
const {data: team} = await TeamsActions.createTeam(
|
||||
TestHelper.fakeTeam(),
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const command = TestHelper.testCommand(team.id);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/commands').
|
||||
reply(201, {...command, token: TestHelper.generateId(), id: TestHelper.generateId()});
|
||||
|
||||
const {data: created} = await Actions.addCommand(
|
||||
command,
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/commands/${created.id}/regen_token`).
|
||||
reply(200, {...created, token: TestHelper.generateId()});
|
||||
|
||||
await Actions.regenCommandToken(
|
||||
created.id,
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const {commands} = store.getState().entities.integrations;
|
||||
assert.ok(commands[created.id]);
|
||||
const updated = commands[created.id];
|
||||
|
||||
assert.equal(updated.id, created.id);
|
||||
assert.notEqual(updated.token, created.token);
|
||||
assert.equal(updated.create_at, created.create_at);
|
||||
assert.equal(updated.update_at, created.update_at);
|
||||
assert.equal(updated.delete_at, created.delete_at);
|
||||
assert.equal(updated.creator_id, created.creator_id);
|
||||
assert.equal(updated.team_id, created.team_id);
|
||||
assert.equal(updated.trigger, created.trigger);
|
||||
assert.equal(updated.method, created.method);
|
||||
assert.equal(updated.username, created.username);
|
||||
assert.equal(updated.icon_url, created.icon_url);
|
||||
assert.equal(updated.auto_complete, created.auto_complete);
|
||||
assert.equal(updated.auto_complete_desc, created.auto_complete_desc);
|
||||
assert.equal(updated.auto_complete_hint, created.auto_complete_hint);
|
||||
assert.equal(updated.display_name, created.display_name);
|
||||
assert.equal(updated.description, created.description);
|
||||
assert.equal(updated.url, created.url);
|
||||
});
|
||||
|
||||
it('editCommand', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams').
|
||||
reply(201, TestHelper.fakeTeamWithId());
|
||||
|
||||
const {data: team} = await TeamsActions.createTeam(
|
||||
TestHelper.fakeTeam(),
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const command = TestHelper.testCommand(team.id);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/commands').
|
||||
reply(201, {...command, token: TestHelper.generateId(), id: TestHelper.generateId()});
|
||||
|
||||
const {data: created} = await Actions.addCommand(
|
||||
command,
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const expected = Object.assign({}, created);
|
||||
expected.trigger = 'modified';
|
||||
expected.method = 'G';
|
||||
expected.username = 'modified';
|
||||
expected.auto_complete = false;
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/commands/${expected.id}`).
|
||||
reply(200, {...expected, update_at: 123});
|
||||
|
||||
await Actions.editCommand(
|
||||
expected,
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const {commands} = store.getState().entities.integrations;
|
||||
assert.ok(commands[created.id]);
|
||||
const actual = commands[created.id];
|
||||
|
||||
assert.notEqual(actual.update_at, expected.update_at);
|
||||
expected.update_at = actual.update_at;
|
||||
assert.equal(JSON.stringify(actual), JSON.stringify(expected));
|
||||
});
|
||||
|
||||
it('deleteCommand', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams').
|
||||
reply(201, TestHelper.fakeTeamWithId());
|
||||
|
||||
const {data: team} = await TeamsActions.createTeam(
|
||||
TestHelper.fakeTeam(),
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const command = TestHelper.testCommand(team.id);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/commands').
|
||||
reply(201, {...command, token: TestHelper.generateId(), id: TestHelper.generateId()});
|
||||
|
||||
const {data: created} = await Actions.addCommand(
|
||||
command,
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
delete(`/commands/${created.id}`).
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await Actions.deleteCommand(
|
||||
created.id,
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const {commands} = store.getState().entities.integrations;
|
||||
assert.ok(!commands[created.id]);
|
||||
});
|
||||
|
||||
it('addOAuthApp', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/oauth/apps').
|
||||
reply(201, TestHelper.fakeOAuthAppWithId());
|
||||
|
||||
const {data: created} = await Actions.addOAuthApp(TestHelper.fakeOAuthApp())(store.dispatch, store.getState);
|
||||
|
||||
const {oauthApps} = store.getState().entities.integrations;
|
||||
assert.ok(oauthApps[created.id]);
|
||||
});
|
||||
|
||||
it('getOAuthApp', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/oauth/apps').
|
||||
reply(201, TestHelper.fakeOAuthAppWithId());
|
||||
|
||||
const {data: created} = await Actions.addOAuthApp(TestHelper.fakeOAuthApp())(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get(`/oauth/apps/${created.id}`).
|
||||
reply(200, created);
|
||||
|
||||
await Actions.getOAuthApp(created.id)(store.dispatch, store.getState);
|
||||
|
||||
const {oauthApps} = store.getState().entities.integrations;
|
||||
assert.ok(oauthApps[created.id]);
|
||||
});
|
||||
|
||||
it('editOAuthApp', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/oauth/apps').
|
||||
reply(201, TestHelper.fakeOAuthAppWithId());
|
||||
|
||||
const {data: created} = await Actions.addOAuthApp(TestHelper.fakeOAuthApp())(store.dispatch, store.getState);
|
||||
|
||||
const expected = Object.assign({}, created);
|
||||
expected.name = 'modified';
|
||||
expected.description = 'modified';
|
||||
expected.homepage = 'https://modified.com';
|
||||
expected.icon_url = 'https://modified.com/icon';
|
||||
expected.callback_urls = ['https://modified.com/callback1', 'https://modified.com/callback2'];
|
||||
expected.is_trusted = true;
|
||||
|
||||
const nockReply = Object.assign({}, expected);
|
||||
nockReply.update_at += 1;
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/oauth/apps/${created.id}`).reply(200, nockReply);
|
||||
|
||||
await Actions.editOAuthApp(expected)(store.dispatch, store.getState);
|
||||
|
||||
const {oauthApps} = store.getState().entities.integrations;
|
||||
assert.ok(oauthApps[created.id]);
|
||||
|
||||
const actual = oauthApps[created.id];
|
||||
|
||||
assert.notEqual(actual.update_at, expected.update_at);
|
||||
expected.update_at = actual.update_at;
|
||||
assert.equal(JSON.stringify(actual), JSON.stringify(expected));
|
||||
});
|
||||
|
||||
it('getOAuthApps', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/oauth/apps').
|
||||
reply(201, TestHelper.fakeOAuthAppWithId());
|
||||
|
||||
const {data: created} = await Actions.addOAuthApp(TestHelper.fakeOAuthApp())(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/oauth/apps').
|
||||
query(true).
|
||||
reply(200, [created]);
|
||||
|
||||
await Actions.getOAuthApps()(store.dispatch, store.getState);
|
||||
|
||||
const {oauthApps} = store.getState().entities.integrations;
|
||||
assert.ok(oauthApps);
|
||||
});
|
||||
|
||||
it('getAuthorizedOAuthApps', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/oauth/apps').
|
||||
reply(201, TestHelper.fakeOAuthAppWithId());
|
||||
|
||||
const {data: created} = await Actions.addOAuthApp(TestHelper.fakeOAuthApp())(store.dispatch, store.getState);
|
||||
|
||||
const user = TestHelper.basicUser;
|
||||
nock(Client4.getBaseRoute()).
|
||||
get(`/users/${user.id}/oauth/apps/authorized`).
|
||||
reply(200, [created]);
|
||||
|
||||
await Actions.getAuthorizedOAuthApps()(store.dispatch, store.getState);
|
||||
|
||||
const {oauthApps} = store.getState().entities.integrations;
|
||||
assert.ok(oauthApps);
|
||||
});
|
||||
|
||||
it('deleteOAuthApp', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/oauth/apps').
|
||||
reply(201, TestHelper.fakeOAuthAppWithId());
|
||||
|
||||
const {data: created} = await Actions.addOAuthApp(TestHelper.fakeOAuthApp())(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
delete(`/oauth/apps/${created.id}`).
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await Actions.deleteOAuthApp(created.id)(store.dispatch, store.getState);
|
||||
|
||||
const {oauthApps} = store.getState().entities.integrations;
|
||||
assert.ok(!oauthApps[created.id]);
|
||||
});
|
||||
|
||||
it('regenOAuthAppSecret', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/oauth/apps').
|
||||
reply(201, TestHelper.fakeOAuthAppWithId());
|
||||
|
||||
const {data: created} = await Actions.addOAuthApp(TestHelper.fakeOAuthApp())(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post(`/oauth/apps/${created.id}/regen_secret`).
|
||||
reply(200, {...created, client_secret: TestHelper.generateId()});
|
||||
|
||||
await Actions.regenOAuthAppSecret(created.id)(store.dispatch, store.getState);
|
||||
|
||||
const {oauthApps} = store.getState().entities.integrations;
|
||||
assert.ok(oauthApps[created.id].client_secret !== created.client_secret);
|
||||
});
|
||||
|
||||
it('submitInteractiveDialog', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/actions/dialogs/submit').
|
||||
|
|
|
|||
|
|
@ -5,15 +5,14 @@ import {Alert} from 'react-native';
|
|||
|
||||
import {IntegrationTypes} from '@mm-redux/action_types';
|
||||
import {General} from '../constants';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {Client4} from '@client/rest';
|
||||
import {getCurrentChannelId} from '@mm-redux/selectors/entities/channels';
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
import {analytics} from '@init/analytics';
|
||||
|
||||
import {batchActions, DispatchFunc, GetStateFunc, ActionFunc} from '@mm-redux/types/actions';
|
||||
|
||||
import {Command, CommandArgs, DialogSubmission, IncomingWebhook, OAuthApp, OutgoingWebhook} from '@mm-redux/types/integrations';
|
||||
import {Command, CommandArgs, DialogSubmission} from '@mm-redux/types/integrations';
|
||||
|
||||
import {logError} from './errors';
|
||||
import {bindClientFunc, forceLogoutIfNecessary, requestSuccess, requestFailure} from './helpers';
|
||||
|
|
@ -28,145 +27,6 @@ import * as DraftUtils from '@utils/draft';
|
|||
import {permalinkBadTeam} from '@utils/general';
|
||||
import {getURLAndMatch, tryOpenURL} from '@utils/url';
|
||||
|
||||
export function createIncomingHook(hook: IncomingWebhook): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.createIncomingWebhook,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_INCOMING_HOOK],
|
||||
params: [
|
||||
hook,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getIncomingHook(hookId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getIncomingWebhook,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_INCOMING_HOOK],
|
||||
params: [
|
||||
hookId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getIncomingHooks(teamId = '', page = 0, perPage: number = General.PAGE_SIZE_DEFAULT): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getIncomingWebhooks,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_INCOMING_HOOKS],
|
||||
params: [
|
||||
teamId,
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function removeIncomingHook(hookId: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
try {
|
||||
await Client4.removeIncomingWebhook(hookId);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: IntegrationTypes.DELETED_INCOMING_HOOK,
|
||||
data: {id: hookId},
|
||||
},
|
||||
]));
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function updateIncomingHook(hook: IncomingWebhook): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.updateIncomingWebhook,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_INCOMING_HOOK],
|
||||
params: [
|
||||
hook,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function createOutgoingHook(hook: OutgoingWebhook): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.createOutgoingWebhook,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_OUTGOING_HOOK],
|
||||
params: [
|
||||
hook,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getOutgoingHook(hookId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getOutgoingWebhook,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_OUTGOING_HOOK],
|
||||
params: [
|
||||
hookId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getOutgoingHooks(channelId = '', teamId = '', page = 0, perPage: number = General.PAGE_SIZE_DEFAULT): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getOutgoingWebhooks,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_OUTGOING_HOOKS],
|
||||
params: [
|
||||
channelId,
|
||||
teamId,
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function removeOutgoingHook(hookId: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
try {
|
||||
await Client4.removeOutgoingWebhook(hookId);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: IntegrationTypes.DELETED_OUTGOING_HOOK,
|
||||
data: {id: hookId},
|
||||
},
|
||||
]));
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function updateOutgoingHook(hook: OutgoingWebhook): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.updateOutgoingWebhook,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_OUTGOING_HOOK],
|
||||
params: [
|
||||
hook,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function regenOutgoingHookToken(hookId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.regenOutgoingHookToken,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_OUTGOING_HOOK],
|
||||
params: [
|
||||
hookId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getCommands(teamId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getCommandsList,
|
||||
|
|
@ -206,16 +66,6 @@ export function getCommandAutocompleteSuggestions(userInput: string, teamId: str
|
|||
};
|
||||
}
|
||||
|
||||
export function getCustomTeamCommands(teamId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getCustomTeamCommands,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_CUSTOM_TEAM_COMMANDS],
|
||||
params: [
|
||||
teamId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function addCommand(command: Command): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.addCommand,
|
||||
|
|
@ -226,16 +76,6 @@ export function addCommand(command: Command): ActionFunc {
|
|||
});
|
||||
}
|
||||
|
||||
export function editCommand(command: Command): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.editCommand,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_COMMAND],
|
||||
params: [
|
||||
command,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function executeCommand(command: string, args: CommandArgs): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.executeCommand,
|
||||
|
|
@ -246,154 +86,6 @@ export function executeCommand(command: string, args: CommandArgs): ActionFunc {
|
|||
});
|
||||
}
|
||||
|
||||
export function regenCommandToken(id: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let res;
|
||||
try {
|
||||
res = await Client4.regenCommandToken(id);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: IntegrationTypes.RECEIVED_COMMAND_TOKEN,
|
||||
data: {
|
||||
id,
|
||||
token: res.token,
|
||||
},
|
||||
},
|
||||
]));
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function deleteCommand(id: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
try {
|
||||
await Client4.deleteCommand(id);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: IntegrationTypes.DELETED_COMMAND,
|
||||
data: {id},
|
||||
},
|
||||
]));
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function addOAuthApp(app: OAuthApp): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.createOAuthApp,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_OAUTH_APP],
|
||||
params: [
|
||||
app,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function editOAuthApp(app: OAuthApp): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.editOAuthApp,
|
||||
onSuccess: IntegrationTypes.RECEIVED_OAUTH_APP,
|
||||
params: [
|
||||
app,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getOAuthApps(page = 0, perPage: number = General.PAGE_SIZE_DEFAULT): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getOAuthApps,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_OAUTH_APPS],
|
||||
params: [
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getOAuthApp(appId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getOAuthApp,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_OAUTH_APP],
|
||||
params: [
|
||||
appId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getAuthorizedOAuthApps(): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const state = getState();
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = await Client4.getAuthorizedOAuthApps(currentUserId);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
|
||||
dispatch(logError(error));
|
||||
|
||||
return {error};
|
||||
}
|
||||
|
||||
return {data};
|
||||
};
|
||||
}
|
||||
|
||||
export function deauthorizeOAuthApp(clientId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.deauthorizeOAuthApp,
|
||||
params: [clientId],
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteOAuthApp(id: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
try {
|
||||
await Client4.deleteOAuthApp(id);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: IntegrationTypes.DELETED_OAUTH_APP,
|
||||
data: {id},
|
||||
},
|
||||
]));
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function regenOAuthAppSecret(appId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.regenOAuthAppSecret,
|
||||
onSuccess: [IntegrationTypes.RECEIVED_OAUTH_APP],
|
||||
params: [
|
||||
appId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function submitInteractiveDialog(submission: DialogSubmission): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const state = getState();
|
||||
|
|
|
|||
|
|
@ -1,145 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import assert from 'assert';
|
||||
import nock from 'nock';
|
||||
|
||||
import * as Actions from '@mm-redux/actions/jobs';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
|
||||
import {RequestStatus} from '../constants';
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
||||
const OK_RESPONSE = {status: 'OK'};
|
||||
|
||||
describe('Actions.Jobs', () => {
|
||||
let store;
|
||||
beforeAll(async () => {
|
||||
await TestHelper.initBasic(Client4);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
store = await configureStore();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await TestHelper.tearDown();
|
||||
});
|
||||
|
||||
it('createJob', async () => {
|
||||
const job = {
|
||||
type: 'data_retention',
|
||||
};
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/jobs').
|
||||
reply(201, {
|
||||
id: 'six4h67ja7ntdkek6g13dp3wka',
|
||||
create_at: 1491399241953,
|
||||
type: 'data_retention',
|
||||
status: 'pending',
|
||||
data: {},
|
||||
});
|
||||
|
||||
await Actions.createJob(job)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const request = state.requests.jobs.createJob;
|
||||
if (request.status === RequestStatus.FAILURE) {
|
||||
throw new Error('createJob request failed');
|
||||
}
|
||||
|
||||
const jobs = state.entities.jobs.jobs;
|
||||
assert.ok(jobs.six4h67ja7ntdkek6g13dp3wka);
|
||||
});
|
||||
|
||||
it('getJob', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/jobs/six4h67ja7ntdkek6g13dp3wka').
|
||||
reply(200, {
|
||||
id: 'six4h67ja7ntdkek6g13dp3wka',
|
||||
create_at: 1491399241953,
|
||||
type: 'data_retention',
|
||||
status: 'pending',
|
||||
data: {},
|
||||
});
|
||||
|
||||
await Actions.getJob('six4h67ja7ntdkek6g13dp3wka')(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const request = state.requests.jobs.getJob;
|
||||
if (request.status === RequestStatus.FAILURE) {
|
||||
throw new Error('getJob request failed');
|
||||
}
|
||||
|
||||
const jobs = state.entities.jobs.jobs;
|
||||
assert.ok(jobs.six4h67ja7ntdkek6g13dp3wka);
|
||||
});
|
||||
|
||||
it('cancelJob', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/jobs/six4h67ja7ntdkek6g13dp3wka/cancel').
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await Actions.cancelJob('six4h67ja7ntdkek6g13dp3wka')(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const request = state.requests.jobs.cancelJob;
|
||||
if (request.status === RequestStatus.FAILURE) {
|
||||
throw new Error('cancelJob request failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('getJobs', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/jobs').
|
||||
query(true).
|
||||
reply(200, [{
|
||||
id: 'six4h67ja7ntdkek6g13dp3wka',
|
||||
create_at: 1491399241953,
|
||||
type: 'data_retention',
|
||||
status: 'pending',
|
||||
data: {},
|
||||
}]);
|
||||
|
||||
await Actions.getJobs()(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const request = state.requests.jobs.getJobs;
|
||||
if (request.status === RequestStatus.FAILURE) {
|
||||
throw new Error('getJobs request failed');
|
||||
}
|
||||
|
||||
const jobs = state.entities.jobs.jobs;
|
||||
assert.ok(jobs.six4h67ja7ntdkek6g13dp3wka);
|
||||
});
|
||||
|
||||
it('getJobsByType', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/jobs/type/data_retention').
|
||||
query(true).
|
||||
reply(200, [{
|
||||
id: 'six4h67ja7ntdkek6g13dp3wka',
|
||||
create_at: 1491399241953,
|
||||
type: 'data_retention',
|
||||
status: 'pending',
|
||||
data: {},
|
||||
}]);
|
||||
|
||||
await Actions.getJobsByType('data_retention')(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const request = state.requests.jobs.getJobs;
|
||||
if (request.status === RequestStatus.FAILURE) {
|
||||
throw new Error('getJobsByType request failed');
|
||||
}
|
||||
|
||||
const jobs = state.entities.jobs.jobs;
|
||||
assert.ok(jobs.six4h67ja7ntdkek6g13dp3wka);
|
||||
|
||||
const jobsByType = state.entities.jobs.jobsByTypeList;
|
||||
assert.ok(jobsByType.data_retention);
|
||||
assert.ok(jobsByType.data_retention.length === 1);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {JobTypes} from '@mm-redux/action_types';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {General} from '../constants';
|
||||
|
||||
import {ActionFunc} from '@mm-redux/types/actions';
|
||||
import {JobType, Job} from '@mm-redux/types/jobs';
|
||||
|
||||
import {bindClientFunc} from './helpers';
|
||||
export function createJob(job: Job): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.createJob,
|
||||
onRequest: JobTypes.CREATE_JOB_REQUEST,
|
||||
onSuccess: [JobTypes.RECEIVED_JOB, JobTypes.CREATE_JOB_SUCCESS],
|
||||
onFailure: JobTypes.CREATE_JOB_FAILURE,
|
||||
params: [
|
||||
job,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getJob(id: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getJob,
|
||||
onRequest: JobTypes.GET_JOB_REQUEST,
|
||||
onSuccess: [JobTypes.RECEIVED_JOB, JobTypes.GET_JOB_SUCCESS],
|
||||
onFailure: JobTypes.GET_JOB_FAILURE,
|
||||
params: [
|
||||
id,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getJobs(page = 0, perPage: number = General.JOBS_CHUNK_SIZE): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getJobs,
|
||||
onRequest: JobTypes.GET_JOBS_REQUEST,
|
||||
onSuccess: [JobTypes.RECEIVED_JOBS, JobTypes.GET_JOBS_SUCCESS],
|
||||
onFailure: JobTypes.GET_JOBS_FAILURE,
|
||||
params: [
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getJobsByType(type: JobType, page = 0, perPage: number = General.JOBS_CHUNK_SIZE): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getJobsByType,
|
||||
onRequest: JobTypes.GET_JOBS_REQUEST,
|
||||
onSuccess: [JobTypes.RECEIVED_JOBS, JobTypes.RECEIVED_JOBS_BY_TYPE, JobTypes.GET_JOBS_SUCCESS],
|
||||
onFailure: JobTypes.GET_JOBS_FAILURE,
|
||||
params: [
|
||||
type,
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function cancelJob(job: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.cancelJob,
|
||||
onRequest: JobTypes.CANCEL_JOB_REQUEST,
|
||||
onSuccess: JobTypes.CANCEL_JOB_SUCCESS,
|
||||
onFailure: JobTypes.CANCEL_JOB_FAILURE,
|
||||
params: [
|
||||
job,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import * as Actions from '@mm-redux/actions/posts';
|
|||
import {getChannelStats} from '@mm-redux/actions/channels';
|
||||
import {login} from '@mm-redux/actions/users';
|
||||
import {createCustomEmoji} from '@mm-redux/actions/emojis';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {Preferences, Posts, RequestStatus} from '../constants';
|
||||
import {ChannelTypes, PostTypes} from '@mm-redux/action_types';
|
||||
import TestHelper from 'test/test_helper';
|
||||
|
|
@ -343,31 +343,6 @@ describe('Actions.Posts', () => {
|
|||
assert.ok(!reactions[post1.id]);
|
||||
});
|
||||
|
||||
it('getPostsUnread', async () => {
|
||||
const {dispatch, getState} = store;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
const post = TestHelper.fakePostWithId(channelId);
|
||||
const userId = getState().entities.users.currentUserId;
|
||||
const response = {
|
||||
posts: {
|
||||
[post.id]: post,
|
||||
},
|
||||
order: [post.id],
|
||||
next_post_id: '',
|
||||
prev_post_id: '',
|
||||
};
|
||||
|
||||
nock(Client4.getUsersRoute()).
|
||||
get(`/${userId}/channels/${channelId}/posts/unread`).
|
||||
query(true).
|
||||
reply(200, response);
|
||||
|
||||
await Actions.getPostsUnread(channelId)(dispatch, getState);
|
||||
const {posts} = getState().entities.posts;
|
||||
|
||||
assert.ok(posts[post.id]);
|
||||
});
|
||||
|
||||
it('getPostThread', async () => {
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
const post = {id: TestHelper.generateId(), channel_id: channelId, message: ''};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General, Preferences, Posts} from '@mm-redux/constants';
|
||||
import {WebsocketEvents} from '@constants';
|
||||
import {PostTypes, ChannelTypes, FileTypes, IntegrationTypes} from '@mm-redux/action_types';
|
||||
|
|
@ -728,33 +728,6 @@ export function getPosts(channelId: string, page = 0, perPage = Posts.POST_CHUNK
|
|||
};
|
||||
}
|
||||
|
||||
export function getPostsUnread(channelId: string) {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const userId = getCurrentUserId(getState());
|
||||
let posts;
|
||||
try {
|
||||
posts = await Client4.getPostsUnread(channelId, userId);
|
||||
getProfilesAndStatusesForPosts(posts.posts, dispatch, getState);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch(batchActions([
|
||||
receivedPosts(posts),
|
||||
receivedPostsInChannel(posts, channelId, posts.next_post_id === '', posts.prev_post_id === ''),
|
||||
]));
|
||||
dispatch({
|
||||
type: PostTypes.RECEIVED_POSTS,
|
||||
data: posts,
|
||||
channelId,
|
||||
});
|
||||
|
||||
return {data: posts};
|
||||
};
|
||||
}
|
||||
|
||||
export function getPostsSince(channelId: string, since: number) {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let posts;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import nock from 'nock';
|
|||
|
||||
import * as Actions from '@mm-redux/actions/preferences';
|
||||
import {login} from '@mm-redux/actions/users';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {Preferences} from '../constants';
|
||||
|
||||
import TestHelper from 'test/test_helper';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {Preferences} from '../constants';
|
||||
import {PreferenceTypes} from '@mm-redux/action_types';
|
||||
import {getMyPreferences as getMyPreferencesSelector, makeGetCategory} from '@mm-redux/selectors/entities/preferences';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import assert from 'assert';
|
|||
import nock from 'nock';
|
||||
|
||||
import * as Actions from '@mm-redux/actions/roles';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {RequestStatus} from '../constants';
|
||||
|
||||
import TestHelper from 'test/test_helper';
|
||||
|
|
@ -44,43 +44,6 @@ describe('Actions.Roles', () => {
|
|||
assert.deepEqual(roles.system_admin.permissions, TestHelper.basicRoles.system_admin.permissions);
|
||||
});
|
||||
|
||||
it('getRoleByName', async () => {
|
||||
nock(Client4.getRolesRoute()).
|
||||
get('/name/system_admin').
|
||||
reply(200, TestHelper.basicRoles.system_admin);
|
||||
await Actions.getRoleByName('system_admin')(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const request = state.requests.roles.getRolesByNames;
|
||||
const {roles} = state.entities.roles;
|
||||
|
||||
if (request.status === RequestStatus.FAILURE) {
|
||||
throw new Error(JSON.stringify(request.error));
|
||||
}
|
||||
|
||||
assert.equal(roles.system_admin.name, 'system_admin');
|
||||
assert.deepEqual(roles.system_admin.permissions, TestHelper.basicRoles.system_admin.permissions);
|
||||
});
|
||||
|
||||
it('getRole', async () => {
|
||||
nock(Client4.getRolesRoute()).
|
||||
get('/' + TestHelper.basicRoles.system_admin.id).
|
||||
reply(200, TestHelper.basicRoles.system_admin);
|
||||
|
||||
await Actions.getRole(TestHelper.basicRoles.system_admin.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const request = state.requests.roles.getRole;
|
||||
const {roles} = state.entities.roles;
|
||||
|
||||
if (request.status === RequestStatus.FAILURE) {
|
||||
throw new Error(JSON.stringify(request.error));
|
||||
}
|
||||
|
||||
assert.equal(roles.system_admin.name, 'system_admin');
|
||||
assert.deepEqual(roles.system_admin.permissions, TestHelper.basicRoles.system_admin.permissions);
|
||||
});
|
||||
|
||||
it('loadRolesIfNeeded', async () => {
|
||||
const mock1 = nock(Client4.getRolesRoute()).
|
||||
post('/names', JSON.stringify(['existing_role'])).
|
||||
|
|
@ -106,14 +69,4 @@ describe('Actions.Roles', () => {
|
|||
assert(!mock1.isDone());
|
||||
assert(mock2.isDone());
|
||||
});
|
||||
|
||||
it('editRole', async () => {
|
||||
const roleId = TestHelper.basicRoles.system_admin.id;
|
||||
const mock = nock(Client4.getRolesRoute()).
|
||||
put('/' + roleId + '/patch', JSON.stringify({id: roleId, test: 'test'})).
|
||||
reply(200, {});
|
||||
|
||||
await Actions.editRole({id: roleId, test: 'test'})(store.dispatch, store.state);
|
||||
assert(mock.isDone());
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,62 +1,22 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {RoleTypes} from '@mm-redux/action_types';
|
||||
import {getRoles} from '@mm-redux/selectors/entities/roles_helpers';
|
||||
|
||||
import {DispatchFunc, GetStateFunc, ActionFunc} from '@mm-redux/types/actions';
|
||||
import {Role} from '@mm-redux/types/roles';
|
||||
|
||||
import {bindClientFunc} from './helpers';
|
||||
export function getRolesByNames(rolesNames: Array<string>) {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getRolesByNames,
|
||||
onRequest: RoleTypes.ROLES_BY_NAMES_REQUEST,
|
||||
onSuccess: [RoleTypes.RECEIVED_ROLES, RoleTypes.ROLES_BY_NAMES_SUCCESS],
|
||||
onFailure: RoleTypes.ROLES_BY_NAMES_FAILURE,
|
||||
params: [
|
||||
rolesNames,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getRoleByName(roleName: string) {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getRoleByName,
|
||||
onRequest: RoleTypes.ROLE_BY_NAME_REQUEST,
|
||||
onSuccess: [RoleTypes.RECEIVED_ROLE, RoleTypes.ROLE_BY_NAME_SUCCESS],
|
||||
onFailure: RoleTypes.ROLE_BY_NAME_FAILURE,
|
||||
params: [
|
||||
roleName,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getRole(roleId: string) {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getRole,
|
||||
onRequest: RoleTypes.ROLE_BY_ID_REQUEST,
|
||||
onSuccess: [RoleTypes.RECEIVED_ROLE, RoleTypes.ROLE_BY_ID_SUCCESS],
|
||||
onFailure: RoleTypes.ROLE_BY_ID_FAILURE,
|
||||
params: [
|
||||
roleId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function editRole(role: Role) {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.patchRole,
|
||||
onRequest: RoleTypes.EDIT_ROLE_REQUEST,
|
||||
onSuccess: [RoleTypes.RECEIVED_ROLE, RoleTypes.EDIT_ROLE_SUCCESS],
|
||||
onFailure: RoleTypes.EDIT_ROLE_FAILURE,
|
||||
params: [
|
||||
role.id,
|
||||
role,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function loadRolesIfNeeded(roles: Iterable<string>): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const state = getState();
|
||||
|
|
|
|||
|
|
@ -1,104 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import assert from 'assert';
|
||||
import nock from 'nock';
|
||||
|
||||
import * as Actions from '@mm-redux/actions/schemes';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
||||
describe('Actions.Schemes', () => {
|
||||
let store;
|
||||
|
||||
beforeAll(async () => {
|
||||
await TestHelper.initBasic(Client4);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
store = await configureStore();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await TestHelper.tearDown();
|
||||
});
|
||||
|
||||
it('getSchemes', async () => {
|
||||
const mockScheme = TestHelper.basicScheme;
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/schemes').
|
||||
query(true).
|
||||
reply(200, [mockScheme]);
|
||||
|
||||
await Actions.getSchemes()(store.dispatch, store.getState);
|
||||
const {schemes} = store.getState().entities.schemes;
|
||||
|
||||
assert.ok(Object.keys(schemes).length > 0);
|
||||
});
|
||||
|
||||
it('createScheme', async () => {
|
||||
const mockScheme = TestHelper.basicScheme;
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/schemes').
|
||||
reply(201, mockScheme);
|
||||
await Actions.createScheme(TestHelper.mockScheme())(store.dispatch, store.getState);
|
||||
|
||||
const {schemes} = store.getState().entities.schemes;
|
||||
|
||||
const schemeId = Object.keys(schemes)[0];
|
||||
assert.strictEqual(Object.keys(schemes).length, 1);
|
||||
assert.strictEqual(mockScheme.id, schemeId);
|
||||
});
|
||||
|
||||
it('getScheme', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/schemes/' + TestHelper.basicScheme.id).
|
||||
reply(200, TestHelper.basicScheme);
|
||||
|
||||
await Actions.getScheme(TestHelper.basicScheme.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const {schemes} = state.entities.schemes;
|
||||
|
||||
assert.equal(schemes[TestHelper.basicScheme.id].name, TestHelper.basicScheme.name);
|
||||
});
|
||||
|
||||
it('patchScheme', async () => {
|
||||
const patchData = {name: 'The Updated Scheme', description: 'This is a scheme created by unit tests'};
|
||||
const scheme = {
|
||||
...TestHelper.basicScheme,
|
||||
...patchData,
|
||||
};
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put('/schemes/' + TestHelper.basicScheme.id + '/patch').
|
||||
reply(200, scheme);
|
||||
|
||||
await Actions.patchScheme(TestHelper.basicScheme.id, scheme)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const {schemes} = state.entities.schemes;
|
||||
|
||||
const updated = schemes[TestHelper.basicScheme.id];
|
||||
assert.ok(updated);
|
||||
assert.strictEqual(updated.name, patchData.name);
|
||||
assert.strictEqual(updated.description, patchData.description);
|
||||
});
|
||||
|
||||
it('deleteScheme', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
delete('/schemes/' + TestHelper.basicScheme.id).
|
||||
reply(200, {status: 'OK'});
|
||||
|
||||
await Actions.deleteScheme(TestHelper.basicScheme.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const {schemes} = state.entities.schemes;
|
||||
|
||||
assert.notStrictEqual(schemes, {});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {SchemeTypes} from '@mm-redux/action_types';
|
||||
import {General} from '../constants';
|
||||
|
||||
import {Scheme, SchemeScope, SchemePatch} from '@mm-redux/types/schemes';
|
||||
|
||||
import {ActionFunc, DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
|
||||
|
||||
import {bindClientFunc, forceLogoutIfNecessary} from './helpers';
|
||||
import {logError} from './errors';
|
||||
export function getScheme(schemeId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getScheme,
|
||||
onSuccess: [SchemeTypes.RECEIVED_SCHEME],
|
||||
params: [
|
||||
schemeId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getSchemes(scope: SchemeScope, page = 0, perPage: number = General.PAGE_SIZE_DEFAULT): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getSchemes,
|
||||
onSuccess: [SchemeTypes.RECEIVED_SCHEMES],
|
||||
params: [
|
||||
scope,
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function createScheme(scheme: Scheme): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.createScheme,
|
||||
onSuccess: [SchemeTypes.CREATED_SCHEME],
|
||||
params: [
|
||||
scheme,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteScheme(schemeId: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let data = null;
|
||||
try {
|
||||
data = await Client4.deleteScheme(schemeId);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch({type: SchemeTypes.DELETED_SCHEME, data: {schemeId}});
|
||||
|
||||
return {data};
|
||||
};
|
||||
}
|
||||
|
||||
export function patchScheme(schemeId: string, scheme: SchemePatch): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.patchScheme,
|
||||
onSuccess: [SchemeTypes.PATCHED_SCHEME],
|
||||
params: [
|
||||
schemeId,
|
||||
scheme,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getSchemeTeams(schemeId: string, page = 0, perPage: number = General.PAGE_SIZE_DEFAULT): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getSchemeTeams,
|
||||
onSuccess: [SchemeTypes.RECEIVED_SCHEME_TEAMS],
|
||||
params: [
|
||||
schemeId,
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getSchemeChannels(schemeId: string, page = 0, perPage: number = General.PAGE_SIZE_DEFAULT): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getSchemeChannels,
|
||||
onSuccess: [SchemeTypes.RECEIVED_SCHEME_CHANNELS],
|
||||
params: [
|
||||
schemeId,
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import assert from 'assert';
|
|||
import nock from 'nock';
|
||||
|
||||
import * as Actions from '@mm-redux/actions/search';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {SearchTypes} from '@mm-redux/action_types';
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
import {getCurrentUserId, getCurrentUserMentionKeys} from '@mm-redux/selectors/entities/users';
|
||||
|
|
|
|||
|
|
@ -3,12 +3,11 @@
|
|||
|
||||
import assert from 'assert';
|
||||
import nock from 'nock';
|
||||
import fs from 'fs';
|
||||
|
||||
import * as Actions from '@mm-redux/actions/teams';
|
||||
import {login} from '@mm-redux/actions/users';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {General, RequestStatus} from '../constants';
|
||||
import {Client4} from '@client/rest';
|
||||
import {RequestStatus} from '../constants';
|
||||
import {GeneralTypes} from '@mm-redux/action_types';
|
||||
import TestHelper from 'test/test_helper';
|
||||
import configureStore from 'test/test_store';
|
||||
|
|
@ -336,19 +335,6 @@ describe('Actions.Teams', () => {
|
|||
assert.ok(Object.prototype.hasOwnProperty.call(member, 'mention_count'));
|
||||
});
|
||||
|
||||
it('getTeamMembersForUser', async () => {
|
||||
nock(Client4.getUserRoute(TestHelper.basicUser.id)).
|
||||
get('/teams/members').
|
||||
reply(200, [{user_id: TestHelper.basicUser.id, team_id: TestHelper.basicTeam.id}]);
|
||||
await Actions.getTeamMembersForUser(TestHelper.basicUser.id)(store.dispatch, store.getState);
|
||||
|
||||
const membersInTeam = store.getState().entities.teams.membersInTeam;
|
||||
|
||||
assert.ok(membersInTeam);
|
||||
assert.ok(membersInTeam[TestHelper.basicTeam.id]);
|
||||
assert.ok(membersInTeam[TestHelper.basicTeam.id][TestHelper.basicUser.id]);
|
||||
});
|
||||
|
||||
it('getTeamMember', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
|
|
@ -406,44 +392,6 @@ describe('Actions.Teams', () => {
|
|||
assert.ok(membersInTeam[TestHelper.basicTeam.id][user2.id]);
|
||||
});
|
||||
|
||||
it('getTeamMembersByIds', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
query(true).
|
||||
reply(201, TestHelper.fakeUserWithId());
|
||||
const user1 = await TestHelper.basicClient4.createUser(
|
||||
TestHelper.fakeUser(),
|
||||
null,
|
||||
null,
|
||||
TestHelper.basicTeam.invite_id,
|
||||
);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
query(true).
|
||||
reply(201, TestHelper.fakeUserWithId());
|
||||
const user2 = await TestHelper.basicClient4.createUser(
|
||||
TestHelper.fakeUser(),
|
||||
null,
|
||||
null,
|
||||
TestHelper.basicTeam.invite_id,
|
||||
);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post(`/teams/${TestHelper.basicTeam.id}/members/ids`).
|
||||
reply(200, [{user_id: user1.id, team_id: TestHelper.basicTeam.id}, {user_id: user2.id, team_id: TestHelper.basicTeam.id}]);
|
||||
await Actions.getTeamMembersByIds(
|
||||
TestHelper.basicTeam.id,
|
||||
[user1.id, user2.id],
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const members = store.getState().entities.teams.membersInTeam;
|
||||
|
||||
assert.ok(members[TestHelper.basicTeam.id]);
|
||||
assert.ok(members[TestHelper.basicTeam.id][user1.id]);
|
||||
assert.ok(members[TestHelper.basicTeam.id][user2.id]);
|
||||
});
|
||||
|
||||
it('getTeamStats', async () => {
|
||||
nock(Client4.getTeamRoute(TestHelper.basicTeam.id)).
|
||||
get('/stats').
|
||||
|
|
@ -475,33 +423,6 @@ describe('Actions.Teams', () => {
|
|||
assert.ok(members[TestHelper.basicTeam.id][user.id]);
|
||||
});
|
||||
|
||||
it('addUsersToTeam', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
reply(201, TestHelper.fakeUserWithId());
|
||||
const user = await TestHelper.basicClient4.createUser(TestHelper.fakeUser());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
reply(201, TestHelper.fakeUserWithId());
|
||||
const user2 = await TestHelper.basicClient4.createUser(TestHelper.fakeUser());
|
||||
|
||||
nock(Client4.getTeamRoute(TestHelper.basicTeam.id)).
|
||||
post('/members/batch').
|
||||
reply(201, [{user_id: user.id, team_id: TestHelper.basicTeam.id}, {user_id: user2.id, team_id: TestHelper.basicTeam.id}]);
|
||||
await Actions.addUsersToTeam(TestHelper.basicTeam.id, [user.id, user2.id])(store.dispatch, store.getState);
|
||||
|
||||
const members = store.getState().entities.teams.membersInTeam;
|
||||
const profilesInTeam = store.getState().entities.users.profilesInTeam;
|
||||
|
||||
assert.ok(members[TestHelper.basicTeam.id]);
|
||||
assert.ok(members[TestHelper.basicTeam.id][user.id]);
|
||||
assert.ok(members[TestHelper.basicTeam.id][user2.id]);
|
||||
assert.ok(profilesInTeam[TestHelper.basicTeam.id]);
|
||||
assert.ok(profilesInTeam[TestHelper.basicTeam.id].has(user.id));
|
||||
assert.ok(profilesInTeam[TestHelper.basicTeam.id].has(user2.id));
|
||||
});
|
||||
|
||||
describe('removeUserFromTeam', () => {
|
||||
const team = {id: 'team'};
|
||||
const user = {id: 'user'};
|
||||
|
|
@ -597,174 +518,4 @@ describe('Actions.Teams', () => {
|
|||
expect(state.entities.channels.currentChannelId).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
it('updateTeamMemberRoles', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
reply(201, TestHelper.fakeUserWithId());
|
||||
const user = await TestHelper.basicClient4.createUser(TestHelper.fakeUser());
|
||||
|
||||
nock(Client4.getTeamRoute(TestHelper.basicTeam.id)).
|
||||
post('/members').
|
||||
reply(201, {user_id: user.id, team_id: TestHelper.basicTeam.id});
|
||||
await Actions.addUserToTeam(TestHelper.basicTeam.id, user.id)(store.dispatch, store.getState);
|
||||
|
||||
const roles = General.TEAM_USER_ROLE + ' ' + General.TEAM_ADMIN_ROLE;
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/teams/${TestHelper.basicTeam.id}/members/${user.id}/roles`).
|
||||
reply(200, {user_id: user.id, team_id: TestHelper.basicTeam.id, roles});
|
||||
await Actions.updateTeamMemberRoles(TestHelper.basicTeam.id, user.id, roles)(store.dispatch, store.getState);
|
||||
|
||||
const members = store.getState().entities.teams.membersInTeam;
|
||||
|
||||
assert.ok(members[TestHelper.basicTeam.id]);
|
||||
assert.ok(members[TestHelper.basicTeam.id][user.id]);
|
||||
assert.ok(members[TestHelper.basicTeam.id][user.id].roles === roles);
|
||||
});
|
||||
|
||||
it('sendEmailInvitesToTeam', async () => {
|
||||
nock(Client4.getTeamRoute(TestHelper.basicTeam.id)).
|
||||
post('/invite/email').
|
||||
reply(200, OK_RESPONSE);
|
||||
const {data} = await Actions.sendEmailInvitesToTeam(TestHelper.basicTeam.id, ['fakeemail1@example.com', 'fakeemail2@example.com'])(store.dispatch, store.getState);
|
||||
assert.deepEqual(data, OK_RESPONSE);
|
||||
});
|
||||
|
||||
it('checkIfTeamExists', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
get(`/teams/name/${TestHelper.basicTeam.name}/exists`).
|
||||
reply(200, {exists: true});
|
||||
|
||||
let {data: exists} = await Actions.checkIfTeamExists(TestHelper.basicTeam.name)(store.dispatch, store.getState);
|
||||
|
||||
assert.ok(exists === true);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/teams/name/junk/exists').
|
||||
reply(200, {exists: false});
|
||||
const {data} = await Actions.checkIfTeamExists('junk')(store.dispatch, store.getState);
|
||||
exists = data;
|
||||
|
||||
assert.ok(exists === false);
|
||||
});
|
||||
|
||||
it('setTeamIcon', async () => {
|
||||
TestHelper.mockLogin();
|
||||
await login(TestHelper.basicUser.email, 'password1')(store.dispatch, store.getState);
|
||||
|
||||
const team = TestHelper.basicTeam;
|
||||
const imageData = fs.createReadStream('test/assets/images/test.png');
|
||||
|
||||
nock(Client4.getTeamRoute(team.id)).
|
||||
post('/image').
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
const {data} = await Actions.setTeamIcon(team.id, imageData)(store.dispatch, store.getState);
|
||||
assert.deepEqual(data, OK_RESPONSE);
|
||||
});
|
||||
|
||||
it('removeTeamIcon', async () => {
|
||||
TestHelper.mockLogin();
|
||||
await login(TestHelper.basicUser.email, 'password1')(store.dispatch, store.getState);
|
||||
|
||||
const team = TestHelper.basicTeam;
|
||||
|
||||
nock(Client4.getTeamRoute(team.id)).
|
||||
delete('/image').
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
const {data} = await Actions.removeTeamIcon(team.id)(store.dispatch, store.getState);
|
||||
assert.deepEqual(data, OK_RESPONSE);
|
||||
});
|
||||
|
||||
it('updateTeamScheme', async () => {
|
||||
TestHelper.mockLogin();
|
||||
await login(TestHelper.basicUser.email, 'password1')(store.dispatch, store.getState);
|
||||
|
||||
const schemeId = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
|
||||
const {id} = TestHelper.basicTeam;
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put('/teams/' + id + '/scheme').
|
||||
reply(200, OK_RESPONSE);
|
||||
|
||||
await Actions.updateTeamScheme(id, schemeId)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const {teams} = state.entities.teams;
|
||||
|
||||
const updated = teams[id];
|
||||
assert.ok(updated);
|
||||
assert.equal(updated.scheme_id, schemeId);
|
||||
});
|
||||
|
||||
it('membersMinusGroupMembers', async () => {
|
||||
const teamID = 'tid10000000000000000000000';
|
||||
const groupIDs = ['gid10000000000000000000000', 'gid20000000000000000000000'];
|
||||
const page = 4;
|
||||
const perPage = 63;
|
||||
|
||||
nock(Client4.getBaseRoute()).get(
|
||||
`/teams/${teamID}/members_minus_group_members?group_ids=${groupIDs.join(',')}&page=${page}&per_page=${perPage}`).
|
||||
reply(200, {users: [], total_count: 0});
|
||||
|
||||
const {error} = await Actions.membersMinusGroupMembers(teamID, groupIDs, page, perPage)(store.dispatch, store.getState);
|
||||
|
||||
assert.equal(error, null);
|
||||
});
|
||||
|
||||
it('searchTeams', async () => {
|
||||
const userClient = TestHelper.createClient();
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
query(true).
|
||||
reply(201, TestHelper.fakeUserWithId());
|
||||
|
||||
const user = await TestHelper.basicClient4.createUser(
|
||||
TestHelper.fakeUser(),
|
||||
null,
|
||||
null,
|
||||
TestHelper.basicTeam.invite_id,
|
||||
);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users/login').
|
||||
reply(200, user);
|
||||
|
||||
await userClient.login(user.email, 'password1');
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams').
|
||||
reply(201, TestHelper.fakeTeamWithId());
|
||||
|
||||
const userTeam = await userClient.createTeam(
|
||||
TestHelper.fakeTeam(),
|
||||
);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams/search').
|
||||
reply(200, [TestHelper.basicTeam, userTeam]);
|
||||
|
||||
await store.dispatch(Actions.searchTeams('test', 0));
|
||||
|
||||
const moreRequest = store.getState().requests.teams.getTeams;
|
||||
if (moreRequest.status === RequestStatus.FAILURE) {
|
||||
throw new Error(JSON.stringify(moreRequest.error));
|
||||
}
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams/search').
|
||||
reply(200, {teams: [TestHelper.basicTeam, userTeam], total_count: 2});
|
||||
|
||||
const response = await store.dispatch(Actions.searchTeams('test', '', false, true));
|
||||
|
||||
const paginatedRequest = store.getState().requests.teams.getTeams;
|
||||
if (paginatedRequest.status === RequestStatus.FAILURE) {
|
||||
throw new Error(JSON.stringify(paginatedRequest.error));
|
||||
}
|
||||
|
||||
assert.ok(response.data.teams.length === 2);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {Client4} from '@client/rest';
|
||||
import {General} from '../constants';
|
||||
import {ChannelTypes, RoleTypes, TeamTypes, UserTypes} from '@mm-redux/action_types';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
|
|
@ -12,14 +12,13 @@ import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
|||
|
||||
import {GetStateFunc, DispatchFunc, ActionFunc, ActionResult, batchActions, Action} from '@mm-redux/types/actions';
|
||||
|
||||
import {Team, TeamMembership, TeamMemberWithError} from '@mm-redux/types/teams';
|
||||
import {Team} from '@mm-redux/types/teams';
|
||||
|
||||
import {selectChannel} from './channels';
|
||||
import {logError} from './errors';
|
||||
import {bindClientFunc, forceLogoutIfNecessary} from './helpers';
|
||||
import {getProfilesByIds, getStatusesByIds} from './users';
|
||||
import {loadRolesIfNeeded} from './roles';
|
||||
import {UserProfile} from '@mm-redux/types/users';
|
||||
|
||||
async function getProfilesAndStatusesForMembers(userIds: string[], dispatch: DispatchFunc, getState: GetStateFunc) {
|
||||
const {
|
||||
|
|
@ -103,13 +102,10 @@ export function getTeams(page = 0, perPage: number = General.TEAMS_CHUNK_SIZE, i
|
|||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let data;
|
||||
|
||||
dispatch({type: TeamTypes.GET_TEAMS_REQUEST, data});
|
||||
|
||||
try {
|
||||
data = await Client4.getTeams(page, perPage, includeTotalCount);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch({type: TeamTypes.GET_TEAMS_FAILURE, data});
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
|
@ -117,7 +113,7 @@ export function getTeams(page = 0, perPage: number = General.TEAMS_CHUNK_SIZE, i
|
|||
const actions: Action[] = [
|
||||
{
|
||||
type: TeamTypes.RECEIVED_TEAMS_LIST,
|
||||
data: includeTotalCount ? data.teams : data,
|
||||
data: (includeTotalCount ? data.teams : data),
|
||||
},
|
||||
{
|
||||
type: TeamTypes.GET_TEAMS_SUCCESS,
|
||||
|
|
@ -138,38 +134,6 @@ export function getTeams(page = 0, perPage: number = General.TEAMS_CHUNK_SIZE, i
|
|||
};
|
||||
}
|
||||
|
||||
export function searchTeams(term: string, page?: number, perPage?: number): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
dispatch({type: TeamTypes.GET_TEAMS_REQUEST, data: null});
|
||||
|
||||
let response;
|
||||
try {
|
||||
response = await Client4.searchTeams(term, page, perPage);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(batchActions([
|
||||
{type: TeamTypes.GET_TEAMS_FAILURE, error},
|
||||
logError(error),
|
||||
]));
|
||||
return {error};
|
||||
}
|
||||
|
||||
const teams = response.teams || response;
|
||||
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: TeamTypes.RECEIVED_TEAMS_LIST,
|
||||
data: teams,
|
||||
},
|
||||
{
|
||||
type: TeamTypes.GET_TEAMS_SUCCESS,
|
||||
},
|
||||
], 'BATCH_SEARCH_TEAMS'));
|
||||
|
||||
return {data: response};
|
||||
};
|
||||
}
|
||||
|
||||
export function createTeam(team: Team): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let created;
|
||||
|
|
@ -263,16 +227,6 @@ export function patchTeam(team: Team): ActionFunc {
|
|||
});
|
||||
}
|
||||
|
||||
export function regenerateTeamInviteId(teamId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.regenerateTeamInviteId,
|
||||
onSuccess: TeamTypes.REGENERATED_TEAM_INVITE_ID,
|
||||
params: [
|
||||
teamId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getMyTeamMembers(): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const getMyTeamMembersFunc = bindClientFunc({
|
||||
|
|
@ -301,9 +255,7 @@ export function getMyTeamMembers(): ActionFunc {
|
|||
export function getTeamMembers(teamId: string, page = 0, perPage: number = General.TEAMS_CHUNK_SIZE): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getTeamMembers,
|
||||
onRequest: TeamTypes.GET_TEAM_MEMBERS_REQUEST,
|
||||
onSuccess: [TeamTypes.RECEIVED_MEMBERS_IN_TEAM, TeamTypes.GET_TEAM_MEMBERS_SUCCESS],
|
||||
onFailure: TeamTypes.GET_TEAM_MEMBERS_FAILURE,
|
||||
onSuccess: TeamTypes.RECEIVED_MEMBERS_IN_TEAM,
|
||||
params: [
|
||||
teamId,
|
||||
page,
|
||||
|
|
@ -336,30 +288,6 @@ export function getTeamMember(teamId: string, userId: string): ActionFunc {
|
|||
};
|
||||
}
|
||||
|
||||
export function getTeamMembersByIds(teamId: string, userIds: Array<string>): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let members;
|
||||
try {
|
||||
const membersRequest = Client4.getTeamMembersByIds(teamId, userIds);
|
||||
|
||||
getProfilesAndStatusesForMembers(userIds, dispatch, getState);
|
||||
|
||||
members = await membersRequest;
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: TeamTypes.RECEIVED_MEMBERS_IN_TEAM,
|
||||
data: members,
|
||||
});
|
||||
|
||||
return {data: members};
|
||||
};
|
||||
}
|
||||
|
||||
export function getTeamsForUser(userId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getTeamsForUser,
|
||||
|
|
@ -372,16 +300,6 @@ export function getTeamsForUser(userId: string): ActionFunc {
|
|||
});
|
||||
}
|
||||
|
||||
export function getTeamMembersForUser(userId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getTeamMembersForUser,
|
||||
onSuccess: TeamTypes.RECEIVED_TEAM_MEMBERS,
|
||||
params: [
|
||||
userId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getTeamStats(teamId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getTeamStats,
|
||||
|
|
@ -392,19 +310,6 @@ export function getTeamStats(teamId: string): ActionFunc {
|
|||
});
|
||||
}
|
||||
|
||||
export function addUserToTeamFromInvite(token: string, inviteId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.addToTeamFromInvite,
|
||||
onRequest: TeamTypes.ADD_TO_TEAM_FROM_INVITE_REQUEST,
|
||||
onSuccess: TeamTypes.ADD_TO_TEAM_FROM_INVITE_SUCCESS,
|
||||
onFailure: TeamTypes.ADD_TO_TEAM_FROM_INVITE_FAILURE,
|
||||
params: [
|
||||
token,
|
||||
inviteId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function addUserToTeam(teamId: string, userId: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let member;
|
||||
|
|
@ -458,66 +363,6 @@ export function addUserToTeam(teamId: string, userId: string): ActionFunc {
|
|||
};
|
||||
}
|
||||
|
||||
export function addUsersToTeam(teamId: string, userIds: Array<string>): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let members;
|
||||
try {
|
||||
members = await Client4.addUsersToTeam(teamId, userIds);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
const profiles: Partial<UserProfile>[] = [];
|
||||
members.forEach((m: TeamMembership) => profiles.push({id: m.user_id}));
|
||||
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: UserTypes.RECEIVED_PROFILES_LIST_IN_TEAM,
|
||||
data: profiles,
|
||||
id: teamId,
|
||||
},
|
||||
{
|
||||
type: TeamTypes.RECEIVED_MEMBERS_IN_TEAM,
|
||||
data: members,
|
||||
},
|
||||
], 'BATCH_ADD_USERS_TO_TEAM'));
|
||||
|
||||
return {data: members};
|
||||
};
|
||||
}
|
||||
|
||||
export function addUsersToTeamGracefully(teamId: string, userIds: Array<string>): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let result: Array<TeamMemberWithError>;
|
||||
try {
|
||||
result = await Client4.addUsersToTeamGracefully(teamId, userIds);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
const addedMembers = result ? result.filter((m) => !m.error) : [];
|
||||
const profiles: Partial<UserProfile>[] = addedMembers.map((m) => ({id: m.user_id}));
|
||||
const members = addedMembers.map((m) => m.member);
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: UserTypes.RECEIVED_PROFILES_LIST_IN_TEAM,
|
||||
data: profiles,
|
||||
id: teamId,
|
||||
},
|
||||
{
|
||||
type: TeamTypes.RECEIVED_MEMBERS_IN_TEAM,
|
||||
data: members,
|
||||
},
|
||||
], 'BATCH_ADD_USERS_TO_TEAM_GRACEFULLY'));
|
||||
|
||||
return {data: result};
|
||||
};
|
||||
}
|
||||
|
||||
export function removeUserFromTeam(teamId: string, userId: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
try {
|
||||
|
|
@ -572,98 +417,6 @@ export function removeUserFromTeam(teamId: string, userId: string): ActionFunc {
|
|||
};
|
||||
}
|
||||
|
||||
export function updateTeamMemberRoles(teamId: string, userId: string, roles: string[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
try {
|
||||
await Client4.updateTeamMemberRoles(teamId, userId, roles);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
const membersInTeam = getState().entities.teams.membersInTeam[teamId];
|
||||
if (membersInTeam && membersInTeam[userId]) {
|
||||
dispatch({
|
||||
type: TeamTypes.RECEIVED_MEMBER_IN_TEAM,
|
||||
data: {...membersInTeam[userId], roles},
|
||||
});
|
||||
}
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function sendEmailInvitesToTeam(teamId: string, emails: Array<string>): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.sendEmailInvitesToTeam,
|
||||
params: [
|
||||
teamId,
|
||||
emails,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function sendEmailGuestInvitesToChannels(teamId: string, channelIds: Array<string>, emails: Array<string>, message: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.sendEmailGuestInvitesToChannels,
|
||||
params: [
|
||||
teamId,
|
||||
channelIds,
|
||||
emails,
|
||||
message,
|
||||
],
|
||||
});
|
||||
}
|
||||
export function sendEmailInvitesToTeamGracefully(teamId: string, emails: Array<string>): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.sendEmailInvitesToTeamGracefully,
|
||||
params: [
|
||||
teamId,
|
||||
emails,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function sendEmailGuestInvitesToChannelsGracefully(teamId: string, channelIds: Array<string>, emails: Array<string>, message: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.sendEmailGuestInvitesToChannelsGracefully,
|
||||
params: [
|
||||
teamId,
|
||||
channelIds,
|
||||
emails,
|
||||
message,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function getTeamInviteInfo(inviteId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getTeamInviteInfo,
|
||||
onRequest: TeamTypes.TEAM_INVITE_INFO_REQUEST,
|
||||
onSuccess: TeamTypes.TEAM_INVITE_INFO_SUCCESS,
|
||||
onFailure: TeamTypes.TEAM_INVITE_INFO_FAILURE,
|
||||
params: [
|
||||
inviteId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function checkIfTeamExists(teamName: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let data;
|
||||
try {
|
||||
data = await Client4.checkIfTeamExists(teamName);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(logError(error));
|
||||
return {error};
|
||||
}
|
||||
|
||||
return {data: data.exists};
|
||||
};
|
||||
}
|
||||
|
||||
export function joinTeam(inviteId: string, teamId: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
dispatch({type: TeamTypes.JOIN_TEAM_REQUEST, data: null});
|
||||
|
|
@ -696,66 +449,3 @@ export function joinTeam(inviteId: string, teamId: string): ActionFunc {
|
|||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function setTeamIcon(teamId: string, imageData: any): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.setTeamIcon,
|
||||
params: [
|
||||
teamId,
|
||||
imageData,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function removeTeamIcon(teamId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.removeTeamIcon,
|
||||
params: [
|
||||
teamId,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function updateTeamScheme(teamId: string, schemeId: string): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: async () => {
|
||||
await Client4.updateTeamScheme(teamId, schemeId);
|
||||
return {teamId, schemeId};
|
||||
},
|
||||
onSuccess: TeamTypes.UPDATED_TEAM_SCHEME,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateTeamMemberSchemeRoles(
|
||||
teamId: string,
|
||||
userId: string,
|
||||
isSchemeUser: boolean,
|
||||
isSchemeAdmin: boolean,
|
||||
): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: async () => {
|
||||
await Client4.updateTeamMemberSchemeRoles(teamId, userId, isSchemeUser, isSchemeAdmin);
|
||||
return {teamId, userId, isSchemeUser, isSchemeAdmin};
|
||||
},
|
||||
onSuccess: TeamTypes.UPDATED_TEAM_MEMBER_SCHEME_ROLES,
|
||||
});
|
||||
}
|
||||
|
||||
export function invalidateAllEmailInvites(): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.invalidateAllEmailInvites,
|
||||
});
|
||||
}
|
||||
|
||||
export function membersMinusGroupMembers(teamID: string, groupIDs: Array<string>, page = 0, perPage: number = General.PROFILE_CHUNK_SIZE): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.teamMembersMinusGroupMembers,
|
||||
onSuccess: TeamTypes.RECEIVED_TEAM_MEMBERS_MINUS_GROUP_MEMBERS,
|
||||
params: [
|
||||
teamID,
|
||||
groupIDs,
|
||||
page,
|
||||
perPage,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue