Skip to content

Commit

Permalink
test: create non private team and readonly team (#30371)
Browse files Browse the repository at this point in the history
  • Loading branch information
janainaCoelhoRocketchat authored Sep 16, 2023
1 parent 3677cc5 commit b3fa016
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 29 deletions.
95 changes: 69 additions & 26 deletions apps/meteor/client/sidebar/header/CreateTeam/CreateTeamModal.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Box, Modal, Button, TextInput, Field, ToggleSwitch, FieldGroup, Icon } from '@rocket.chat/fuselage';
import { Box, Button, Field, FieldGroup, Icon, Modal, TextInput, ToggleSwitch } from '@rocket.chat/fuselage';
import { useUniqueId } from '@rocket.chat/fuselage-hooks';
import {
useTranslation,
useSetting,
usePermission,
useEndpoint,
useToastMessageDispatch,
usePermission,
usePermissionWithScopedRoles,
useSetting,
useToastMessageDispatch,
useTranslation,
} from '@rocket.chat/ui-contexts';
import type { ComponentProps, ReactElement } from 'react';
import React, { memo, useMemo, useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import React, { memo, useEffect, useMemo } from 'react';
import { Controller, useForm } from 'react-hook-form';

import UserAutoCompleteMultiple from '../../../components/UserAutoCompleteMultiple';
import { goToRoomById } from '../../../lib/utils/goToRoomById';
Expand Down Expand Up @@ -129,18 +130,35 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
}
};

const createTeamFormId = useUniqueId();
const nameId = useUniqueId();
const topicId = useUniqueId();
const privateId = useUniqueId();
const readOnlyId = useUniqueId();
const encryptedId = useUniqueId();
const broadcastId = useUniqueId();
const addMembersId = useUniqueId();

