chore: Purge and rename removed v1 files (#37912)
parent
62708dcd12
commit
a587ab378c
@ -1,8 +0,0 @@ |
||||
import { testCreateChannelModal } from './testCreateChannelModal'; |
||||
import CreateChannelModalComponent from '../../../sidebar/header/CreateChannel'; |
||||
|
||||
jest.mock('../../../lib/utils/goToRoomById', () => ({ |
||||
goToRoomById: jest.fn(), |
||||
})); |
||||
|
||||
testCreateChannelModal(CreateChannelModalComponent); |
||||
@ -1,269 +0,0 @@ |
||||
import { mockAppRoot } from '@rocket.chat/mock-providers'; |
||||
import { render, screen } from '@testing-library/react'; |
||||
import userEvent from '@testing-library/user-event'; |
||||
|
||||
import type CreateChannelModal2Component from './CreateChannelModal'; |
||||
import { createFakeLicenseInfo } from '../../../../tests/mocks/data'; |
||||
import type CreateChannelModalComponent from '../../../sidebar/header/CreateChannel'; |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export function testCreateChannelModal(CreateChannelModal: typeof CreateChannelModalComponent | typeof CreateChannelModal2Component) { |
||||
describe('CreateChannelModal', () => { |
||||
describe('Encryption', () => { |
||||
it('should render with encryption option disabled and set to off when E2E_Enable=false and E2E_Enabled_Default_PrivateRooms=false', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', false).withSetting('E2E_Enabled_Default_PrivateRooms', false).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Encrypted') as HTMLInputElement; |
||||
expect(encrypted).toBeInTheDocument(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
}); |
||||
|
||||
it('should render with encryption option enabled and set to off when E2E_Enable=true and E2E_Enabled_Default_PrivateRooms=false', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', false).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Encrypted') as HTMLInputElement; |
||||
expect(encrypted).toBeInTheDocument(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
}); |
||||
|
||||
it('should render with encryption option disabled and set to off when E2E_Enable=false and E2E_Enabled_Default_PrivateRooms=true', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', false).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Encrypted') as HTMLInputElement; |
||||
expect(encrypted).toBeInTheDocument(); |
||||
|
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
}); |
||||
|
||||
it('should render with encryption option enabled and set to on when E2E_Enable=true and E2E_Enabled_Default_PrivateRooms=True', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Encrypted') as HTMLInputElement; |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
}); |
||||
|
||||
it('when Private goes ON → OFF: forces Encrypted OFF and disables it (E2E_Enable=true, E2E_Enabled_Default_PrivateRooms=true)', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Encrypted') as HTMLInputElement; |
||||
const priv = screen.getByLabelText('Private') as HTMLInputElement; |
||||
|
||||
// initial: private=true, encrypted ON and enabled
|
||||
expect(priv).toBeChecked(); |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
|
||||
// Private ON -> OFF: encrypted must become OFF and disabled
|
||||
await userEvent.click(priv); |
||||
expect(priv).not.toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
}); |
||||
|
||||
it('when Private goes OFF → ON: keeps Encrypted OFF but re-enables it (E2E_Enable=true, E2E_Enabled_Default_PrivateRooms=true)', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Encrypted') as HTMLInputElement; |
||||
const priv = screen.getByLabelText('Private') as HTMLInputElement; |
||||
|
||||
// turn private OFF to simulate user path from non-private
|
||||
await userEvent.click(priv); |
||||
expect(priv).not.toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
|
||||
// turn private back ON -> encrypted should remain OFF but become enabled
|
||||
await userEvent.click(priv); |
||||
expect(priv).toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
}); |
||||
|
||||
it('private room: toggling Broadcast on/off does not change or disable Encrypted', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Encrypted') as HTMLInputElement; |
||||
const broadcast = screen.getByLabelText('Broadcast') as HTMLInputElement; |
||||
const priv = screen.getByLabelText('Private') as HTMLInputElement; |
||||
|
||||
expect(priv).toBeChecked(); |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
expect(broadcast).not.toBeChecked(); |
||||
|
||||
// Broadcast: OFF -> ON (Encrypted unchanged + enabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).toBeChecked(); |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
|
||||
// Broadcast: ON -> OFF (Encrypted unchanged + enabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).not.toBeChecked(); |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
|
||||
// User can still toggle Encrypted freely while Broadcast is OFF
|
||||
await userEvent.click(encrypted); |
||||
expect(encrypted).not.toBeChecked(); |
||||
|
||||
// User can still toggle Encrypted freely while Broadcast is ON
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
}); |
||||
|
||||
it('non-private room: Encrypted remains OFF and disabled regardless of Broadcast state', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Encrypted') as HTMLInputElement; |
||||
const broadcast = screen.getByLabelText('Broadcast') as HTMLInputElement; |
||||
const priv = screen.getByLabelText('Private') as HTMLInputElement; |
||||
|
||||
// Switch to non-private
|
||||
await userEvent.click(priv); |
||||
expect(priv).not.toBeChecked(); |
||||
|
||||
// Encrypted must be OFF + disabled (non-private cannot be encrypted)
|
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
|
||||
// Broadcast: OFF -> ON (Encrypted stays OFF + disabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
|
||||
// Broadcast: ON -> OFF (Encrypted still OFF + disabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).not.toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
}); |
||||
}); |
||||
|
||||
describe('Federation', () => { |
||||
it('should render with federated option disabled when user lacks license module', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
const federated = screen.getByLabelText('Federation_Matrix_Federated'); |
||||
expect(federated).toHaveAccessibleDescription('error-this-is-a-premium-feature'); |
||||
expect(federated).toBeInTheDocument(); |
||||
expect(federated).not.toBeChecked(); |
||||
expect(federated).toBeDisabled(); |
||||
}); |
||||
|
||||
it('should render with federated option disabled if the feature is disabled for workspaces', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot() |
||||
.withJohnDoe() |
||||
.withSetting('Federation_Matrix_enabled', false) |
||||
.withEndpoint( |
||||
'GET', |
||||
'/v1/licenses.info', |
||||
jest.fn().mockImplementation(() => ({ |
||||
license: createFakeLicenseInfo({ activeModules: ['federation'] }), |
||||
})), |
||||
) |
||||
.build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
const federated = screen.getByLabelText('Federation_Matrix_Federated'); |
||||
|
||||
expect(federated).toBeInTheDocument(); |
||||
expect(federated).not.toBeChecked(); |
||||
expect(federated).toBeDisabled(); |
||||
expect(federated).toHaveAccessibleDescription('Federation_Matrix_Federated_Description_disabled'); |
||||
}); |
||||
|
||||
it('should render with federated option disabled when user lacks permission', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot() |
||||
.withJohnDoe() |
||||
.withSetting('Federation_Matrix_enabled', true) |
||||
.withEndpoint( |
||||
'GET', |
||||
'/v1/licenses.info', |
||||
jest.fn().mockImplementation(() => ({ |
||||
license: createFakeLicenseInfo({ activeModules: ['federation'] }), |
||||
})), |
||||
) |
||||
.build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
const federated = screen.getByLabelText('Federation_Matrix_Federated'); |
||||
|
||||
expect(federated).toBeInTheDocument(); |
||||
expect(federated).not.toBeChecked(); |
||||
expect(federated).toBeDisabled(); |
||||
expect(federated).toHaveAccessibleDescription('error-not-authorized-federation'); |
||||
}); |
||||
|
||||
it('should render with federated option enabled when user has license module, permission and feature enabled', async () => { |
||||
render(<CreateChannelModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot() |
||||
.withJohnDoe() |
||||
.withSetting('Federation_Matrix_enabled', true) |
||||
.withPermission('access-federation') |
||||
.withEndpoint( |
||||
'GET', |
||||
'/v1/licenses.info', |
||||
jest.fn().mockImplementation(() => ({ |
||||
license: createFakeLicenseInfo({ activeModules: ['federation'] }), |
||||
})), |
||||
) |
||||
.build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
const federated = screen.getByLabelText('Federation_Matrix_Federated'); |
||||
expect(federated).toBeInTheDocument(); |
||||
expect(federated).not.toBeChecked(); |
||||
expect(federated).not.toBeDisabled(); |
||||
expect(federated).toHaveAccessibleDescription('Federation_Matrix_Federated_Description'); |
||||
}); |
||||
}); |
||||
}); |
||||
} |
||||
@ -0,0 +1 @@ |
||||
export { default } from './SidebarToggler'; |
||||
@ -1 +0,0 @@ |
||||
export { default as SidebarTogglerV2 } from './SidebarToggler'; |
||||
@ -0,0 +1,247 @@ |
||||
import { mockAppRoot } from '@rocket.chat/mock-providers'; |
||||
import { render, screen } from '@testing-library/react'; |
||||
import userEvent from '@testing-library/user-event'; |
||||
|
||||
import CreateTeamModal from './CreateTeamModal'; |
||||
|
||||
jest.mock('../../../lib/utils/goToRoomById', () => ({ |
||||
goToRoomById: jest.fn(), |
||||
})); |
||||
|
||||
describe('CreateTeamModal', () => { |
||||
it('should render with encryption option disabled and set to off when E2E_Enable=false and E2E_Enabled_Default_PrivateRooms=false', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', false).withSetting('E2E_Enabled_Default_PrivateRooms', false).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Teams_New_Encrypted_Label') as HTMLInputElement; |
||||
expect(encrypted).toBeInTheDocument(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
}); |
||||
|
||||
it('should render with encryption option enabled and set to off when E2E_Enable=true and E2E_Enabled_Default_PrivateRooms=false', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', false).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Teams_New_Encrypted_Label') as HTMLInputElement; |
||||
expect(encrypted).toBeInTheDocument(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
}); |
||||
|
||||
it('should render with encryption option disabled and set to off when E2E_Enable=false and E2E_Enabled_Default_PrivateRooms=true', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', false).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Teams_New_Encrypted_Label') as HTMLInputElement; |
||||
expect(encrypted).toBeInTheDocument(); |
||||
|
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
}); |
||||
|
||||
it('should render with encryption option enabled and set to on when E2E_Enable=true and E2E_Enabled_Default_PrivateRooms=True', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Teams_New_Encrypted_Label') as HTMLInputElement; |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
}); |
||||
|
||||
it('when Private goes ON → OFF: forces Encrypted OFF and disables it (E2E_Enable=true, E2E_Enabled_Default_PrivateRooms=true)', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Teams_New_Encrypted_Label') as HTMLInputElement; |
||||
const priv = screen.getByLabelText('Teams_New_Private_Label') as HTMLInputElement; |
||||
|
||||
// initial: private=true, encrypted ON and enabled
|
||||
expect(priv).toBeChecked(); |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
|
||||
// Private ON -> OFF: encrypted must become OFF and disabled
|
||||
await userEvent.click(priv); |
||||
expect(priv).not.toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
}); |
||||
|
||||
it('when Private goes OFF → ON: keeps Encrypted OFF but re-enables it (E2E_Enable=true, E2E_Enabled_Default_PrivateRooms=true)', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Teams_New_Encrypted_Label') as HTMLInputElement; |
||||
const priv = screen.getByLabelText('Teams_New_Private_Label') as HTMLInputElement; |
||||
|
||||
// turn private OFF to simulate user path from non-private
|
||||
await userEvent.click(priv); |
||||
expect(priv).not.toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
|
||||
// turn private back ON -> encrypted should remain OFF but become enabled
|
||||
await userEvent.click(priv); |
||||
expect(priv).toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
}); |
||||
|
||||
it('private team: toggling Broadcast on/off does not change or disable Encrypted', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Teams_New_Encrypted_Label') as HTMLInputElement; |
||||
const broadcast = screen.getByLabelText('Teams_New_Broadcast_Label') as HTMLInputElement; |
||||
const priv = screen.getByLabelText('Teams_New_Private_Label') as HTMLInputElement; |
||||
|
||||
expect(priv).toBeChecked(); |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
expect(broadcast).not.toBeChecked(); |
||||
|
||||
// Broadcast: OFF -> ON (Encrypted unchanged + enabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).toBeChecked(); |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
|
||||
// Broadcast: ON -> OFF (Encrypted unchanged + enabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).not.toBeChecked(); |
||||
expect(encrypted).toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
|
||||
// User can still toggle Encrypted freely while Broadcast is OFF
|
||||
await userEvent.click(encrypted); |
||||
expect(encrypted).not.toBeChecked(); |
||||
|
||||
// User can still toggle Encrypted freely while Broadcast is ON
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeEnabled(); |
||||
}); |
||||
|
||||
it('non-private team: Encrypted remains OFF and disabled regardless of Broadcast state', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withSetting('E2E_Enable', true).withSetting('E2E_Enabled_Default_PrivateRooms', true).build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const encrypted = screen.getByLabelText('Teams_New_Encrypted_Label') as HTMLInputElement; |
||||
const broadcast = screen.getByLabelText('Teams_New_Broadcast_Label') as HTMLInputElement; |
||||
const priv = screen.getByLabelText('Teams_New_Private_Label') as HTMLInputElement; |
||||
|
||||
// Switch to non-private
|
||||
await userEvent.click(priv); |
||||
expect(priv).not.toBeChecked(); |
||||
|
||||
// Encrypted must be OFF + disabled (non-private cannot be encrypted)
|
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
|
||||
// Broadcast: OFF -> ON (Encrypted stays OFF + disabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
|
||||
// Broadcast: ON -> OFF (Encrypted still OFF + disabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).not.toBeChecked(); |
||||
expect(encrypted).not.toBeChecked(); |
||||
expect(encrypted).toBeDisabled(); |
||||
}); |
||||
|
||||
it('should disable and turn on ReadOnly toggle when Broadcast is ON and no set-readonly permission', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const broadcast = screen.getByLabelText('Teams_New_Broadcast_Label') as HTMLInputElement; |
||||
const readOnly = screen.getByLabelText('Teams_New_Read_only_Label') as HTMLInputElement; |
||||
|
||||
expect(readOnly).not.toBeChecked(); |
||||
|
||||
// Broadcast: OFF -> ON (ReadOnly stays ON + disabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).toBeChecked(); |
||||
expect(readOnly).toBeChecked(); |
||||
expect(readOnly).toBeDisabled(); |
||||
}); |
||||
|
||||
it('should disable and turn on ReadOnly toggle when Broadcast is ON with set-readonly permission', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withPermission('set-readonly').build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const broadcast = screen.getByLabelText('Teams_New_Broadcast_Label') as HTMLInputElement; |
||||
const readOnly = screen.getByLabelText('Teams_New_Read_only_Label') as HTMLInputElement; |
||||
|
||||
expect(readOnly).not.toBeChecked(); |
||||
|
||||
// Broadcast: OFF -> ON (ReadOnly stays ON + disabled)
|
||||
await userEvent.click(broadcast); |
||||
expect(broadcast).toBeChecked(); |
||||
expect(readOnly).toBeChecked(); |
||||
expect(readOnly).toBeDisabled(); |
||||
}); |
||||
|
||||
it('should disable and turn off ReadOnly toggle when Broadcast is OFF with no set-readonly permission', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const broadcast = screen.getByLabelText('Teams_New_Broadcast_Label') as HTMLInputElement; |
||||
const readOnly = screen.getByLabelText('Teams_New_Read_only_Label') as HTMLInputElement; |
||||
|
||||
expect(broadcast).not.toBeChecked(); |
||||
expect(readOnly).not.toBeChecked(); |
||||
expect(readOnly).toBeDisabled(); |
||||
}); |
||||
|
||||
it('should enable ReadOnly toggle when Broadcast is OFF with set-readonly permission', async () => { |
||||
render(<CreateTeamModal onClose={() => null} />, { |
||||
wrapper: mockAppRoot().withPermission('set-readonly').build(), |
||||
}); |
||||
|
||||
await userEvent.click(screen.getByText('Advanced_settings')); |
||||
|
||||
const broadcast = screen.getByLabelText('Teams_New_Broadcast_Label') as HTMLInputElement; |
||||
const readOnly = screen.getByLabelText('Teams_New_Read_only_Label') as HTMLInputElement; |
||||
|
||||
expect(broadcast).not.toBeChecked(); |
||||
expect(readOnly).not.toBeChecked(); |
||||
expect(readOnly).toBeEnabled(); |
||||
}); |
||||
}); |
||||
@ -1,8 +1,11 @@ |
||||
import type { HTMLAttributes, Ref } from 'react'; |
||||
import { SidebarV2ListItem } from '@rocket.chat/fuselage'; |
||||
import type { ForwardedRef, HTMLAttributes } from 'react'; |
||||
import { forwardRef } from 'react'; |
||||
|
||||
const RoomListRoomWrapper = forwardRef(function RoomListRoomWrapper(props: HTMLAttributes<HTMLDivElement>, ref: Ref<HTMLDivElement>) { |
||||
return <div role='listitem' ref={ref} {...props} />; |
||||
type RoomListRoomWrapperProps = HTMLAttributes<HTMLDivElement>; |
||||
|
||||
const RoomListRoomWrapper = forwardRef(function RoomListRoomWrapper(props: RoomListRoomWrapperProps, ref: ForwardedRef<HTMLDivElement>) { |
||||
return <SidebarV2ListItem ref={ref} {...props} />; |
||||
}); |
||||
|
||||
export default RoomListRoomWrapper; |
||||
|
||||
@ -1,226 +0,0 @@ |
||||
import type { IMessage } from '@rocket.chat/core-typings'; |
||||
import { isDirectMessageRoom, isMultipleDirectMessageRoom, isOmnichannelRoom, isVideoConfMessage } from '@rocket.chat/core-typings'; |
||||
import { Sidebar, SidebarItemAction, SidebarItemActions } from '@rocket.chat/fuselage'; |
||||
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; |
||||
import { useLayout } from '@rocket.chat/ui-contexts'; |
||||
import DOMPurify from 'dompurify'; |
||||
import type { TFunction } from 'i18next'; |
||||
import type { AllHTMLAttributes, ComponentType, ReactElement, ReactNode } from 'react'; |
||||
import { memo, useMemo } from 'react'; |
||||
|
||||
import { normalizeSidebarMessage } from './normalizeSidebarMessage'; |
||||
import { RoomIcon } from '../../components/RoomIcon'; |
||||
import { roomCoordinator } from '../../lib/rooms/roomCoordinator'; |
||||
import { isIOsDevice } from '../../lib/utils/isIOsDevice'; |
||||
import { useOmnichannelPriorities } from '../../views/omnichannel/hooks/useOmnichannelPriorities'; |
||||
import RoomMenu from '../RoomMenu'; |
||||
import SidebarItemBadges from '../badges/SidebarItemBadges'; |
||||
import type { useAvatarTemplate } from '../hooks/useAvatarTemplate'; |
||||
import { useUnreadDisplay } from '../hooks/useUnreadDisplay'; |
||||
|
||||
const getMessage = (room: SubscriptionWithRoom, lastMessage: IMessage | undefined, t: TFunction): string | undefined => { |
||||
if (!lastMessage) { |
||||
return t('No_messages_yet'); |
||||
} |
||||
if (isVideoConfMessage(lastMessage)) { |
||||
return t('Call_started'); |
||||
} |
||||
if (!lastMessage.u) { |
||||
return normalizeSidebarMessage(lastMessage, t); |
||||
} |
||||
if (lastMessage.u?.username === room.u?.username) { |
||||
return `${t('You')}: ${normalizeSidebarMessage(lastMessage, t)}`; |
||||
} |
||||
if (isDirectMessageRoom(room) && !isMultipleDirectMessageRoom(room)) { |
||||
return normalizeSidebarMessage(lastMessage, t); |
||||
} |
||||
return `${lastMessage.u.name || lastMessage.u.username}: ${normalizeSidebarMessage(lastMessage, t)}`; |
||||
}; |
||||
|
||||
type RoomListRowProps = { |
||||
extended: boolean; |
||||
t: TFunction; |
||||
SideBarItemTemplate: ComponentType< |
||||
{ |
||||
icon: ReactNode; |
||||
title: ReactNode; |
||||
avatar: ReactNode; |
||||
actions: unknown; |
||||
href: string; |
||||
time?: Date; |
||||
menu?: () => ReactNode; |
||||
menuOptions?: unknown; |
||||
subtitle?: ReactNode; |
||||
titleIcon?: string; |
||||
badges?: ReactNode; |
||||
threadUnread?: boolean; |
||||
unread?: boolean; |
||||
selected?: boolean; |
||||
is?: string; |
||||
} & AllHTMLAttributes<HTMLElement> |
||||
>; |
||||
AvatarTemplate: ReturnType<typeof useAvatarTemplate>; |
||||
openedRoom?: string; |
||||
// sidebarViewMode: 'extended';
|
||||
isAnonymous?: boolean; |
||||
|
||||
room: SubscriptionWithRoom; |
||||
id?: string; |
||||
/* @deprecated */ |
||||
style?: AllHTMLAttributes<HTMLElement>['style']; |
||||
|
||||
selected?: boolean; |
||||
|
||||
sidebarViewMode?: unknown; |
||||
videoConfActions?: { |
||||
[action: string]: () => void; |
||||
}; |
||||
}; |
||||
|
||||
function SideBarItemTemplateWithData({ |
||||
room, |
||||
id, |
||||
selected, |
||||
style, |
||||
extended, |
||||
SideBarItemTemplate, |
||||
AvatarTemplate, |
||||
t, |
||||
isAnonymous, |
||||
videoConfActions, |
||||
}: RoomListRowProps): ReactElement { |
||||
const { sidebar } = useLayout(); |
||||
|
||||
const href = roomCoordinator.getRouteLink(room.t, room) || ''; |
||||
const title = roomCoordinator.getRoomName(room.t, room) || ''; |
||||
|
||||
const { lastMessage, unread = 0, alert, rid, t: type, cl } = room; |
||||
|
||||
const { unreadCount, unreadTitle, showUnread, highlightUnread: highlighted } = useUnreadDisplay(room); |
||||
|
||||
const icon = ( |
||||
// TODO: Remove icon='at'
|
||||
<Sidebar.Item.Icon highlighted={highlighted} icon='at'> |
||||
<RoomIcon room={room} placement='sidebar' isIncomingCall={Boolean(videoConfActions)} /> |
||||
</Sidebar.Item.Icon> |
||||
); |
||||
|
||||
const actions = useMemo( |
||||
() => |
||||
videoConfActions && ( |
||||
<SidebarItemActions> |
||||
<SidebarItemAction onClick={videoConfActions.acceptCall} secondary success icon='phone' /> |
||||
<SidebarItemAction onClick={videoConfActions.rejectCall} secondary danger icon='phone-off' /> |
||||
</SidebarItemActions> |
||||
), |
||||
[videoConfActions], |
||||
); |
||||
|
||||
const isQueued = isOmnichannelRoom(room) && room.status === 'queued'; |
||||
const { enabled: isPriorityEnabled } = useOmnichannelPriorities(); |
||||
|
||||
const message = extended && getMessage(room, lastMessage, t); |
||||
const subtitle = message ? ( |
||||
<span className='message-body--unstyled' dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(message) }} /> |
||||
) : null; |
||||
|
||||
return ( |
||||
<SideBarItemTemplate |
||||
is='a' |
||||
id={id} |
||||
data-qa='sidebar-item' |
||||
data-unread={highlighted} |
||||
unread={highlighted} |
||||
selected={selected} |
||||
href={href} |
||||
onClick={(): void => { |
||||
!selected && sidebar.toggle(); |
||||
}} |
||||
aria-label={showUnread ? t('__unreadTitle__from__roomTitle__', { unreadTitle, roomTitle: title }) : title} |
||||
title={title} |
||||
time={lastMessage?.ts} |
||||
subtitle={subtitle} |
||||
icon={icon} |
||||
style={style} |
||||
badges={<SidebarItemBadges room={room} roomTitle={title} />} |
||||
avatar={AvatarTemplate && <AvatarTemplate {...room} />} |
||||
actions={actions} |
||||
menu={ |
||||
!isIOsDevice && !isAnonymous && (!isQueued || (isQueued && isPriorityEnabled)) |
||||
? (): ReactElement => ( |
||||
<RoomMenu |
||||
alert={alert} |
||||
threadUnread={unreadCount.threads > 0} |
||||
rid={rid} |
||||
unread={!!unread} |
||||
roomOpen={selected} |
||||
type={type} |
||||
cl={cl} |
||||
name={title} |
||||
hideDefaultOptions={isQueued} |
||||
/> |
||||
) |
||||
: undefined |
||||
} |
||||
/> |
||||
); |
||||
} |
||||
|
||||
function safeDateNotEqualCheck(a: Date | string | undefined, b: Date | string | undefined): boolean { |
||||
if (!a || !b) { |
||||
return a !== b; |
||||
} |
||||
return new Date(a).toISOString() !== new Date(b).toISOString(); |
||||
} |
||||
|
||||
const keys: (keyof RoomListRowProps)[] = [ |
||||
'id', |
||||
'style', |
||||
'extended', |
||||
'selected', |
||||
'SideBarItemTemplate', |
||||
'AvatarTemplate', |
||||
't', |
||||
'sidebarViewMode', |
||||
'videoConfActions', |
||||
]; |
||||
|
||||
// eslint-disable-next-line react/no-multi-comp
|
||||
export default memo(SideBarItemTemplateWithData, (prevProps, nextProps) => { |
||||
if (keys.some((key) => prevProps[key] !== nextProps[key])) { |
||||
return false; |
||||
} |
||||
|
||||
if (prevProps.room === nextProps.room) { |
||||
return true; |
||||
} |
||||
|
||||
if (prevProps.room._id !== nextProps.room._id) { |
||||
return false; |
||||
} |
||||
if (prevProps.room._updatedAt?.toISOString() !== nextProps.room._updatedAt?.toISOString()) { |
||||
return false; |
||||
} |
||||
if (safeDateNotEqualCheck(prevProps.room.lastMessage?._updatedAt, nextProps.room.lastMessage?._updatedAt)) { |
||||
return false; |
||||
} |
||||
if (prevProps.room.alert !== nextProps.room.alert) { |
||||
return false; |
||||
} |
||||
if (isOmnichannelRoom(prevProps.room) && isOmnichannelRoom(nextProps.room) && prevProps.room?.v?.status !== nextProps.room?.v?.status) { |
||||
return false; |
||||
} |
||||
if (prevProps.room.teamMain !== nextProps.room.teamMain) { |
||||
return false; |
||||
} |
||||
|
||||
if ( |
||||
isOmnichannelRoom(prevProps.room) && |
||||
isOmnichannelRoom(nextProps.room) && |
||||
prevProps.room.priorityWeight !== nextProps.room.priorityWeight |
||||
) { |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
}); |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue