Mm 32502 guest identification 2 (#5198)
* Add Guest Experience Test Cases * Added testIDs and cleaned up tests * Minor refactor Co-authored-by: Furqan Malik <furqanmalik@Furqans-MacBook-Pro.local> Co-authored-by: Malik <abc@abcs-MBP.phub.net.cable.rogers.com> Co-authored-by: Furqan Malik <furqanmalik@Furqans-MBP.phub.net.cable.rogers.com> Co-authored-by: Joseph Baylon <joseph.baylon@mattermost.com> Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
parent
875bcc6af3
commit
6287706452
10 changed files with 122 additions and 3 deletions
|
|
@ -78,8 +78,8 @@ const ChannelMentionItem = (props) => {
|
|||
key={channelId}
|
||||
onPress={completeMention}
|
||||
style={[style.row, margins]}
|
||||
type={'opacity'}
|
||||
testID={testID}
|
||||
type={'opacity'}
|
||||
>
|
||||
<Text style={style.rowDisplayName}>{'@' + displayName}</Text>
|
||||
<BotTag
|
||||
|
|
@ -99,8 +99,8 @@ const ChannelMentionItem = (props) => {
|
|||
onPress={completeMention}
|
||||
style={margins}
|
||||
underlayColor={changeOpacity(theme.buttonBg, 0.08)}
|
||||
type={'native'}
|
||||
testID={testID}
|
||||
type={'native'}
|
||||
>
|
||||
<View style={style.row}>
|
||||
<CompassIcon
|
||||
|
|
|
|||
|
|
@ -270,6 +270,7 @@ export default class PostHeader extends PureComponent {
|
|||
return (
|
||||
<GuestTag
|
||||
style={style.tag}
|
||||
testID='post_header.guest_tag'
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export default class Tag extends PureComponent {
|
|||
inTitle: PropTypes.bool,
|
||||
show: PropTypes.bool,
|
||||
style: ViewPropTypes.style,
|
||||
testID: PropTypes.string,
|
||||
theme: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
|
|
@ -61,6 +62,7 @@ export default class Tag extends PureComponent {
|
|||
id={this.props.id}
|
||||
defaultMessage={this.props.defaultMessage}
|
||||
style={[style.text, this.props.inTitle ? style.title : null]}
|
||||
testID={this.props.testID}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -117,6 +117,22 @@ export const apiGetUserById = async (userId) => {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -177,6 +193,7 @@ function generateRandomUser(prefix) {
|
|||
|
||||
export const User = {
|
||||
apiAdminLogin,
|
||||
apiDemoteUserToGuest,
|
||||
apiLogin,
|
||||
apiLogout,
|
||||
apiCreateUser,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class Post {
|
|||
message: 'markdown_text',
|
||||
postHeaderDateTime: 'post_header.date_time',
|
||||
postHeaderDisplayName: 'post_header.display_name',
|
||||
postHeaderGuestTag: 'post_header.guest_tag',
|
||||
postHeaderReply: 'post_header.reply',
|
||||
postPreHeaderText: 'post_pre_header.text',
|
||||
}
|
||||
|
|
@ -30,11 +31,13 @@ class Post {
|
|||
getPostHeader = (postItemMatcher) => {
|
||||
const postItemHeaderDateTimeMatcher = by.id(this.testID.postHeaderDateTime).withAncestor(postItemMatcher);
|
||||
const postItemHeaderDisplayNameMatcher = by.id(this.testID.postHeaderDisplayName).withAncestor(postItemMatcher);
|
||||
const postItemHeaderGuestTagMatcher = by.id(this.testID.postHeaderGuestTag).withAncestor(postItemMatcher);
|
||||
const postItemHeaderReplyMatcher = by.id(this.testID.postHeaderReply).withAncestor(postItemMatcher);
|
||||
|
||||
return {
|
||||
postItemHeaderDateTime: element(postItemHeaderDateTimeMatcher),
|
||||
postItemHeaderDisplayName: element(postItemHeaderDisplayNameMatcher),
|
||||
postItemHeaderGuestTag: element(postItemHeaderGuestTagMatcher),
|
||||
postItemHeaderReply: element(postItemHeaderReplyMatcher),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class PostList {
|
|||
postItem,
|
||||
postItemHeaderDateTime,
|
||||
postItemHeaderDisplayName,
|
||||
postItemHeaderGuestTag,
|
||||
postItemHeaderReply,
|
||||
postItemMessage,
|
||||
postItemPreHeaderText,
|
||||
|
|
@ -26,6 +27,7 @@ class PostList {
|
|||
postListPostItem: postItem,
|
||||
postListPostItemHeaderDateTime: postItemHeaderDateTime,
|
||||
postListPostItemHeaderDisplayName: postItemHeaderDisplayName,
|
||||
postListPostItemHeaderGuestTag: postItemHeaderGuestTag,
|
||||
postListPostItemHeaderReply: postItemHeaderReply,
|
||||
postListPostItemMessage: postItemMessage,
|
||||
postListPostItemPreHeaderText: postItemPreHeaderText,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ class LongPostScreen {
|
|||
postItem,
|
||||
postItemHeaderDateTime,
|
||||
postItemHeaderDisplayName,
|
||||
postItemHeaderGuestTag,
|
||||
postItemHeaderReply,
|
||||
postItemMessage,
|
||||
postItemProfilePicture,
|
||||
|
|
@ -23,6 +24,7 @@ class LongPostScreen {
|
|||
longPostItem: postItem,
|
||||
longPostItemHeaderDateTime: postItemHeaderDateTime,
|
||||
longPostItemHeaderDisplayName: postItemHeaderDisplayName,
|
||||
longPostItemHeaderGuestTag: postItemHeaderGuestTag,
|
||||
longPostItemHeaderReply: postItemHeaderReply,
|
||||
longPostItemMessage: postItemMessage,
|
||||
longPostItemProfilePicture: postItemProfilePicture,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ class SearchResultPostScreen {
|
|||
postItem,
|
||||
postItemHeaderDateTime,
|
||||
postItemHeaderDisplayName,
|
||||
postItemHeaderGuestTag,
|
||||
postItemHeaderReply,
|
||||
postItemMessage,
|
||||
postItemProfilePicture,
|
||||
|
|
@ -23,6 +24,7 @@ class SearchResultPostScreen {
|
|||
searchResultPostItem: postItem,
|
||||
searchResultPostItemHeaderDateTime: postItemHeaderDateTime,
|
||||
searchResultPostItemHeaderDisplayName: postItemHeaderDisplayName,
|
||||
searchResultPostItemHeaderGuestTag: postItemHeaderGuestTag,
|
||||
searchResultPostItemHeaderReply: postItemHeaderReply,
|
||||
searchResultPostItemMessage: postItemMessage,
|
||||
searchResultPostItemProfilePicture: postItemProfilePicture,
|
||||
|
|
|
|||
90
detox/e2e/test/guest_account/guest_experience.e2e.js
Normal file
90
detox/e2e/test/guest_account/guest_experience.e2e.js
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
// 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 {Autocomplete} from '@support/ui/component';
|
||||
import {
|
||||
ChannelScreen,
|
||||
SearchScreen,
|
||||
} from '@support/ui/screen';
|
||||
import {
|
||||
Channel,
|
||||
Post,
|
||||
Setup,
|
||||
User,
|
||||
} from '@support/server_api';
|
||||
|
||||
describe('Guest Experience', () => {
|
||||
let testChannel;
|
||||
let testTeam;
|
||||
let testGuestUser;
|
||||
|
||||
beforeAll(async () => {
|
||||
const {team, user} = await Setup.apiInit();
|
||||
testGuestUser = user;
|
||||
testTeam = team;
|
||||
|
||||
({channel: testChannel} = await Channel.apiGetChannelByName(testTeam.name, 'town-square'));
|
||||
|
||||
// # Demote user to guest
|
||||
await User.apiDemoteUserToGuest(testGuestUser.id);
|
||||
|
||||
// # Open channel screen
|
||||
await ChannelScreen.open(testGuestUser);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await ChannelScreen.logout();
|
||||
});
|
||||
|
||||
it('MM-T1404 Guest badge not shown next to system messages', async () => {
|
||||
// * Verify guest badge is not visible in system message
|
||||
const systemMessage = 'You and @sysadmin joined the team.';
|
||||
const {post} = await Post.apiGetLastPostInChannel(testChannel.id);
|
||||
const {postListPostItemHeaderGuestTag} = await ChannelScreen.getPostListPostItem(post.id, systemMessage);
|
||||
await expect(postListPostItemHeaderGuestTag).not.toBeVisible();
|
||||
});
|
||||
|
||||
it('MM-T1397 Guest tag in search in:', async () => {
|
||||
const {
|
||||
getSearchResultPostItem,
|
||||
searchInSection,
|
||||
searchInput,
|
||||
} = SearchScreen;
|
||||
const {
|
||||
channelMentionSuggestionList,
|
||||
getChannelMentionItem,
|
||||
} = Autocomplete;
|
||||
|
||||
// # Post a message as guest user
|
||||
const testMessage = Date.now().toString();
|
||||
await ChannelScreen.postMessage(testMessage);
|
||||
|
||||
// * Verify guest badge is visible in channel
|
||||
const {post} = await Post.apiGetLastPostInChannel(testChannel.id);
|
||||
const {postListPostItemHeaderGuestTag} = await ChannelScreen.getPostListPostItem(post.id, testMessage);
|
||||
await expect(postListPostItemHeaderGuestTag).toBeVisible();
|
||||
|
||||
// # Search ":in" channel and select channel from autocomplete
|
||||
await SearchScreen.open();
|
||||
await searchInput.clearText();
|
||||
await searchInSection.tap();
|
||||
await searchInput.typeText(testChannel.name);
|
||||
await expect(channelMentionSuggestionList).toExist();
|
||||
const channelMentionAutocomplete = await getChannelMentionItem(testChannel.id);
|
||||
await channelMentionAutocomplete.tap();
|
||||
await searchInput.tapReturnKey();
|
||||
|
||||
// * Verify guest badge is visible in search results
|
||||
const {searchResultPostItemHeaderGuestTag} = await getSearchResultPostItem(post.id, testMessage);
|
||||
await expect(searchResultPostItemHeaderGuestTag).toBeVisible();
|
||||
|
||||
// # Go back to channel
|
||||
await SearchScreen.cancel();
|
||||
});
|
||||
});
|
||||
|
|
@ -150,7 +150,7 @@ describe('Messaging', () => {
|
|||
});
|
||||
|
||||
async function createPrivateChannel(channelName) {
|
||||
// # Open Mainside bar and press on private channels more button
|
||||
// # Open create private channel screen
|
||||
await ChannelScreen.openMainSidebar();
|
||||
await MainSidebar.openCreatePrivateChannelButton.tap();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue