MM-35355 Detox/E2E: Add e2e for channels settings (#5377)

* MM-35355 Detox/E2E: Add e2e for channels settings

* Added disabling of non prepackaged plugins to init

* Fix apiGetChannelByName doc parameter
This commit is contained in:
Joseph Baylon 2021-05-12 08:04:01 -07:00 committed by GitHub
parent 288c847518
commit 53050595dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 947 additions and 364 deletions

View file

@ -1,13 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {System, User} from '@support/server_api';
import {Plugin, System, User} from '@support/server_api';
beforeAll(async () => {
// Login as sysadmin and reset server configuration
await System.apiCheckSystemHealth();
await User.apiAdminLogin();
await System.apiUpdateConfig();
await Plugin.apiDisableNonPrepackagedPlugins();
await device.launchApp({
newInstance: false,

View file

@ -18,9 +18,29 @@ import {getResponseFromError} from './common';
// - return value defined by `@return`
// ****************************************************************
/**
* Add user to channel.
* See https://api.mattermost.com/#operation/AddChannelMember
* @param {string} userId - The ID of user to add into the channel
* @param {string} channelId - The channel ID
* @return {Object} returns {member} on success or {error, status} on error
*/
export const apiAddUserToChannel = async (userId, channelId) => {
try {
const response = await client.post(
`/api/v4/channels/${channelId}/members`,
{user_id: userId},
);
return {member: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Create a channel.
* See https://api.mattermost.com/#tag/channels/paths/~1channels/post
* See https://api.mattermost.com/#operation/CreateChannel
* @param {string} option.teamId - The team ID of the team to create the channel on
* @param {string} option.type - 'O' (default) for a public channel, 'P' for a private channel
* @param {string} option.prefix - option to add prefix to name and display name
@ -42,7 +62,7 @@ export const apiCreateChannel = async ({teamId = null, type = 'O', prefix = 'cha
/**
* Create a direct message channel.
* See https://api.mattermost.com/#tag/channels/paths/~1channels~1direct/post
* See https://api.mattermost.com/#operation/CreateDirectChannel
* @param {Array} userIds - the two user IDs to be in the direct message
* @return {Object} returns {channel} on success or {error, status} on error
*/
@ -61,7 +81,7 @@ export const apiCreateDirectChannel = async (userIds = []) => {
/**
* Create a group message channel.
* See https://api.mattermost.com/#tag/channels/paths/~1channels~1group/post
* See https://api.mattermost.com/#operation/CreateGroupChannel
* @param {Array} userIds - user IDs to be in the group message channel
* @return {Object} returns {channel} on success or {error, status} on error
*/
@ -78,46 +98,9 @@ export const apiCreateGroupChannel = async (userIds = []) => {
}
};
/**
* Get a channel by name and team name.
* See https://api.mattermost.com/#tag/channels/paths/~1teams~1name~1{team_name}~1channels~1name~1{channel_name}/get
* @param {string} teamName - team name
* @param {string} channelName - channel name
* @return {Object} returns {channel} on success or {error, status} on error
*/
export const apiGetChannelByName = async (teamName, channelName) => {
try {
const response = await client.get(`/api/v4/teams/name/${teamName}/channels/name/${channelName}`);
return {channel: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Add user to channel.
* See https://api.mattermost.com/#tag/channels/paths/~1channels~1{channel_id}~1members/post
* @param {string} userId - The ID of user to add into the channel
* @param {string} channelId - The channel ID
* @return {Object} returns {member} on success or {error, status} on error
*/
export const apiAddUserToChannel = async (userId, channelId) => {
try {
const response = await client.post(
`/api/v4/channels/${channelId}/members`,
{user_id: userId},
);
return {member: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Remove user from channel.
* See https://api.mattermost.com/#tag/channels/paths/~1channels~1{channel_id}~1members~1{user_id}/delete
* See https://api.mattermost.com/#operation/RemoveUserFromChannel
* @param {string} channelId - The channel ID
* @param {string} userId - The user ID to be removed from channel
* @return {Object} returns {status} on success or {error, status} on error
@ -134,9 +117,43 @@ export const apiDeleteUserFromChannel = async (channelId, userId) => {
}
};
/**
* Get a channel by name.
* See https://api.mattermost.com/#operation/GetChannelByName
* @param {string} teamId - team ID
* @param {string} channelName - channel name
* @return {Object} returns {channel} on success or {error, status} on error
*/
export const apiGetChannelByName = async (teamId, channelName) => {
try {
const response = await client.get(`/api/v4/teams/${teamId}/channels/name/${channelName}`);
return {channel: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Get a channel by name and team name.
* See https://api.mattermost.com/#operation/GetChannelByNameForTeamName
* @param {string} teamName - team name
* @param {string} channelName - channel name
* @return {Object} returns {channel} on success or {error, status} on error
*/
export const apiGetChannelByNameAndTeamName = async (teamName, channelName) => {
try {
const response = await client.get(`/api/v4/teams/name/${teamName}/channels/name/${channelName}`);
return {channel: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Get channels for user.
* See https://api.mattermost.com/#tag/channels/paths/~1users~1{user_id}~1teams~1{team_id}~1channels/get
* See https://api.mattermost.com/#operation/GetChannelsForTeamForUser
* @param {string} userId - The user ID
* @param {string} teamId - The team ID the user belongs to
* @return {Object} returns {channels} on success or {error, status} on error

View file

@ -20,7 +20,7 @@ import {getResponseFromError} from './common';
/**
* Synchronize any user attribute changes in the configured AD/LDAP server with Mattermost.
* See https://api.mattermost.com/#tag/LDAP/paths/~1ldap~1sync/post
* See https://api.mattermost.com/#operation/SyncLdap
* @return {string} returns {status} on success or {error, status} on error
*/
export const apiLDAPSync = async () => {
@ -35,7 +35,7 @@ export const apiLDAPSync = async () => {
/**
* Test the current AD/LDAP configuration to see if the AD/LDAP server can be contacted successfully.
* See https://api.mattermost.com/#tag/LDAP/paths/~1ldap~1test/post
* See https://api.mattermost.com/#operation/TestLdap
* @return {string} returns {status} on success or {error, status} on error
*/
export const apiLDAPTest = async () => {

View file

@ -18,87 +18,6 @@ import {apiUploadFile, getResponseFromError} from './common';
// - return value defined by `@return`
// ****************************************************************
/**
* Get plugins.
* See https://api.mattermost.com/#tag/plugins/paths/~1plugins/get
* @return {Object} returns {plugins} on success or {error, status} on error
*/
export const apiGetAllPlugins = async () => {
try {
const response = await client.get('/api/v4/plugins');
return {plugins: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Upload plugin.
* See https://api.mattermost.com/#tag/plugins/paths/~1plugins/post
* @param {string} filename - the filename of plugin to be uploaded
* @return {Object} returns response on success or {error, status} on error
*/
export const apiUploadPlugin = async (filename) => {
try {
const absFilePath = path.resolve(__dirname, `../../support/fixtures/${filename}`);
const response = await apiUploadFile('plugin', absFilePath, {url: '/api/v4/plugins', method: 'POST'});
return response;
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Install plugin from URL.
* See https://api.mattermost.com/#tag/plugins/paths/~1plugins~1install_from_url/post
* @param {string} pluginDownloadUrl - URL used to download the plugin
* @param {string} force - Set to 'true' to overwrite a previously installed plugin with the same ID, if any
* @return {Object} returns {plugin} on success or {error, status} on error
*/
export const apiInstallPluginFromUrl = async (pluginDownloadUrl, force = false) => {
try {
const response = await client.post(`/api/v4/plugins/install_from_url?plugin_download_url=${encodeURIComponent(pluginDownloadUrl)}&force=${force}`);
return {plugin: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Enable plugin.
* See https://api.mattermost.com/#tag/plugins/paths/~1plugins~1{plugin_id}~1enable/post
* @param {string} pluginId - the plugin ID
* @return {Object} returns response on success or {error, status} on error
*/
export const apiEnablePluginById = async (pluginId) => {
try {
const response = await client.post(`/api/v4/plugins/${encodeURIComponent(pluginId)}/enable`);
return response;
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Disable plugin.
* See https://api.mattermost.com/#tag/plugins/paths/~1plugins~1{plugin_id}~1disable/post
* @param {string} pluginId - the plugin ID
* @return {Object} returns response on success or {error, status} on error
*/
export const apiDisablePluginById = async (pluginId) => {
try {
const response = await client.post(`/api/v4/plugins/${encodeURIComponent(pluginId)}/disable`);
return response;
} catch (err) {
return getResponseFromError(err);
}
};
const prepackagedPlugins = [
'antivirus',
'mattermost-autolink',
@ -120,6 +39,9 @@ const prepackagedPlugins = [
*/
export const apiDisableNonPrepackagedPlugins = async () => {
const {plugins} = await apiGetAllPlugins();
if (!plugins) {
return;
}
plugins.active.forEach(async (plugin) => {
if (!prepackagedPlugins.includes(plugin.id)) {
await apiDisablePluginById(plugin.id);
@ -127,9 +49,73 @@ export const apiDisableNonPrepackagedPlugins = async () => {
});
};
/**
* Disable plugin.
* See https://api.mattermost.com/#operation/DisablePlugin
* @param {string} pluginId - the plugin ID
* @return {Object} returns response on success or {error, status} on error
*/
export const apiDisablePluginById = async (pluginId) => {
try {
const response = await client.post(`/api/v4/plugins/${encodeURIComponent(pluginId)}/disable`);
return response;
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Enable plugin.
* See https://api.mattermost.com/#operation/EnablePlugin
* @param {string} pluginId - the plugin ID
* @return {Object} returns response on success or {error, status} on error
*/
export const apiEnablePluginById = async (pluginId) => {
try {
const response = await client.post(`/api/v4/plugins/${encodeURIComponent(pluginId)}/enable`);
return response;
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Get plugins.
* See https://api.mattermost.com/#operation/GetPlugins
* @return {Object} returns {plugins} on success or {error, status} on error
*/
export const apiGetAllPlugins = async () => {
try {
const response = await client.get('/api/v4/plugins');
return {plugins: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Install plugin from URL.
* See https://api.mattermost.com/#operation/InstallPluginFromUrl
* @param {string} pluginDownloadUrl - URL used to download the plugin
* @param {string} force - Set to 'true' to overwrite a previously installed plugin with the same ID, if any
* @return {Object} returns {plugin} on success or {error, status} on error
*/
export const apiInstallPluginFromUrl = async (pluginDownloadUrl, force = false) => {
try {
const response = await client.post(`/api/v4/plugins/install_from_url?plugin_download_url=${encodeURIComponent(pluginDownloadUrl)}&force=${force}`);
return {plugin: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Remove plugin.
* See https://api.mattermost.com/#tag/plugins/paths/~1plugins~1{plugin_id}/delete
* See https://api.mattermost.com/#operation/RemovePlugin
* @param {string} pluginId - the plugin ID
* @return {Object} returns response on success or {error, status} on error
*/
@ -142,3 +128,32 @@ export const apiRemovePluginById = async (pluginId) => {
return getResponseFromError(err);
}
};
/**
* Upload plugin.
* See https://api.mattermost.com/#operation/UploadPlugin
* @param {string} filename - the filename of plugin to be uploaded
* @return {Object} returns response on success or {error, status} on error
*/
export const apiUploadPlugin = async (filename) => {
try {
const absFilePath = path.resolve(__dirname, `../../support/fixtures/${filename}`);
const response = await apiUploadFile('plugin', absFilePath, {url: '/api/v4/plugins', method: 'POST'});
return response;
} catch (err) {
return getResponseFromError(err);
}
};
export const Plugin = {
apiDisableNonPrepackagedPlugins,
apiDisablePluginById,
apiEnablePluginById,
apiGetAllPlugins,
apiInstallPluginFromUrl,
apiRemovePluginById,
apiUploadPlugin,
};
export default Plugin;

View file

@ -5,8 +5,8 @@ import client from './client';
import {getResponseFromError} from './common';
// ****************************************************************
// Channels
// See https://api.mattermost.com/#tag/channels
// Posts
// See https://api.mattermost.com/#tag/posts
//
// Exported API function should have the following:
// - documented using JSDoc
@ -18,7 +18,7 @@ import {getResponseFromError} from './common';
/**
* Create a new post in a channel. To create the post as a comment on another post, provide root_id.
* See https://api.mattermost.com/#tag/posts/paths/~1posts/post
* See https://api.mattermost.com/#operation/CreatePost
* @param {string} option.channelId - The channel ID to post in
* @param {string} option.message - The message contents, can be formatted with Markdown
* @param {string} option.rootId - The post ID to comment on
@ -46,7 +46,7 @@ export const apiCreatePost = async ({channelId, message, rootId, props = {}, cre
/**
* Get posts for a channel.
* See https://api.mattermost.com/#tag/posts/paths/~1channels~1{channel_id}~1posts/get
* See https://api.mattermost.com/#operation/GetPostsForChannel
* @param {string} channelId - The channel ID to get the posts for
* @return {Object} returns {posts} on success or {error, status} on error
*/

View file

@ -16,26 +16,6 @@ import {getResponseFromError} from './common';
// - return value defined by `@return`
// ****************************************************************
/**
* Save the user's preferences.
* See https://api.mattermost.com/#tag/preferences/paths/~1users~1{user_id}~1preferences/put
* @param {string} userId - the user ID
* @param {Array} preferences - a list of user's preferences
* @return {string} returns {status} on success or {error, status} on error
*/
export const apiSaveUserPreferences = async (userId, preferences = []) => {
try {
const response = await client.put(
`/api/v4/users/${userId}/preferences`,
preferences,
);
return {status: response.status};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Save the user's favorite channel preference.
* @param {string} userId - the user ID
@ -70,6 +50,26 @@ export const apiSaveTeamsOrderPreference = (userId, orderedTeamIds = []) => {
return apiSaveUserPreferences(userId, [preference]);
};
/**
* Save the user's preferences.
* See https://api.mattermost.com/#operation/UpdatePreferences
* @param {string} userId - the user ID
* @param {Array} preferences - a list of user's preferences
* @return {string} returns {status} on success or {error, status} on error
*/
export const apiSaveUserPreferences = async (userId, preferences = []) => {
try {
const response = await client.put(
`/api/v4/users/${userId}/preferences`,
preferences,
);
return {status: response.status};
} catch (err) {
return getResponseFromError(err);
}
};
export const Preference = {
apiSaveFavoriteChannelPreference,
apiSaveTeamsOrderPreference,

View file

@ -18,7 +18,7 @@ import {getResponseFromError} from './common';
/**
* Get user status.
* See https://api.mattermost.com/#tag/status/paths/~1users~1{user_id}~1status/get
* See https://api.mattermost.com/#operation/GetUserStatus
* @param {string} userId - the user ID
* @return {Object} returns {userStatus} on success or {error, status} on error
*/
@ -34,7 +34,7 @@ export const apiGetUserStatus = async (userId) => {
/**
* Update user status.
* See https://api.mattermost.com/#tag/status/paths/~1users~1{user_id}~1status/put
* See https://api.mattermost.com/#operation/UpdateUserStatus
* @param {string} userId - the user ID
* @param {string} status - the user status, can be online, away, offline and dnd
* @return {Object} returns {userStatus} on success or {error, status} on error

View file

@ -37,7 +37,7 @@ export const apiCheckSystemHealth = async () => {
/**
* Send a test email.
* See https://api.mattermost.com/#tag/system/paths/~1email~1test/post
* See https://api.mattermost.com/#operation/TestEmail
* @return {Object} returns response on success or {error, status} on error
*/
export const apiEmailTest = async () => {
@ -49,58 +49,9 @@ export const apiEmailTest = async () => {
}
};
/**
* Get configuration.
* See https://api.mattermost.com/#tag/system/paths/~1config/get
* @return {Object} returns {config} on success or {error, status} on error
*/
export const apiGetConfig = async () => {
try {
const response = await client.get('/api/v4/config');
return {config: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Update configuration.
* See https://api.mattermost.com/#tag/system/paths/~1config/put
* @param {Object} newConfig - specific config to update
* @return {Object} returns {config} on success or {error, status} on error
*/
export const apiUpdateConfig = async (newConfig = {}) => {
try {
const {config: currentConfig} = await apiGetConfig();
const config = merge.all([currentConfig, getDefaultConfig(), newConfig]);
const response = await client.put(
'/api/v4/config',
config,
);
return {config: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
function getDefaultConfig() {
const fromEnv = {
LdapSettings: {
LdapServer: testConfig.ldapServer,
LdapPort: testConfig.ldapPort,
},
ServiceSettings: {SiteURL: testConfig.siteUrl},
};
return merge(defaultServerConfig, fromEnv);
}
/**
* Get client license.
* See https://api.mattermost.com/#tag/system/paths/~1license~1client/get
* See https://api.mattermost.com/#operation/GetClientLicense
* @return {Object} returns {license} on success or {error, status} on error
*/
export const apiGetClientLicense = async () => {
@ -113,9 +64,24 @@ export const apiGetClientLicense = async () => {
}
};
/**
* Get configuration.
* See https://api.mattermost.com/#operation/GetConfig
* @return {Object} returns {config} on success or {error, status} on error
*/
export const apiGetConfig = async () => {
try {
const response = await client.get('/api/v4/config');
return {config: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Ping server status.
* See https://api.mattermost.com/#tag/system/paths/~1system~1ping/get
* See https://api.mattermost.com/#operation/GetPing
* @return {Object} returns {data} on success or {error, status} on error
*/
export const apiPingServerStatus = async () => {
@ -127,14 +93,6 @@ export const apiPingServerStatus = async () => {
}
};
/**
* Require SMTP server to be running.
*/
export const apiRequireSMTPServer = async () => {
const {status} = await apiEmailTest();
jestExpect(status).toEqual(200);
};
/**
* Require server license to successfully continue.
* @return {Object} returns {license} on success or fail when no license
@ -179,8 +137,39 @@ export const apiRequireLicenseForFeature = async (key = '') => {
return {license};
};
/**
* Require SMTP server to be running.
*/
export const apiRequireSMTPServer = async () => {
const {status} = await apiEmailTest();
jestExpect(status).toEqual(200);
};
/**
* Update configuration.
* See https://api.mattermost.com/#operation/UpdateConfig
* @param {Object} newConfig - specific config to update
* @return {Object} returns {config} on success or {error, status} on error
*/
export const apiUpdateConfig = async (newConfig = {}) => {
try {
const {config: currentConfig} = await apiGetConfig();
const config = merge.all([currentConfig, getDefaultConfig(), newConfig]);
const response = await client.put(
'/api/v4/config',
config,
);
return {config: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Upload server license with file expected at "/detox/e2e/support/fixtures/mattermost-license.txt"
* See https://api.mattermost.com/#operation/UploadLicenseFile
* @return {Object} returns response on success or {error, status} on error
*/
export const apiUploadLicense = async () => {
@ -213,11 +202,24 @@ async function getClientLicense() {
return {license: out.license};
}
function getDefaultConfig() {
const fromEnv = {
LdapSettings: {
LdapServer: testConfig.ldapServer,
LdapPort: testConfig.ldapPort,
},
ServiceSettings: {SiteURL: testConfig.siteUrl},
};
return merge(defaultServerConfig, fromEnv);
}
export const System = {
apiCheckSystemHealth,
apiEmailTest,
apiGetClientLicense,
apiGetConfig,
apiPingServerStatus,
apiRequireLicense,
apiRequireLicenseForFeature,
apiRequireSMTPServer,

View file

@ -19,9 +19,29 @@ import {getResponseFromError} from './common';
// - return value defined by `@return`
// ****************************************************************
/**
* Add user to team.
* See https://api.mattermost.com/#operation/AddTeamMember
* @param {string} userId - The ID of user to add into the team
* @param {string} teamId - The team ID
* @return {Object} returns {member} on success or {error, status} on error
*/
export const apiAddUserToTeam = async (userId, teamId) => {
try {
const response = await client.post(
`/api/v4/teams/${teamId}/members`,
{team_id: teamId, user_id: userId},
);
return {member: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Create a team.
* See https://api.mattermost.com/#tag/teams/paths/~1teams/post
* See https://api.mattermost.com/#operation/CreateTeam
* @param {string} option.type - 'O' (default) for open, 'I' for invite only
* @param {string} option.prefix - option to add prefix to name and display name
* @param {Object} team - fix team object to be created
@ -40,29 +60,9 @@ export const apiCreateTeam = async ({type = 'O', prefix = 'team', team = null} =
}
};
/**
* Add user to team.
* See https://api.mattermost.com/#tag/teams/paths/~1teams~1{team_id}~1members/post
* @param {string} userId - The ID of user to add into the team
* @param {string} teamId - The team ID
* @return {Object} returns {member} on success or {error, status} on error
*/
export const apiAddUserToTeam = async (userId, teamId) => {
try {
const response = await client.post(
`/api/v4/teams/${teamId}/members`,
{team_id: teamId, user_id: userId},
);
return {member: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Delete a team.
* See https://api.mattermost.com/#tag/teams/paths/~1teams~1{team_id}/delete
* See https://api.mattermost.com/#operation/SoftDeleteTeam
* @param {string} teamId - The team ID
* @return {Object} returns {status} on success or {error, status} on error
*/
@ -96,7 +96,7 @@ export const apiDeleteTeams = async (teams = []) => {
/**
* Remove user from team.
* See https://api.mattermost.com/#tag/teams/paths/~1teams~1{team_id}~1members~1{user_id}/delete
* See https://api.mattermost.com/#operation/RemoveTeamMember
* @param {string} teamId - The team ID
* @param {string} userId - The user ID to be removed from team
* @return {Object} returns {status} on success or {error, status} on error
@ -115,7 +115,7 @@ export const apiDeleteUserFromTeam = async (teamId, userId) => {
/**
* Get teams.
* See https://api.mattermost.com/#tag/teams/paths/~1teams/get
* See https://api.mattermost.com/#operation/GetAllTeams
* @return {Object} returns {teams} on success or {error, status} on error
*/
export const apiGetTeams = async () => {
@ -130,7 +130,7 @@ export const apiGetTeams = async () => {
/**
* Get teams for user.
* See https://api.mattermost.com/#tag/teams/paths/~1users~1{user_id}~1teams/get
* See https://api.mattermost.com/#operation/GetTeamsForUser
* @param {string} userId - The user ID
* @return {Object} returns {teams} on success or {error, status} on error
*/
@ -146,7 +146,7 @@ export const apiGetTeamsForUser = async (userId = 'me') => {
/**
* Patch a team.
* See https://api.mattermost.com/#tag/teams/paths/~1teams~1{team_id}~1patch/put
* See https://api.mattermost.com/#operation/PatchTeam
* @param {string} teamId - The team ID
* @param {string} patch.display_name - Display name
* @param {string} patch.description - Description

View file

@ -19,9 +19,113 @@ import {getResponseFromError} from './common';
// - return value defined by `@return`
// ****************************************************************
/**
* Login to Mattermost server as sysadmin.
* @return {Object} returns {user, status} on success or {error, status} on error
*/
export const apiAdminLogin = () => {
return apiLogin({
username: testConfig.adminUsername,
password: testConfig.adminPassword,
});
};
/**
* Create a user.
* See https://api.mattermost.com/#operation/CreateUser
* @param {Object} user - user object to be created
* @return {Object} returns {user} on success or {error, status} on error
*/
export const apiCreateUser = async ({prefix = 'user', user = null} = {}) => {
try {
const newUser = user || generateRandomUser(prefix);
const response = await client.post(
'/api/v4/users',
newUser,
);
return {user: {...response.data, password: newUser.password}};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Deactivate a user account.
* See https://api.mattermost.com/#operation/DeleteUser
* @param {string} userId - the user ID
* @return {Object} returns {status} on success or {error, status} on error
*/
export const apiDeactivateUser = async (userId) => {
try {
const response = await client.delete(`/api/v4/users/${userId}`);
return {status: response.status};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Demote a user to a guest.
* See https://api.mattermost.com/#operation/DemoteUserToGuest
* @param {string} userId - the user ID
* @return {Object} returns {status} on success or {error, status} on error
*/
export const apiDemoteUserToGuest = async (userId) => {
try {
const response = await client.post(`/api/v4/users/${userId}/demote`);
return {status: response.status};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Get user from a current session.
* @return {Object} returns {user} on success or {error, status} on error
*/
export const apiGetMe = () => {
return apiGetUserById('me');
};
/**
* Get a user by ID.
* See https://api.mattermost.com/#operation/GetUser
* @param {string} userId - the user ID
* @return {Object} returns {user} on success or {error, status} on error
*/
export const apiGetUserById = async (userId) => {
try {
const response = await client.get(`/api/v4/users/${userId}`);
return {user: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Get a user by username.
* See https://api.mattermost.com/#operation/GetUserByUsername
* @param {string} username - the username
* @return {Object} returns {user} on success or {error, status} on error
*/
export const apiGetUserByUsername = async (username) => {
try {
const response = await client.get(`/api/v4/users/username/${username}`);
return {user: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Login to Mattermost server.
* See https://api.mattermost.com/#tag/users/paths/~1users~1login/post
* See https://api.mattermost.com/#operation/Login
* @param {string} user.username - username of a user
* @param {string} user.password - password of a user
* @return {Object} returns {user, status} on success or {error, status} on error
@ -48,20 +152,9 @@ export const apiLogin = async (user) => {
}
};
/**
* Login to Mattermost server as sysadmin.
* @return {Object} returns {user, status} on success or {error, status} on error
*/
export const apiAdminLogin = () => {
return apiLogin({
username: testConfig.adminUsername,
password: testConfig.adminPassword,
});
};
/**
* Logout from the Mattermost server.
* See https://api.mattermost.com/#tag/users/paths/~1users~1logout/post
* See https://api.mattermost.com/#operation/Logout
* @return {Object} returns data on success
*/
export const apiLogout = async () => {
@ -72,83 +165,6 @@ export const apiLogout = async () => {
return response.data;
};
/**
* Create a user.
* See https://api.mattermost.com/#tag/users/paths/~1users/post
* @param {Object} user - user object to be created
* @return {Object} returns {user} on success or {error, status} on error
*/
export const apiCreateUser = async ({prefix = 'user', user = null} = {}) => {
try {
const newUser = user || generateRandomUser(prefix);
const response = await client.post(
'/api/v4/users',
newUser,
);
return {user: {...response.data, password: newUser.password}};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Get user from a current session.
* @return {Object} returns {user} on success or {error, status} on error
*/
export const apiGetMe = () => {
return apiGetUserById('me');
};
/**
* Get a user by ID.
* See https://api.mattermost.com/#tag/users/paths/~1users~1{user_id}/get
* @param {string} userId - the user ID
* @return {Object} returns {user} on success or {error, status} on error
*/
export const apiGetUserById = async (userId) => {
try {
const response = await client.get(`/api/v4/users/${userId}`);
return {user: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Demote a user to a guest.
* See https://api.mattermost.com/#tag/users/paths/~1users~1{user_id}~1demote/post
* @param {string} userId - the user ID
* @return {Object} returns {status} on success or {error, status} on error
*/
export const apiDemoteUserToGuest = async (userId) => {
try {
const response = await client.post(`/api/v4/users/${userId}/demote`);
return {status: response.status};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Get a user by username.
* See https://api.mattermost.com/#tag/users/paths/~1users~1username~1{username}/get
* @param {string} username - the username
* @return {Object} returns {user} on success or {error, status} on error
*/
export const apiGetUserByUsername = async (username) => {
try {
const response = await client.get(`/api/v4/users/username/${username}`);
return {user: response.data};
} catch (err) {
return getResponseFromError(err);
}
};
/**
* Patch user from a current session.
* @param {Object} userData - data to partially update a user
@ -160,7 +176,7 @@ export const apiPatchMe = (userData) => {
/**
* Patch a user.
* See https://api.mattermost.com/#tag/users/paths/~1users~1{user_id}~1patch/put
* See https://api.mattermost.com/#operation/PatchUser
* @param {string} userId - the user ID
* @param {Object} userData - data to partially update a user
* @return {Object} returns {user} on success or {error, status} on error
@ -194,13 +210,14 @@ function generateRandomUser(prefix) {
export const User = {
apiAdminLogin,
apiDemoteUserToGuest,
apiLogin,
apiLogout,
apiCreateUser,
apiDeactivateUser,
apiDemoteUserToGuest,
apiGetMe,
apiGetUserById,
apiGetUserByUsername,
apiLogin,
apiLogout,
apiPatchMe,
apiPatchUser,
};

View file

@ -18,6 +18,7 @@ class Alert {
cancelButton = isAndroid() ? element(by.text('CANCEL')) : element(by.label('Cancel')).atIndex(1);
deleteButton = isAndroid() ? element(by.text('DELETE')) : element(by.label('Delete')).atIndex(0);
joinButton = isAndroid() ? element(by.text('JOIN')) : element(by.label('Join')).atIndex(0);
okButton = isAndroid() ? element(by.text('OK')) : element(by.label('OK')).atIndex(1);
noButton = isAndroid() ? element(by.text('NO')) : element(by.label('No')).atIndex(1);
yesButton = isAndroid() ? element(by.text('YES')) : element(by.label('Yes')).atIndex(0);
}

View file

@ -23,7 +23,7 @@ describe('Advanced Settings', () => {
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
// # Open channel screen
await ChannelScreen.open(user);

View file

@ -38,7 +38,7 @@ describe('Clock Display', () => {
await System.apiUpdateConfig({DisplaySettings: {ExperimentalTimezone: true}});
const {team, user} = await Setup.apiInit();
({channel: testChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: testChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
// # Set user's timezone
await User.apiPatchUser(user.id, {timezone: {automaticTimezone: '', manualTimezone: testTimezone, useAutomaticTimezone: 'false'}});

View file

@ -22,7 +22,7 @@ describe('Language Settings', () => {
const {team, user} = await Setup.apiInit();
testUser = user;
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
});
afterAll(async () => {

View file

@ -30,7 +30,7 @@ describe('User Profile', () => {
const {team, user} = await Setup.apiInit();
testUser = user;
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
// # Open channel screen
await ChannelScreen.open(testUser);

View file

@ -23,7 +23,7 @@ describe('Autocomplete', () => {
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
testChannel = channel;
// # Open channel screen

View file

@ -0,0 +1,124 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// *******************************************************************
// - [#] indicates a test step (e.g. # Go to a screen)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
import {
Alert,
MainSidebar,
} from '@support/ui/component';
import {
ChannelInfoScreen,
ChannelMembersScreen,
ChannelScreen,
} from '@support/ui/screen';
import {
Channel,
Setup,
Team,
User,
} from '@support/server_api';
import {isAndroid} from '@support/utils';
describe('Channel Moderation', () => {
const {
channelNavBarTitle,
goToChannel,
} = ChannelScreen;
const {manageMembersAction} = ChannelInfoScreen;
const {getUserByDisplayUsername} = ChannelMembersScreen;
let testUser;
let testOtherUser;
let testChannel;
let townSquareChannel;
beforeAll(async () => {
const {channel, team, user} = await Setup.apiInit();
testUser = user;
testChannel = channel;
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
({user: testOtherUser} = await User.apiCreateUser());
await Team.apiAddUserToTeam(testOtherUser.id, team.id);
await Channel.apiAddUserToChannel(testOtherUser.id, testChannel.id);
// # Open channel screen
await ChannelScreen.open(testUser);
});
afterAll(async () => {
await ChannelScreen.logout();
});
it('MM-T3317_1 user is prompted alert when removed from channel while on it', async () => {
// # Go to channel
await goToChannel(testChannel.display_name);
// * Verify user is a member of the channel
await ChannelInfoScreen.open();
await manageMembersAction.tap();
await expect(getUserByDisplayUsername(`@${testUser.username} - you`)).toBeVisible();
// # Go back to channel
await ChannelMembersScreen.back();
await ChannelInfoScreen.close();
// # Remove user while on channel
await Channel.apiDeleteUserFromChannel(testChannel.id, testUser.id);
// * Verify user is prompted removal alert
const removeFromChannelTitleText = `Removed from ${testChannel.display_name}`;
const removeFromChannelDescriptionText = 'You were removed from the channel.';
const removeFromChannelTitle = isAndroid() ? element(by.text(removeFromChannelTitleText)) : element(by.label(removeFromChannelTitleText)).atIndex(0);
const removeFromChannelDescription = isAndroid() ? element(by.text(removeFromChannelDescriptionText)) : element(by.label(removeFromChannelDescriptionText)).atIndex(0);
await expect(removeFromChannelTitle).toBeVisible();
await expect(removeFromChannelDescription).toBeVisible();
// # Tap on ok button
await Alert.okButton.tap();
// * Verify redirected to town square channel
await expect(channelNavBarTitle).toHaveText(townSquareChannel.display_name);
});
it('MM-T3317_2 user is not prompted alert when removed from channel while not on it', async () => {
const {
closeMainSidebar,
openMainSidebar,
} = ChannelScreen;
// # Open channel screen
await ChannelScreen.logout();
await ChannelScreen.open(testOtherUser);
// # Go to channel
await goToChannel(testChannel.display_name);
// * Verify user is a member of the channel
await ChannelInfoScreen.open();
await manageMembersAction.tap();
await expect(getUserByDisplayUsername(`@${testOtherUser.username} - you`)).toBeVisible();
// # Go back to channel
await ChannelMembersScreen.back();
await ChannelInfoScreen.close();
// # Go to town square channel
await goToChannel(townSquareChannel.display_name);
// # Remove user while on channel
await Channel.apiDeleteUserFromChannel(testChannel.id, testOtherUser.id);
// * Verify channel is not in the channels list anymore
await openMainSidebar();
await expect(MainSidebar.getChannelByDisplayName(testChannel.display_name)).not.toBeVisible();
// # Close main sidebar
await closeMainSidebar();
});
});

View file

@ -0,0 +1,119 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// *******************************************************************
// - [#] indicates a test step (e.g. # Go to a screen)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
import {
ChannelAddMembersScreen,
ChannelInfoScreen,
ChannelScreen,
} from '@support/ui/screen';
import {
Setup,
Team,
User,
} from '@support/server_api';
describe('Channel Add Members', () => {
const {
goToChannel,
postMessage,
} = ChannelScreen;
const {
addMembersAction,
channelInfoScrollView,
} = ChannelInfoScreen;
const {
addButton,
getUserByDisplayUsername,
searchInput,
} = ChannelAddMembersScreen;
let testChannel;
let testTeam;
let testActiveUser;
let testDeactivatedUser;
beforeAll(async () => {
const {channel, team, user} = await Setup.apiInit();
testChannel = channel;
testTeam = team;
({user: testActiveUser} = await User.apiCreateUser({prefix: 'active-'}));
({user: testDeactivatedUser} = await User.apiCreateUser({prefix: 'deactivated-'}));
await Team.apiAddUserToTeam(testActiveUser.id, testTeam.id);
await Team.apiAddUserToTeam(testDeactivatedUser.id, testTeam.id);
await User.apiDeactivateUser(testDeactivatedUser.id);
// # Open channel screen
await ChannelScreen.open(user);
});
afterAll(async () => {
await ChannelScreen.logout();
});
it('MM-T853_1 should not display deactivated users in add members list', async () => {
// # Open add members screen
await goToChannel(testChannel.display_name);
await ChannelInfoScreen.open();
await channelInfoScrollView.scrollTo('bottom');
await addMembersAction.tap();
// Verify deactivated user is not in the list
await expect(getUserByDisplayUsername(`@${testActiveUser.username}`)).toBeVisible();
await expect(getUserByDisplayUsername(`@${testDeactivatedUser.username}`)).not.toBeVisible();
// # Go back to channel
await ChannelAddMembersScreen.back();
await ChannelInfoScreen.close();
});
it('MM-T853_2 should be able to add members to channel', async () => {
// # Open add members screen
await goToChannel(testChannel.display_name);
await postMessage('divider');
await ChannelInfoScreen.open();
await expect(element(by.id(ChannelInfoScreen.testID.manageMembersAction).withDescendant(by.text('2')))).toBeVisible();
await channelInfoScrollView.scrollTo('bottom');
await addMembersAction.tap();
// # Add members to channel
await searchInput.typeText('active');
await getUserByDisplayUsername(`@${testActiveUser.username}`).tap();
await addButton.tap();
// * Verify members are added
await expect(element(by.id(ChannelInfoScreen.testID.manageMembersAction).withDescendant(by.text('3')))).toBeVisible();
// * Verify system message
await ChannelInfoScreen.close();
await expect(element(by.text(`@${testActiveUser.username} added to the channel by you.`))).toBeVisible();
});
it('MM-T854 should be able load users in long add members list', async () => {
// # Add users
[...Array(100).keys()].forEach(async (key) => {
const {user: testOtherUser} = await User.apiCreateUser({prefix: `a-${key}-`});
await Team.apiAddUserToTeam(testOtherUser.id, testTeam.id);
});
const {user: testLastUser} = await User.apiCreateUser({prefix: 'z-'});
await Team.apiAddUserToTeam(testLastUser.id, testTeam.id);
// # Open add members screen
await goToChannel(testChannel.display_name);
await ChannelInfoScreen.open();
await channelInfoScrollView.scrollTo('bottom');
await addMembersAction.tap();
// * Verify user can scroll down multiple times until last user is seen
await waitFor(getUserByDisplayUsername(`@${testLastUser.username}`)).toBeVisible().whileElement(by.id(ChannelAddMembersScreen.testID.usersList)).scroll(500, 'down');
await ChannelAddMembersScreen.back();
// # Close channel info screen
await ChannelInfoScreen.close();
});
});

View file

@ -39,7 +39,7 @@ describe('Channel Info', () => {
const {channel, team, user} = await Setup.apiInit();
testChannel1 = channel;
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
({channel: testChannel2} = await Channel.apiCreateChannel({type: 'O', teamId: team.id}));
await Channel.apiAddUserToChannel(user.id, testChannel2.id);

View file

@ -0,0 +1,75 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// *******************************************************************
// - [#] indicates a test step (e.g. # Go to a screen)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
import {
ChannelInfoScreen,
ChannelMembersScreen,
ChannelScreen,
MoreDirectMessagesScreen,
} from '@support/ui/screen';
import {
Setup,
Team,
User,
} from '@support/server_api';
import {getRandomId} from '@support/utils';
describe('Channel View Members', () => {
const searchTerm = getRandomId();
let testUser;
let testOtherUser1;
let testOtherUser2;
beforeAll(async () => {
const {user, team} = await Setup.apiInit({userOptions: {prefix: `${searchTerm}-3-`}});
testUser = user;
({user: testOtherUser1} = await User.apiCreateUser({prefix: `${searchTerm}-1-`}));
await Team.apiAddUserToTeam(testOtherUser1.id, team.id);
({user: testOtherUser2} = await User.apiCreateUser({prefix: `${searchTerm}-2-`}));
await Team.apiAddUserToTeam(testOtherUser2.id, team.id);
// # Open channel screen
await ChannelScreen.open(testUser);
});
afterAll(async () => {
await ChannelScreen.logout();
});
it('MM-T878 should only be able to view members in GM channel', async () => {
const {
getUserAtIndex,
searchInput,
startButton,
} = MoreDirectMessagesScreen;
// # Open more direct messages screen
await ChannelScreen.openMainSidebar();
await MoreDirectMessagesScreen.open();
// # Create a GM with with 2 other users
await searchInput.typeText(searchTerm);
await getUserAtIndex(0).tap();
await searchInput.typeText(searchTerm);
await getUserAtIndex(1).tap();
await startButton.tap();
// * Verify GM channel can only view members
await ChannelInfoScreen.open();
await ChannelInfoScreen.manageMembersAction.tap();
await expect(element(by.text('View Members'))).toBeVisible();
await expect(ChannelMembersScreen.removeButton).not.toExist();
// # Go back to channel
await ChannelMembersScreen.back();
await ChannelInfoScreen.close();
});
});

View file

@ -0,0 +1,68 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// *******************************************************************
// - [#] indicates a test step (e.g. # Go to a screen)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
import {MainSidebar} from '@support/ui/component';
import {
ChannelInfoScreen,
ChannelScreen,
} from '@support/ui/screen';
import {Setup} from '@support/server_api';
describe('Favorite Channels', () => {
let testChannel;
beforeAll(async () => {
const {channel, user} = await Setup.apiInit();
testChannel = channel;
// # Open channel screen
await ChannelScreen.open(user);
});
afterAll(async () => {
await ChannelScreen.logout();
});
it('MM-T850 should be able to favorite a channel', async () => {
const {
closeMainSidebar,
goToChannel,
openMainSidebar,
} = ChannelScreen;
const {
favoriteSwitchFalse,
favoriteSwitchTrue,
} = ChannelInfoScreen;
const {hasChannelDisplayNameAtIndex} = MainSidebar;
// # Open channel info screen
await goToChannel(testChannel.display_name);
await ChannelInfoScreen.open();
// * Verify favorite switch is toggled off
await expect(favoriteSwitchFalse).toBeVisible();
await expect(favoriteSwitchTrue).not.toBeVisible();
// # Toggle on favorite switch
await favoriteSwitchFalse.tap();
// * Verify favorite switch is toggled on
await expect(favoriteSwitchTrue).toBeVisible();
await expect(favoriteSwitchFalse).not.toBeVisible();
// * Verify channel appears in favorite channels list
await ChannelInfoScreen.close();
await openMainSidebar();
await expect(element(by.text('FAVORITE CHANNELS'))).toBeVisible();
await hasChannelDisplayNameAtIndex(0, testChannel.display_name);
// # Close main sidebar
await closeMainSidebar();
});
});

View file

@ -0,0 +1,144 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// *******************************************************************
// - [#] indicates a test step (e.g. # Go to a screen)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
import {PostOptions} from '@support/ui/component';
import {
ChannelInfoScreen,
ChannelScreen,
EditPostScreen,
PermalinkScreen,
PinnedMessagesScreen,
ThreadScreen,
} from '@support/ui/screen';
import {
Channel,
Post,
Setup,
} from '@support/server_api';
describe('Pinned Messages', () => {
const {
getPostListPostItem,
openPostOptionsFor,
openReplyThreadFor,
postMessage,
} = ChannelScreen;
const {pinAction} = PostOptions;
let townSquareChannel;
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
townSquareChannel = channel;
// # Open channel screen
await ChannelScreen.open(user);
});
afterAll(async () => {
await ChannelScreen.logout();
});
it('MM-T851_1 should be able pin a message from channel post list', async () => {
// # Post a message
const testMessage = Date.now().toString();
await postMessage(testMessage);
// # Pin message from channel post list
const {post} = await Post.apiGetLastPostInChannel(townSquareChannel.id);
await openPostOptionsFor(post.id, testMessage);
await pinAction.tap();
// * Verify message appears in pinned messages
const {postListPostItemPreHeaderText} = await getPostListPostItem(post.id, testMessage);
await expect(postListPostItemPreHeaderText).toHaveText('Pinned');
await ChannelInfoScreen.open();
await PinnedMessagesScreen.open();
const {searchResultPostItem} = await PinnedMessagesScreen.getSearchResultPostItem(post.id, testMessage);
await expect(searchResultPostItem).toBeVisible();
// # Go back to channel
await PinnedMessagesScreen.back();
await ChannelInfoScreen.close();
});
it('MM-T851_2 should be able to jump to recent messages from pinned post', async () => {
// # Post a message
const testMessage = Date.now().toString();
await postMessage(testMessage);
// # Pin message from channel post list
const {post} = await Post.apiGetLastPostInChannel(townSquareChannel.id);
await openPostOptionsFor(post.id, testMessage);
await pinAction.tap();
// # Jump to recent messages from pinned post
await ChannelInfoScreen.open();
await PinnedMessagesScreen.open();
const {searchResultPostItem} = await PinnedMessagesScreen.getSearchResultPostItem(post.id, testMessage);
await searchResultPostItem.tap();
await PermalinkScreen.jumpToRecentMessages();
// * Verify user is on channel where message is posted
await expect(ChannelScreen.channelNavBarTitle).toHaveText(townSquareChannel.display_name);
const {postListPostItem: channelPostItem} = await ChannelScreen.getPostListPostItem(post.id, testMessage);
await expect(channelPostItem).toBeVisible();
});
it('MM-T851_3 should be able to open reply thread for pinned message', async () => {
// # Post a message
const testMessage = Date.now().toString();
await postMessage(testMessage);
// # Pin message from channel post list
const {post} = await Post.apiGetLastPostInChannel(townSquareChannel.id);
await openPostOptionsFor(post.id, testMessage);
await pinAction.tap();
// # Open reply thread for pinned message
await openReplyThreadFor(post.id, testMessage);
// * Verify reply thread for pinned message is displayed
const {postListPostItem} = await ThreadScreen.getPostListPostItem(post.id, testMessage);
await expect(postListPostItem).toBeVisible();
// # Go back to channel
await ThreadScreen.back();
});
it('MM-T851_4 should be able to edit pinned message', async () => {
const {
messageInput,
saveButton,
} = EditPostScreen;
// # Post a message
const testMessage = Date.now().toString();
await postMessage(testMessage);
// # Pin message from channel post list
const {post} = await Post.apiGetLastPostInChannel(townSquareChannel.id);
await openPostOptionsFor(post.id, testMessage);
await pinAction.tap();
// # Edit pinned message
const additionalText = ' additional text';
await openPostOptionsFor(post.id, testMessage);
await EditPostScreen.open();
await messageInput.tap();
await messageInput.typeText(additionalText);
await saveButton.tap();
// * Verify pinned message is edited
await ChannelScreen.toBeVisible();
const {postListPostItem} = await getPostListPostItem(post.id, `${testMessage}${additionalText} (edited)`);
await expect(postListPostItem).toBeVisible();
});
});

View file

@ -29,7 +29,7 @@ describe('Guest Experience', () => {
testGuestUser = user;
testTeam = team;
({channel: testChannel} = await Channel.apiGetChannelByName(testTeam.name, 'town-square'));
({channel: testChannel} = await Channel.apiGetChannelByName(testTeam.id, 'town-square'));
// # Demote user to guest
await User.apiDemoteUserToGuest(testGuestUser.id);

View file

@ -31,7 +31,7 @@ describe('Permalink', () => {
const {user, team, channel} = await Setup.apiInit();
testUser = user;
testChannel = channel;
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
// # Open channel screen
await ChannelScreen.open(user);

View file

@ -45,7 +45,7 @@ describe('Messaging', () => {
await expect(element(by.text(message))).toExist();
// * Check that no duplicate message is saved.
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
const {posts} = await Post.apiGetPostsInChannel(channel.id);
jestExpect(posts.length).toEqual(3);
jestExpect(posts[0].message).toEqual(message);

View file

@ -101,7 +101,7 @@ describe('Messaging', () => {
await postMessage(Date.now().toString());
// # Get the last post data
const {channel: privateChannel2} = await Channel.apiGetChannelByName(testTeam.name, privateChannel2Name);
const {channel: privateChannel2} = await Channel.apiGetChannelByName(testTeam.id, privateChannel2Name);
const {post} = await Post.apiGetLastPostInChannel(privateChannel2.id);
// # Go to the Town Square channel

View file

@ -35,7 +35,7 @@ describe('in-app Notification', () => {
testChannel1 = channel;
testNotification = getNotification(testChannel1, team, user);
({channel: testChannel2} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: testChannel2} = await Channel.apiGetChannelByName(team.id, 'town-square'));
// # Open channel screen
await ChannelScreen.open(user);

View file

@ -26,7 +26,7 @@ describe('Add Reaction', () => {
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
({channel: testChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: testChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
({user: testOtherUser} = await User.apiCreateUser());
await Team.apiAddUserToTeam(testOtherUser.id, team.id);

View file

@ -23,7 +23,7 @@ describe('Advanced Settings', () => {
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
// # Open channel screen
await ChannelScreen.open(user);

View file

@ -38,7 +38,7 @@ describe('Clock Display', () => {
await System.apiUpdateConfig({DisplaySettings: {ExperimentalTimezone: true}});
const {team, user} = await Setup.apiInit();
({channel: testChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: testChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
// # Set user's timezone
await User.apiPatchUser(user.id, {timezone: {automaticTimezone: '', manualTimezone: testTimezone, useAutomaticTimezone: 'false'}});

View file

@ -52,7 +52,7 @@ describe('Direct Messages', () => {
({user: testOtherUser} = await User.apiCreateUser({prefix: searchTerm}));
await Team.apiAddUserToTeam(testOtherUser.id, team.id);
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
// # Post message by other user
testMessage = `Message by ${testOtherUser.username}`;

View file

@ -48,7 +48,7 @@ describe('Email Notifications', () => {
await Status.apiUpdateUserStatus(testUser.id, 'offline');
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
testChannel = channel;
({user: testOtherUser1} = await User.apiCreateUser());

View file

@ -27,11 +27,11 @@ describe('Mention Badges', () => {
beforeAll(async () => {
({user: testUser1} = await User.apiCreateUser());
({team: testTeam1} = await Team.apiCreateTeam({prefix: 'team-a'}));
({channel: testChannel1} = await Channel.apiGetChannelByName(testTeam1.name, 'town-square'));
({channel: testChannel1} = await Channel.apiGetChannelByName(testTeam1.id, 'town-square'));
({user: testUser2} = await User.apiCreateUser());
({team: testTeam2} = await Team.apiCreateTeam({prefix: 'team-b'}));
({channel: testChannel2} = await Channel.apiGetChannelByName(testTeam2.name, 'town-square'));
({channel: testChannel2} = await Channel.apiGetChannelByName(testTeam2.id, 'town-square'));
await Team.apiAddUserToTeam(testUser1.id, testTeam1.id);
await Team.apiAddUserToTeam(testUser1.id, testTeam2.id);

View file

@ -29,7 +29,7 @@ describe('Message Deletion', () => {
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
testChannel = channel;
// # Open channel screen

View file

@ -33,7 +33,7 @@ describe('Message Edit', () => {
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
testChannel = channel;
// # Open channel screen

View file

@ -35,7 +35,7 @@ describe('Message Posting', () => {
const {channel, team, user} = await Setup.apiInit();
testChannel = channel;
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
// # Open channel screen
await ChannelScreen.open(user);

View file

@ -27,7 +27,7 @@ describe('Message Reply', () => {
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
testChannel = channel;
// # Open channel screen

View file

@ -51,7 +51,7 @@ describe('Private Channels', () => {
({user: testOtherUser} = await User.apiCreateUser({prefix: `${testOtherUserSearchTerm}-`}));
await Team.apiAddUserToTeam(testOtherUser.id, team.id);
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
({channel: testPrivateChannel} = await Channel.apiCreateChannel({type: 'P', prefix: '1-private-channel', teamId: team.id}));
await Channel.apiAddUserToChannel(user.id, testPrivateChannel.id);

View file

@ -45,7 +45,7 @@ describe('Public Channels', () => {
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square'));
({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.id, 'town-square'));
({channel: testPublicChannel} = await Channel.apiCreateChannel({type: 'O', prefix: testPublicChannePrefix, teamId: team.id}));
// # Open channel screen

View file

@ -29,7 +29,7 @@ describe('Recent Mentions', () => {
const {team, user} = await Setup.apiInit();
testUser1 = user;
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
testChannel = channel;
({user: testUser2} = await User.apiCreateUser());

View file

@ -38,7 +38,7 @@ describe('Saved Messages', () => {
beforeAll(async () => {
const {team, user} = await Setup.apiInit();
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
testChannel = channel;
// # Open channel screen

View file

@ -44,7 +44,7 @@ describe('Search', () => {
const {team, user} = await Setup.apiInit();
testUser = user;
const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(team.id, 'town-square');
testChannel = channel;
// # Open channel screen

View file

@ -49,7 +49,7 @@ describe('Select Team', () => {
await team.tap();
// * Verify redirect to default channel of joined team
const {channel} = await Channel.apiGetChannelByName(testTeam.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(testTeam.id, 'town-square');
await ChannelScreen.toBeVisible();
await expect(ChannelScreen.channelNavBarTitle).toHaveText(channel.display_name);
});

View file

@ -25,13 +25,13 @@ describe('Teams', () => {
const {team, user} = await Setup.apiInit({teamOptions: {prefix: 'team-a'}});
testTeam1 = team;
const {channel} = await Channel.apiGetChannelByName(testTeam1.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(testTeam1.id, 'town-square');
testTeam1Channel = channel;
({team: testTeam2} = await Team.apiCreateTeam({prefix: 'team-b'}));
await Team.apiAddUserToTeam(user.id, testTeam2.id);
({channel: testTeam2Channel} = await Channel.apiGetChannelByName(testTeam2.name, 'town-square'));
({channel: testTeam2Channel} = await Channel.apiGetChannelByName(testTeam2.id, 'town-square'));
// # Open channel screen
await ChannelScreen.open(user);

View file

@ -46,7 +46,7 @@ describe('Select Team', () => {
await team.tap();
// * Verify redirect to default channel of joined team
const {channel} = await Channel.apiGetChannelByName(testTeam.name, 'town-square');
const {channel} = await Channel.apiGetChannelByName(testTeam.id, 'town-square');
const {channelNavBarTitle} = ChannelScreen;
await ChannelScreen.toBeVisible();
await expect(channelNavBarTitle).toHaveText(channel.display_name);