Skip to content
Merged
64 changes: 64 additions & 0 deletions app/containers/MessageComposer/MessageComposer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,70 @@ describe('MessageComposer', () => {
expect(onSendMessage).toHaveBeenCalledWith('@john', undefined);
});

test('does not show @all or @here in autocomplete when user does not have permissions', async () => {
mockedStore.dispatch(setPermissions({ 'mention-all': [], 'mention-here': [] }));
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);

await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.changeText(screen.getByTestId('message-composer-input'), '@');
await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
nativeEvent: { selection: { start: 1, end: 1 } }
});
jest.advanceTimersByTime(500);

await waitFor(() => expect(screen.queryByTestId('autocomplete-item-all')).not.toBeOnTheScreen());
await waitFor(() => expect(screen.queryByTestId('autocomplete-item-here')).not.toBeOnTheScreen());
});

test('shows only @all when user has mention-all permission', async () => {
mockedStore.dispatch(setPermissions({ 'mention-all': ['user'], 'mention-here': [] }));
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);

await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.changeText(screen.getByTestId('message-composer-input'), '@');
await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
nativeEvent: { selection: { start: 1, end: 1 } }
});
jest.advanceTimersByTime(500);

await waitFor(() => expect(screen.queryByTestId('autocomplete-item-all')).toBeOnTheScreen());
await waitFor(() => expect(screen.queryByTestId('autocomplete-item-here')).not.toBeOnTheScreen());
});

test('shows only @here when user has mention-here permission', async () => {
mockedStore.dispatch(setPermissions({ 'mention-here': ['user'], 'mention-all': [] }));
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);

await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.changeText(screen.getByTestId('message-composer-input'), '@');
await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
nativeEvent: { selection: { start: 1, end: 1 } }
});
jest.advanceTimersByTime(500);

await waitFor(() => expect(screen.queryByTestId('autocomplete-item-here')).toBeOnTheScreen());
await waitFor(() => expect(screen.queryByTestId('autocomplete-item-all')).not.toBeOnTheScreen());
});

test('shows both @all and @here when user has both permissions', async () => {
mockedStore.dispatch(setPermissions({ 'mention-all': ['user'], 'mention-here': ['user'] }));
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);

await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.changeText(screen.getByTestId('message-composer-input'), '@');
await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
nativeEvent: { selection: { start: 1, end: 1 } }
});
jest.advanceTimersByTime(500);

await waitFor(() => expect(screen.queryByTestId('autocomplete-item-all')).toBeOnTheScreen());
await waitFor(() => expect(screen.queryByTestId('autocomplete-item-here')).toBeOnTheScreen());
});

test('select # room inserts channel and sends, autocomplete hides', async () => {
const onSendMessage = jest.fn();
(search as unknown as jest.Mock).mockImplementationOnce(() => [{ rid: 'r1', name: 'general', t: 'c' }]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ exports[`MessageComposer Audio tap record 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={259}
handlerTag={289}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -177,7 +177,7 @@ exports[`MessageComposer Audio tap record 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={260}
handlerTag={290}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -299,7 +299,7 @@ exports[`MessageComposer Quote Add quote \`abc\` 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={246}
handlerTag={276}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -415,7 +415,7 @@ exports[`MessageComposer Quote Add quote \`abc\` 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={247}
handlerTag={277}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -587,7 +587,7 @@ exports[`MessageComposer Quote Add quote \`abc\` 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={248}
handlerTag={278}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -744,7 +744,7 @@ exports[`MessageComposer Quote Add quote \`def\` 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={249}
handlerTag={279}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -860,7 +860,7 @@ exports[`MessageComposer Quote Add quote \`def\` 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={250}
handlerTag={280}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -1033,7 +1033,7 @@ exports[`MessageComposer Quote Add quote \`def\` 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={251}
handlerTag={281}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -1214,7 +1214,7 @@ exports[`MessageComposer Quote Add quote \`def\` 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={252}
handlerTag={282}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -1371,7 +1371,7 @@ exports[`MessageComposer Quote Remove a quote 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={253}
handlerTag={283}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -1487,7 +1487,7 @@ exports[`MessageComposer Quote Remove a quote 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={254}
handlerTag={284}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -1660,7 +1660,7 @@ exports[`MessageComposer Quote Remove a quote 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={255}
handlerTag={285}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down Expand Up @@ -1841,7 +1841,7 @@ exports[`MessageComposer Quote Remove a quote 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={256}
handlerTag={286}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down
7 changes: 5 additions & 2 deletions app/containers/MessageComposer/hooks/useAutocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { getCommandPreview, getListCannedResponse } from '../../../lib/services/
import log from '../../../lib/methods/helpers/log';
import I18n from '../../../i18n';
import { NO_CANNED_RESPONSES } from '../constants';
import { usePermissions } from '../../../lib/hooks/usePermissions';

const MENTIONS_COUNT_TO_DISPLAY = 4;

Expand Down Expand Up @@ -52,6 +53,8 @@ export const useAutocomplete = ({
updateAutocompleteVisible?: (updatedAutocompleteVisible: boolean) => void;
}): TAutocompleteItem[] => {
const [items, setItems] = useState<TAutocompleteItem[]>([]);
const [mentionAll, mentionHere] = usePermissions(['mention-all', 'mention-here']);

useEffect(() => {
const getAutocomplete = async () => {
try {
Expand Down Expand Up @@ -87,7 +90,7 @@ export const useAutocomplete = ({
type
})) as IAutocompleteUserRoom[];
if (type === '@') {
if ('all'.includes(text.toLocaleLowerCase())) {
if (mentionAll && 'all'.includes(text.toLocaleLowerCase())) {
parsedRes.push({
id: 'all',
title: 'all',
Expand All @@ -96,7 +99,7 @@ export const useAutocomplete = ({
t: 'd'
});
}
if ('here'.includes(text.toLocaleLowerCase())) {
if (mentionHere && 'here'.includes(text.toLocaleLowerCase())) {
parsedRes.push({
id: 'here',
title: 'here',
Expand Down
4 changes: 3 additions & 1 deletion app/lib/methods/getPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ export const SUPPORTED_PERMISSIONS = [
'create-team-channel',
'create-team-group',
'delete-team-channel',
'delete-team-group'
'delete-team-group',
'mention-all',
'mention-here'
] as const;

export async function setPermissions(): Promise<void> {
Expand Down
Loading