From b9b1c0f0a9c1ff3287a299f18b3d03f5d2325e06 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Sat, 12 Oct 2024 02:51:45 -0300 Subject: [PATCH] test: added MockedDeviceContext to voip unit tests (#33553) --- .../src/MockedAppRootBuilder.tsx | 87 +++++++++++-------- .../src/MockedDeviceContext.tsx | 21 +++++ packages/mock-providers/src/index.ts | 1 + .../components/VoipPopup/VoipPopup.spec.tsx | 17 ++-- .../VoipPopup/VoipPopup.stories.tsx | 6 +- .../components/VoipPopupHeader.spec.tsx | 14 +-- .../VoipPopup/views/VoipDialerView.spec.tsx | 11 ++- .../VoipPopup/views/VoipErrorView.spec.tsx | 16 ++-- .../VoipPopup/views/VoipIncomingView.spec.tsx | 8 +- .../hooks/useVoipDeviceSettings.spec.tsx | 25 +----- .../components/VoipTimer/VoipTimer.spec.tsx | 9 +- .../VoipTransferModal.spec.tsx | 8 +- 12 files changed, 126 insertions(+), 97 deletions(-) create mode 100644 packages/mock-providers/src/MockedDeviceContext.tsx diff --git a/packages/mock-providers/src/MockedAppRootBuilder.tsx b/packages/mock-providers/src/MockedAppRootBuilder.tsx index 646a78a4d815..73b6683d3edc 100644 --- a/packages/mock-providers/src/MockedAppRootBuilder.tsx +++ b/packages/mock-providers/src/MockedAppRootBuilder.tsx @@ -3,7 +3,7 @@ import type { ServerMethodName, ServerMethodParameters, ServerMethodReturn } fro import { Emitter } from '@rocket.chat/emitter'; import languages from '@rocket.chat/i18n/dist/languages'; import type { Method, OperationParams, OperationResult, PathPattern, UrlParams } from '@rocket.chat/rest-typings'; -import type { ModalContextValue, TranslationKey } from '@rocket.chat/ui-contexts'; +import type { Device, ModalContextValue, TranslationKey } from '@rocket.chat/ui-contexts'; import { AuthorizationContext, ConnectionStatusContext, @@ -24,6 +24,8 @@ import React, { useEffect, useReducer } from 'react'; import { I18nextProvider, initReactI18next } from 'react-i18next'; import { useSyncExternalStore } from 'use-sync-external-store/shim'; +import { MockedDeviceContext } from './MockedDeviceContext'; + type Mutable = { -readonly [P in keyof T]: T[P]; }; @@ -126,6 +128,10 @@ export class MockedAppRootBuilder { private events = new Emitter(); + private audioInputDevices: Device[] = []; + + private audioOutputDevices: Device[] = []; + wrap(wrapper: (children: ReactNode) => ReactNode): this { this.wrappers.push(wrapper); return this; @@ -338,6 +344,16 @@ export class MockedAppRootBuilder { return this; } + withAudioInputDevices(devices: Device[]): this { + this.audioInputDevices = devices; + return this; + } + + withAudioOutputDevices(devices: Device[]): this { + this.audioOutputDevices = devices; + return this; + } + private i18n = createInstance({ // debug: true, lng: 'en', @@ -382,7 +398,7 @@ export class MockedAppRootBuilder { }, }); - const { connectionStatus, server, router, settings, user, i18n, authorization, wrappers } = this; + const { connectionStatus, server, router, settings, user, i18n, authorization, wrappers, audioInputDevices, audioOutputDevices } = this; const reduceTranslation = (translation?: ContextType): ContextType => { return { @@ -457,46 +473,49 @@ export class MockedAppRootBuilder { */} - {/* */} - - - {/* + + + + {/* */} - '', - emitInteraction: () => Promise.reject(new Error('not implemented')), - getInteractionPayloadByViewId: () => undefined, - handleServerInteraction: () => undefined, - off: () => undefined, - on: () => undefined, - openView: () => undefined, - disposeView: () => undefined, - notifyBusy: () => undefined, - notifyIdle: () => undefined, - }} - > - {/* + '', + emitInteraction: () => Promise.reject(new Error('not implemented')), + getInteractionPayloadByViewId: () => undefined, + handleServerInteraction: () => undefined, + off: () => undefined, + on: () => undefined, + openView: () => undefined, + disposeView: () => undefined, + notifyBusy: () => undefined, + notifyIdle: () => undefined, + }} + > + {/* */} - {wrappers.reduce( - (children, wrapper) => wrapper(children), - <> - {children} - {modal.currentModal.component} - , - )} - {/* + {wrappers.reduce( + (children, wrapper) => wrapper(children), + <> + {children} + {modal.currentModal.component} + , + )} + {/* */} - - {/* + + {/* */} - - - {/* */} + + + {/* diff --git a/packages/mock-providers/src/MockedDeviceContext.tsx b/packages/mock-providers/src/MockedDeviceContext.tsx new file mode 100644 index 000000000000..ab946aa02c9b --- /dev/null +++ b/packages/mock-providers/src/MockedDeviceContext.tsx @@ -0,0 +1,21 @@ +import type { DeviceContextValue } from '@rocket.chat/ui-contexts'; +import { DeviceContext } from '@rocket.chat/ui-contexts'; +import React from 'react'; + +const mockDeviceContextValue: DeviceContextValue = { + enabled: true, + selectedAudioOutputDevice: undefined, + selectedAudioInputDevice: undefined, + availableAudioOutputDevices: [], + availableAudioInputDevices: [], + setAudioOutputDevice: () => undefined, + setAudioInputDevice: () => undefined, +}; + +type MockedDeviceContextProps = Partial & { + children: React.ReactNode; +}; + +export const MockedDeviceContext = ({ children, ...props }: MockedDeviceContextProps) => { + return {children}; +}; diff --git a/packages/mock-providers/src/index.ts b/packages/mock-providers/src/index.ts index 22e4427cea1c..38a92c053e4b 100644 --- a/packages/mock-providers/src/index.ts +++ b/packages/mock-providers/src/index.ts @@ -7,3 +7,4 @@ export * from './MockedModalContext'; export * from './MockedServerContext'; export * from './MockedSettingsContext'; export * from './MockedUserContext'; +export * from './MockedDeviceContext'; diff --git a/packages/ui-voip/src/components/VoipPopup/VoipPopup.spec.tsx b/packages/ui-voip/src/components/VoipPopup/VoipPopup.spec.tsx index 9a442eef572d..644b8aba4720 100644 --- a/packages/ui-voip/src/components/VoipPopup/VoipPopup.spec.tsx +++ b/packages/ui-voip/src/components/VoipPopup/VoipPopup.spec.tsx @@ -18,10 +18,11 @@ jest.mock('../../hooks/useVoipDialer', () => ({ })); const mockedUseVoipSession = jest.mocked(useVoipSession); +const appRoot = mockAppRoot(); it('should properly render incoming popup', async () => { mockedUseVoipSession.mockImplementationOnce(() => createMockVoipSession({ type: 'INCOMING' })); - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByTestId('vc-popup-incoming')).toBeInTheDocument(); }); @@ -29,7 +30,7 @@ it('should properly render incoming popup', async () => { it('should properly render ongoing popup', async () => { mockedUseVoipSession.mockImplementationOnce(() => createMockVoipSession({ type: 'ONGOING' })); - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByTestId('vc-popup-ongoing')).toBeInTheDocument(); }); @@ -37,7 +38,7 @@ it('should properly render ongoing popup', async () => { it('should properly render outgoing popup', async () => { mockedUseVoipSession.mockImplementationOnce(() => createMockVoipSession({ type: 'OUTGOING' })); - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByTestId('vc-popup-outgoing')).toBeInTheDocument(); }); @@ -45,13 +46,13 @@ it('should properly render outgoing popup', async () => { it('should properly render error popup', async () => { mockedUseVoipSession.mockImplementationOnce(() => createMockVoipSession({ type: 'ERROR' })); - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByTestId('vc-popup-error')).toBeInTheDocument(); }); it('should properly render dialer popup', async () => { - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByTestId('vc-popup-dialer')).toBeInTheDocument(); }); @@ -59,7 +60,7 @@ it('should properly render dialer popup', async () => { it('should prioritize session over dialer', async () => { mockedUseVoipSession.mockImplementationOnce(() => createMockVoipSession({ type: 'INCOMING' })); - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.queryByTestId('vc-popup-dialer')).not.toBeInTheDocument(); expect(screen.getByTestId('vc-popup-incoming')).toBeInTheDocument(); @@ -68,12 +69,12 @@ it('should prioritize session over dialer', async () => { const testCases = Object.values(composeStories(stories)).map((story) => [story.storyName || 'Story', story]); test.each(testCases)(`renders %s without crashing`, async (_storyname, Story) => { - const tree = render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + const tree = render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(replaceReactAriaIds(tree.baseElement)).toMatchSnapshot(); }); test.each(testCases)('%s should have no a11y violations', async (_storyname, Story) => { - const { container } = render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + const { container } = render(, { wrapper: appRoot.build(), legacyRoot: true }); const results = await axe(container); expect(results).toHaveNoViolations(); diff --git a/packages/ui-voip/src/components/VoipPopup/VoipPopup.stories.tsx b/packages/ui-voip/src/components/VoipPopup/VoipPopup.stories.tsx index 128a15071eb8..b3bc0bda38a4 100644 --- a/packages/ui-voip/src/components/VoipPopup/VoipPopup.stories.tsx +++ b/packages/ui-voip/src/components/VoipPopup/VoipPopup.stories.tsx @@ -14,6 +14,7 @@ const MockVoipClient = class extends Emitter { setSessionType(type: VoipSession['type']) { this._sessionType = type; + setTimeout(() => this.emit('stateChanged'), 0); } getSession = () => @@ -47,11 +48,6 @@ const queryClient = new QueryClient({ queries: { retry: false }, mutations: { retry: false }, }, - logger: { - log: console.log, - warn: console.warn, - error: () => undefined, - }, }); export default { diff --git a/packages/ui-voip/src/components/VoipPopup/components/VoipPopupHeader.spec.tsx b/packages/ui-voip/src/components/VoipPopup/components/VoipPopupHeader.spec.tsx index 9c51e5ad3bc8..07e455260522 100644 --- a/packages/ui-voip/src/components/VoipPopup/components/VoipPopupHeader.spec.tsx +++ b/packages/ui-voip/src/components/VoipPopup/components/VoipPopupHeader.spec.tsx @@ -3,40 +3,42 @@ import { render, screen } from '@testing-library/react'; import VoipPopupHeader from './VoipPopupHeader'; +const appRoot = mockAppRoot(); + it('should render title', () => { - render(voice call header title, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(voice call header title, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByText('voice call header title')).toBeInTheDocument(); }); it('should not render close button when onClose is not provided', () => { - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.queryByRole('button', { name: 'Close' })).not.toBeInTheDocument(); }); it('should render close button when onClose is provided', () => { - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByRole('button', { name: 'Close' })).toBeInTheDocument(); }); it('should call onClose when close button is clicked', () => { const closeFn = jest.fn(); - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); screen.getByRole('button', { name: 'Close' }).click(); expect(closeFn).toHaveBeenCalled(); }); it('should render settings button by default', () => { - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByRole('button', { name: /Device_settings/ })).toBeInTheDocument(); }); it('should not render settings button when hideSettings is true', () => { - render(text, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(text, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.queryByRole('button', { name: /Device_settings/ })).not.toBeInTheDocument(); }); diff --git a/packages/ui-voip/src/components/VoipPopup/views/VoipDialerView.spec.tsx b/packages/ui-voip/src/components/VoipPopup/views/VoipDialerView.spec.tsx index efe175bffad3..3add6e463982 100644 --- a/packages/ui-voip/src/components/VoipPopup/views/VoipDialerView.spec.tsx +++ b/packages/ui-voip/src/components/VoipPopup/views/VoipDialerView.spec.tsx @@ -6,12 +6,15 @@ import VoipDialerView from './VoipDialerView'; const makeCall = jest.fn(); const closeDialer = jest.fn(); + +const appRoot = mockAppRoot(); + jest.mock('../../../hooks/useVoipAPI', () => ({ useVoipAPI: jest.fn(() => ({ makeCall, closeDialer })), })); it('should look good', async () => { - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByText('New_Call')).toBeInTheDocument(); expect(screen.getByRole('button', { name: /Device_settings/ })).toBeInTheDocument(); @@ -19,7 +22,7 @@ it('should look good', async () => { }); it('should only enable call button if input has value (keyboard)', async () => { - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByRole('button', { name: /Call/i })).toBeDisabled(); await userEvent.type(screen.getByLabelText('Phone_number'), '123'); @@ -27,7 +30,7 @@ it('should only enable call button if input has value (keyboard)', async () => { }); it('should only enable call button if input has value (mouse)', async () => { - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByRole('button', { name: /Call/i })).toBeDisabled(); screen.getByTestId(`dial-pad-button-1`).click(); @@ -37,7 +40,7 @@ it('should only enable call button if input has value (mouse)', async () => { }); it('should call methods makeCall and closeDialer when call button is clicked', async () => { - render(, { wrapper: mockAppRoot().build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); await userEvent.type(screen.getByLabelText('Phone_number'), '123'); screen.getByTestId(`dial-pad-button-1`).click(); diff --git a/packages/ui-voip/src/components/VoipPopup/views/VoipErrorView.spec.tsx b/packages/ui-voip/src/components/VoipPopup/views/VoipErrorView.spec.tsx index 2b7823d9141a..426b284f5102 100644 --- a/packages/ui-voip/src/components/VoipPopup/views/VoipErrorView.spec.tsx +++ b/packages/ui-voip/src/components/VoipPopup/views/VoipErrorView.spec.tsx @@ -4,11 +4,11 @@ import { render, screen, within } from '@testing-library/react'; import { createMockFreeSwitchExtensionDetails, createMockVoipErrorSession } from '../../../tests/mocks'; import VoipErrorView from './VoipErrorView'; -const wrapper = mockAppRoot().withEndpoint('GET', '/v1/voip-freeswitch.extension.getDetails', () => createMockFreeSwitchExtensionDetails()); +const appRoot = mockAppRoot().withEndpoint('GET', '/v1/voip-freeswitch.extension.getDetails', () => createMockFreeSwitchExtensionDetails()); it('should properly render error view', async () => { const errorSession = createMockVoipErrorSession({ error: { status: -1, reason: '' } }); - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.queryByLabelText('Device_settings')).not.toBeInTheDocument(); expect(await screen.findByText('Administrator')).toBeInTheDocument(); @@ -16,7 +16,7 @@ it('should properly render error view', async () => { it('should only enable error actions', () => { const errorSession = createMockVoipErrorSession({ error: { status: -1, reason: '' } }); - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(within(screen.getByTestId('vc-popup-footer')).queryAllByRole('button')).toHaveLength(5); expect(screen.getByRole('button', { name: 'Turn_off_microphone' })).toBeDisabled(); @@ -28,7 +28,7 @@ it('should only enable error actions', () => { it('should properly interact with the voice call session', () => { const errorSession = createMockVoipErrorSession({ error: { status: -1, reason: '' } }); - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); screen.getByRole('button', { name: 'End_call' }).click(); expect(errorSession.end).toHaveBeenCalled(); @@ -36,7 +36,7 @@ it('should properly interact with the voice call session', () => { it('should properly render unknown error calls', async () => { const session = createMockVoipErrorSession({ error: { status: -1, reason: '' } }); - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByText('Unable_to_complete_call')).toBeInTheDocument(); screen.getByRole('button', { name: 'End_call' }).click(); @@ -45,7 +45,7 @@ it('should properly render unknown error calls', async () => { it('should properly render error for unavailable calls', async () => { const session = createMockVoipErrorSession({ error: { status: 480, reason: '' } }); - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByText('Temporarily_unavailable')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'End_call' })).toBeEnabled(); @@ -55,7 +55,7 @@ it('should properly render error for unavailable calls', async () => { it('should properly render error for busy calls', async () => { const session = createMockVoipErrorSession({ error: { status: 486, reason: '' } }); - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByText('Caller_is_busy')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'End_call' })).toBeEnabled(); @@ -65,7 +65,7 @@ it('should properly render error for busy calls', async () => { it('should properly render error for terminated calls', async () => { const session = createMockVoipErrorSession({ error: { status: 487, reason: '' } }); - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByText('Call_terminated')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'End_call' })).toBeEnabled(); diff --git a/packages/ui-voip/src/components/VoipPopup/views/VoipIncomingView.spec.tsx b/packages/ui-voip/src/components/VoipPopup/views/VoipIncomingView.spec.tsx index 9b364d51178e..67e1bdc131f0 100644 --- a/packages/ui-voip/src/components/VoipPopup/views/VoipIncomingView.spec.tsx +++ b/packages/ui-voip/src/components/VoipPopup/views/VoipIncomingView.spec.tsx @@ -4,12 +4,12 @@ import { render, screen, within } from '@testing-library/react'; import { createMockFreeSwitchExtensionDetails, createMockVoipIncomingSession } from '../../../tests/mocks'; import VoipIncomingView from './VoipIncomingView'; -const wrapper = mockAppRoot().withEndpoint('GET', '/v1/voip-freeswitch.extension.getDetails', () => createMockFreeSwitchExtensionDetails()); +const appRoot = mockAppRoot().withEndpoint('GET', '/v1/voip-freeswitch.extension.getDetails', () => createMockFreeSwitchExtensionDetails()); const incomingSession = createMockVoipIncomingSession(); it('should properly render incoming view', async () => { - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByText('Incoming_call...')).toBeInTheDocument(); expect(screen.getByRole('button', { name: /Device_settings/ })).toBeInTheDocument(); @@ -17,7 +17,7 @@ it('should properly render incoming view', async () => { }); it('should only enable incoming actions', () => { - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(within(screen.getByTestId('vc-popup-footer')).queryAllByRole('button')).toHaveLength(5); expect(screen.getByRole('button', { name: 'Decline' })).toBeEnabled(); @@ -28,7 +28,7 @@ it('should only enable incoming actions', () => { }); it('should properly interact with the voice call session', () => { - render(, { wrapper: wrapper.build(), legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); screen.getByRole('button', { name: 'Decline' }).click(); screen.getByRole('button', { name: 'Accept' }).click(); diff --git a/packages/ui-voip/src/components/VoipSettingsButton/hooks/useVoipDeviceSettings.spec.tsx b/packages/ui-voip/src/components/VoipSettingsButton/hooks/useVoipDeviceSettings.spec.tsx index 17da9f5d8142..d0419e367e07 100644 --- a/packages/ui-voip/src/components/VoipSettingsButton/hooks/useVoipDeviceSettings.spec.tsx +++ b/packages/ui-voip/src/components/VoipSettingsButton/hooks/useVoipDeviceSettings.spec.tsx @@ -1,24 +1,11 @@ import { mockAppRoot } from '@rocket.chat/mock-providers'; -import { DeviceContext, DeviceContextValue } from '@rocket.chat/ui-contexts'; import { renderHook } from '@testing-library/react'; import { useVoipDeviceSettings } from './useVoipDeviceSettings'; -let mockDeviceContextValue = { - enabled: true, - selectedAudioOutputDevice: undefined, - selectedAudioInputDevice: undefined, - availableAudioOutputDevices: [], - availableAudioInputDevices: [], - setAudioOutputDevice: () => undefined, - setAudioInputDevice: () => undefined, -} as unknown as DeviceContextValue; - it('should be disabled when there are no devices', () => { const { result } = renderHook(() => useVoipDeviceSettings(), { - wrapper: mockAppRoot() - .wrap((children) => {children}) - .build(), + wrapper: mockAppRoot().build(), legacyRoot: true, }); @@ -27,16 +14,10 @@ it('should be disabled when there are no devices', () => { }); it('should be enabled when there are devices', () => { - mockDeviceContextValue = { - ...mockDeviceContextValue, - - availableAudioOutputDevices: [{ label: '' }], - availableAudioInputDevices: [{ label: '' }], - } as unknown as DeviceContextValue; - const { result } = renderHook(() => useVoipDeviceSettings(), { wrapper: mockAppRoot() - .wrap((children) => {children}) + .withAudioInputDevices([{ type: '', id: '', label: '' }]) + .withAudioOutputDevices([{ type: '', id: '', label: '' }]) .build(), legacyRoot: true, }); diff --git a/packages/ui-voip/src/components/VoipTimer/VoipTimer.spec.tsx b/packages/ui-voip/src/components/VoipTimer/VoipTimer.spec.tsx index 12a01e9b33bf..7121a0f1176e 100644 --- a/packages/ui-voip/src/components/VoipTimer/VoipTimer.spec.tsx +++ b/packages/ui-voip/src/components/VoipTimer/VoipTimer.spec.tsx @@ -1,7 +1,10 @@ +import { mockAppRoot } from '@rocket.chat/mock-providers'; import { act, render, screen } from '@testing-library/react'; import VoipTimer from './VoipTimer'; +const appRoot = mockAppRoot(); + describe('VoipTimer', () => { beforeEach(() => { jest.useFakeTimers(); @@ -12,13 +15,13 @@ describe('VoipTimer', () => { }); it('should display the initial time correctly', () => { - render(, { legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByText('00:00')).toBeInTheDocument(); }); it('should update the time after a few seconds', () => { - render(, { legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); act(() => { jest.advanceTimersByTime(5000); @@ -30,7 +33,7 @@ describe('VoipTimer', () => { it('should start with a minute on the timer', () => { const startTime = new Date(); startTime.setMinutes(startTime.getMinutes() - 1); - render(, { legacyRoot: true }); + render(, { wrapper: appRoot.build(), legacyRoot: true }); expect(screen.getByText('01:00')).toBeInTheDocument(); }); diff --git a/packages/ui-voip/src/components/VoipTransferModal/VoipTransferModal.spec.tsx b/packages/ui-voip/src/components/VoipTransferModal/VoipTransferModal.spec.tsx index 09c8037cd9f9..ddec476bcf77 100644 --- a/packages/ui-voip/src/components/VoipTransferModal/VoipTransferModal.spec.tsx +++ b/packages/ui-voip/src/components/VoipTransferModal/VoipTransferModal.spec.tsx @@ -1,5 +1,5 @@ import { mockAppRoot } from '@rocket.chat/mock-providers'; -import { render, screen } from '@testing-library/react'; +import { act, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import VoipTransferModal from '.'; @@ -58,8 +58,10 @@ it('should be able to select transfer target', async () => { expect(hangUpAnTransferButton).toBeDisabled(); screen.getByLabelText('Transfer_to').focus(); - const userOption = await screen.findByRole('option', { name: 'Jane Doe' }); - await userEvent.click(userOption); + await act(async () => { + const userOption = await screen.findByRole('option', { name: 'Jane Doe' }); + await userEvent.click(userOption); + }); expect(hangUpAnTransferButton).toBeEnabled(); hangUpAnTransferButton.click();