return (
<Modal wrapperFunction={(props: ComponentProps<typeof Box>) => <Box is='form' onSubmit={handleSubmit(handleCreateTeam)} {...props} />}>
<Modal
aria-labelledby={`${createTeamFormId}-title`}
wrapperFunction={(props: ComponentProps<typeof Box>) => (
<Box is='form' id={createTeamFormId} onSubmit={handleSubmit(handleCreateTeam)} {...props} />
)}
>
<Modal.Header>
<Modal.Title>{t('Teams_New_Title')}</Modal.Title>
<Modal.Title id={`${createTeamFormId}-title`}>{t('Teams_New_Title')}</Modal.Title>
<Modal.Close title={t('Close')} onClick={onClose} tabIndex={-1} />
</Modal.Header>
<Modal.Content mbe={2}>
<FieldGroup>
<Field>
<Field.Label>{t('Teams_New_Name_Label')}</Field.Label>
<Field.Label required htmlFor={nameId}>
{t('Teams_New_Name_Label')}
</Field.Label>
<Field.Row>
<TextInput
id={nameId}
aria-invalid={errors.name ? 'true' : 'false'}
{...register('name', {
required: t('error-the-field-is-required', { field: t('Name') }),
Expand All @@ -149,89 +167,114 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
placeholder={t('Team_Name')}
addon={<Icon size='x20' name={isPrivate ? 'team-lock' : 'team'} />}
error={errors.name?.message}
aria-describedby={`${nameId}-error`}
aria-required='true'
/>
</Field.Row>
{errors?.name && <Field.Error>{errors.name.message}</Field.Error>}
{errors?.name && (
<Field.Error aria-live='assertive' id={`${nameId}-error`}>
{errors.name.message}
</Field.Error>
)}
</Field>
<Field>
<Field.Label>
<Field.Label htmlFor={topicId}>
{t('Teams_New_Description_Label')}{' '}
<Box is='span' color='annotation'>
({t('optional')})
</Box>
</Field.Label>
<Field.Row>
<TextInput {...register('topic')} placeholder={t('Teams_New_Description_Placeholder')} />
<TextInput
id={topicId}
aria-describedby={`${topicId}-hint`}
{...register('topic')}
placeholder={t('Teams_New_Description_Placeholder')}
/>
</Field.Row>
</Field>
<Field>
<Box display='flex' justifyContent='space-between' alignItems='start'>
<Box display='flex' flexDirection='column' width='full'>
<Field.Label>{t('Teams_New_Private_Label')}</Field.Label>
<Field.Description>
<Field.Label htmlFor={privateId}>{t('Teams_New_Private_Label')}</Field.Label>
<Field.Description id={`${privateId}-hint`}>
{isPrivate ? t('Teams_New_Private_Description_Enabled') : t('Teams_New_Private_Description_Disabled')}
</Field.Description>
</Box>
<Controller
control={control}
name='isPrivate'
render={({ field: { onChange, value, ref } }): ReactElement => (
<ToggleSwitch onChange={onChange} checked={value} ref={ref} />
<ToggleSwitch id={privateId} aria-describedby={`${privateId}-hint`} onChange={onChange} checked={value} ref={ref} />
)}
/>
</Box>
</Field>
<Field>
<Box display='flex' justifyContent='space-between' alignItems='start'>
<Box display='flex' flexDirection='column' width='full'>
<Field.Label>{t('Teams_New_Read_only_Label')}</Field.Label>
<Field.Description>
<Field.Label htmlFor={readOnlyId}>{t('Teams_New_Read_only_Label')}</Field.Label>
<Field.Description id={`${readOnlyId}-hint`}>
{readOnly ? t('Only_authorized_users_can_write_new_messages') : t('Teams_New_Read_only_Description')}
</Field.Description>
</Box>
<Controller
control={control}
name='readOnly'
render={({ field: { onChange, value, ref } }): ReactElement => (
<ToggleSwitch disabled={!canChangeReadOnly} onChange={onChange} checked={value} ref={ref} />
<ToggleSwitch
id={readOnlyId}
aria-describedby={`${readOnlyId}-hint`}
disabled={!canChangeReadOnly}
onChange={onChange}
checked={value}
ref={ref}
/>
)}
/>
</Box>
</Field>
<Field>
<Box display='flex' justifyContent='space-between' alignItems='start'>
<Box display='flex' flexDirection='column' width='full'>
<Field.Label>{t('Teams_New_Encrypted_Label')}</Field.Label>
<Field.Description>
<Field.Label htmlFor={encryptedId}>{t('Teams_New_Encrypted_Label')}</Field.Label>
<Field.Description id={`${encryptedId}-hint`}>
{isPrivate ? t('Teams_New_Encrypted_Description_Enabled') : t('Teams_New_Encrypted_Description_Disabled')}
</Field.Description>
</Box>
<Controller
control={control}
name='encrypted'
render={({ field: { onChange, value, ref } }): ReactElement => (
<ToggleSwitch disabled={!canSetReadOnly || !canChangeEncrypted} onChange={onChange} checked={value} ref={ref} />
<ToggleSwitch
id={encryptedId}
disabled={!canSetReadOnly || !canChangeEncrypted}
onChange={onChange}
aria-describedby={`${encryptedId}-hint`}
checked={value}
ref={ref}
/>
)}
/>
</Box>
</Field>
<Field>
<Box display='flex' justifyContent='space-between' alignItems='start'>
<Box display='flex' flexDirection='column' width='full'>
<Field.Label>{t('Teams_New_Broadcast_Label')}</Field.Label>
<Field.Description>{t('Teams_New_Broadcast_Description')}</Field.Description>
<Field.Label htmlFor={broadcastId}>{t('Teams_New_Broadcast_Label')}</Field.Label>
<Field.Description d={`${broadcastId}-hint`}>{t('Teams_New_Broadcast_Description')}</Field.Description>
</Box>
<Controller
control={control}
name='broadcast'
render={({ field: { onChange, value, ref } }): ReactElement => (
<ToggleSwitch onChange={onChange} checked={value} ref={ref} />
<ToggleSwitch aria-describedby={`${broadcastId}-hint`} id={broadcastId} onChange={onChange} checked={value} ref={ref} />
)}
/>
</Box>
</Field>
<Field>
<Field.Label>
<Field.Label htmlFor={addMembersId}>
{t('Teams_New_Add_members_Label')}{' '}
<Box is='span' color='annotation'>
({t('optional')})
Expand Down
10 changes: 9 additions & 1 deletion apps/meteor/tests/e2e/page-objects/home-team.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Locator, Page } from '@playwright/test';

import { HomeContent, HomeSidenav, HomeFlextab } from './fragments';
import { HomeContent, HomeFlextab, HomeSidenav } from './fragments';

export class HomeTeam {
private readonly page: Page;
Expand Down Expand Up @@ -30,4 +30,12 @@ export class HomeTeam {
get btnTeamCreate(): Locator {
return this.page.locator('role=dialog >> role=group >> role=button[name=Create]');
}

get textPrivate(): Locator {
return this.page.locator('role=dialog[name="Create Team"] >> label >> text="Private"');
}

get textReadOnly(): Locator {
return this.page.locator('role=dialog[name="Create Team"] >> label >> text="Read Only"');
}
}
26 changes: 24 additions & 2 deletions apps/meteor/tests/e2e/team-management.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import { faker } from '@faker-js/faker';
import { Users } from './fixtures/userStates';
import { HomeTeam } from './page-objects';
import { createTargetChannel } from './utils';
import { test, expect } from './utils/test';
import { expect, test } from './utils/test';

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

test.describe.serial('teams-management', () => {
let poHomeTeam: HomeTeam;
let targetChannel: string;
const targetTeam = faker.string.uuid();
const targetTeamNonPrivate = faker.string.uuid();
const targetTeamReadOnly = faker.string.uuid();

test.beforeAll(async ({ api }) => {
targetChannel = await createTargetChannel(api);
Expand All @@ -22,7 +24,7 @@ test.describe.serial('teams-management', () => {
await page.goto('/home');
});

test('expect create "targetTeam"', async ({ page }) => {
test('expect create "targetTeam" private', async ({ page }) => {
await poHomeTeam.sidenav.openNewByLabel('Team');
await poHomeTeam.inputTeamName.type(targetTeam);
await poHomeTeam.addMember('user1');
Expand All @@ -31,6 +33,26 @@ test.describe.serial('teams-management', () => {
await expect(page).toHaveURL(`/group/${targetTeam}`);
});

test('expect create "targetTeamNonPrivate" non private', async ({ page }) => {
await poHomeTeam.sidenav.openNewByLabel('Team');
await poHomeTeam.inputTeamName.type(targetTeamNonPrivate);
await poHomeTeam.textPrivate.click();
await poHomeTeam.addMember('user1');
await poHomeTeam.btnTeamCreate.click();

await expect(page).toHaveURL(`/channel/${targetTeamNonPrivate}`);
});

test('expect create "targetTeamReadOnly" readonly', async ({ page }) => {
await poHomeTeam.sidenav.openNewByLabel('Team');
await poHomeTeam.inputTeamName.type(targetTeamReadOnly);
await poHomeTeam.textReadOnly.click();
await poHomeTeam.addMember('user1');
await poHomeTeam.btnTeamCreate.click();

await expect(page).toHaveURL(`/group/${targetTeamReadOnly}`);
});

test('expect throw validation error if team name already exists', async () => {
await poHomeTeam.sidenav.openNewByLabel('Team');
await poHomeTeam.inputTeamName.type(targetTeam);
Expand Down

0 comments on commit b3fa016

Please sign in to comment.