Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rich-hounds-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fixes error messages not showing in the UI when `Preview Public Channel` permission is not in the user role and an app is preventing the same user to join the room.
1 change: 1 addition & 0 deletions apps/meteor/client/components/FilterByText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const FilterByText = forwardRef<HTMLInputElement, FilterByTextProps>(function Fi
<Box mi={4} display='flex' flexGrow={1}>
<TextInput
{...props}
role='searchbox'
placeholder={placeholder ?? t('Search')}
ref={mergedRefs}
addon={<Icon name='magnifier' size='x20' />}
Expand Down
5 changes: 5 additions & 0 deletions apps/meteor/client/hooks/useJoinRoom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { useToastMessageDispatch } from '@rocket.chat/ui-contexts/src/hooks/useToastMessageDispatch';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { sdk } from '../../app/utils/client/lib/SDKClient';
Expand All @@ -11,6 +12,7 @@ type UseJoinRoomMutationFunctionProps = {

export const useJoinRoom = () => {
const queryClient = useQueryClient();
const dispatchToastMessage = useToastMessageDispatch();

return useMutation({
mutationFn: async ({ rid, reference, type }: UseJoinRoomMutationFunctionProps) => {
Expand All @@ -23,5 +25,8 @@ export const useJoinRoom = () => {
queryKey: ['rooms', data],
});
},
onError: (error: unknown) => {
dispatchToastMessage({ message: error, type: 'error' });
},
});
};
1 change: 0 additions & 1 deletion apps/meteor/client/views/room/NotSubscribedRoom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const NotSubscribedRoom = ({ rid, reference, type }: NotSubscribedRoomProps): Re
const { t } = useTranslation();

const handleJoinClick = useJoinRoom();
// TODO: Handle onJoinClick error

const { isMobile } = useLayout();

Expand Down
1 change: 1 addition & 0 deletions apps/meteor/tests/e2e/fixtures/inject-initial-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default async function injectInitialData() {
createUserFixture(Users.user2),
createUserFixture(Users.user3),
createUserFixture(Users.userE2EE),
createUserFixture(Users.userNotAllowedByApp),
];

await Promise.all(
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/tests/e2e/fixtures/insert-apps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { request } from '@playwright/test';
import { Users } from './userStates';
import { BASE_API_URL, BASE_URL } from '../config/constants';

const APP_URL = 'https://github.com/RocketChat/Apps.RocketChat.Tester/blob/master/dist/appsrocketchattester_0.1.0.zip?raw=true';
const APP_URL = 'https://github.com/RocketChat/Apps.RocketChat.Tester/blob/master/dist/appsrocketchattester_0.2.0.zip?raw=true';

export default async function insertApp(): Promise<void> {
const api = await request.newContext();
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/tests/e2e/fixtures/userStates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export const Users = {
user1: generateContext('user1'),
user2: generateContext('user2'),
user3: generateContext('user3'),
userNotAllowedByApp: generateContext('userNotAllowedByApp'),
userE2EE: generateContext('userE2EE'),
samluser1: generateContext('samluser1'),
samluser2: generateContext('samluser2'),
Expand Down
22 changes: 22 additions & 0 deletions apps/meteor/tests/e2e/page-objects/directory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Page } from '@playwright/test';

export class Directory {
public readonly page: Page;

constructor(page: Page) {
this.page = page;
}

async searchChannel(name: string) {
await this.page.locator('role=searchbox').fill(name);
}

getSearchByChannelName(name: string) {
return this.page.locator(`role=link >> text="${name}"`);
}

async openChannel(name: string) {
await this.searchChannel(name);
await this.getSearchByChannelName(name).click();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -459,4 +459,8 @@ export class HomeContent {
get btnClearSelection() {
return this.page.getByRole('button', { name: 'Clear selection' });
}

get btnJoinChannel() {
return this.page.getByRole('button', { name: 'Join channel' });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export class HomeSidenav {
return this.page.locator('#modal-root [data-qa="create-direct-modal"] [data-qa-type="user-auto-complete-input"]');
}

get btnDirectory(): Locator {
return this.page.locator('role=button[name="Directory"]');
}

get btnCreate(): Locator {
return this.page.locator('role=button[name="Create"]');
}
Expand Down Expand Up @@ -140,6 +144,10 @@ export class HomeSidenav {
await this.page.locator(`role=menuitemcheckbox[name="${status}"]`).click();
}

async openDirectory(): Promise<void> {
await this.btnDirectory.click();
}

async openChat(name: string): Promise<void> {
await this.searchRoom(name);
await this.getSearchItemByName(name).click();
Expand Down
56 changes: 56 additions & 0 deletions apps/meteor/tests/e2e/preview-public-channel.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Users } from './fixtures/userStates';
import { HomeChannel, Utils } from './page-objects';
import { Directory } from './page-objects/directory';
import { createTargetChannel } from './utils';
import { test, expect } from './utils/test';

test.use({ storageState: Users.user1.state });

test.describe('Preview public channel', () => {
let poHomeChannel: HomeChannel;
let poDirectory: Directory;
let poUtils: Utils;
let targetChannel: string;

test.beforeEach(async ({ page, api }) => {
poHomeChannel = new HomeChannel(page);
targetChannel = await createTargetChannel(api);
poDirectory = new Directory(page);
poUtils = new Utils(page);

await page.goto('/home');
});

test.afterEach(async ({ api }) => {
await api.post('/channels.delete', { roomName: targetChannel });
});

test.describe('without preview public room permission', () => {
test.beforeAll(async ({ api }) => {
await api.post('/permissions.update', { permissions: [{ _id: 'preview-c-room', roles: ['admin'] }] });
});

test.afterAll(async ({ api }) => {
await api.post('/permissions.update', { permissions: [{ _id: 'preview-c-room', roles: ['admin', 'user', 'anonymous'] }] });
});

test('should not let user role preview public rooms', async () => {
await poHomeChannel.sidenav.openDirectory();
await poDirectory.openChannel(targetChannel);

expect(poHomeChannel.content.btnJoinChannel).toBeVisible;
});

test.describe('apps', () => {
test.use({ storageState: Users.userNotAllowedByApp.state });

test('should prevent user from join the room', async () => {
await poHomeChannel.sidenav.openDirectory();
await poDirectory.openChannel(targetChannel);
await poHomeChannel.content.btnJoinChannel.click();

expect(poUtils.getAlertByText('TEST OF NOT ALLOWED USER')).toBeVisible;
});
});
});
});