Convert some tests from Enzyme to RTL (#9483)

This commit is contained in:
Michael Telatynski 2022-10-24 09:06:20 +01:00 committed by GitHub
parent 9eb4f8d723
commit 913af09e61
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 313 additions and 450 deletions

View file

@ -47,7 +47,7 @@ const ShareLatestLocation: React.FC<Props> = ({ latestLocationState }) => {
return <> return <>
<TooltipTarget label={_t('Open in OpenStreetMap')}> <TooltipTarget label={_t('Open in OpenStreetMap')}>
<a <a
data-test-id='open-location-in-osm' data-testid='open-location-in-osm'
href={mapLink} href={mapLink}
target='_blank' target='_blank'
rel='noreferrer noopener' rel='noreferrer noopener'

View file

@ -15,8 +15,7 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
// eslint-disable-next-line deprecate/import import { fireEvent, render } from "@testing-library/react";
import { mount } from 'enzyme';
import { import {
Beacon, Beacon,
RoomMember, RoomMember,
@ -28,7 +27,6 @@ import { act } from 'react-dom/test-utils';
import BeaconListItem from '../../../../src/components/views/beacon/BeaconListItem'; import BeaconListItem from '../../../../src/components/views/beacon/BeaconListItem';
import MatrixClientContext from '../../../../src/contexts/MatrixClientContext'; import MatrixClientContext from '../../../../src/contexts/MatrixClientContext';
import { import {
findByTestId,
getMockClientWithEventEmitter, getMockClientWithEventEmitter,
makeBeaconEvent, makeBeaconEvent,
makeBeaconInfoEvent, makeBeaconInfoEvent,
@ -76,11 +74,9 @@ describe('<BeaconListItem />', () => {
beacon: new Beacon(aliceBeaconEvent), beacon: new Beacon(aliceBeaconEvent),
}; };
const getComponent = (props = {}) => const getComponent = (props = {}) => render(<MatrixClientContext.Provider value={mockClient}>
mount(<BeaconListItem {...defaultProps} {...props} />, { <BeaconListItem {...defaultProps} {...props} />
wrappingComponent: MatrixClientContext.Provider, </MatrixClientContext.Provider>);
wrappingComponentProps: { value: mockClient },
});
const setupRoomWithBeacons = (beaconInfoEvents: MatrixEvent[], locationEvents?: MatrixEvent[]): Beacon[] => { const setupRoomWithBeacons = (beaconInfoEvents: MatrixEvent[], locationEvents?: MatrixEvent[]): Beacon[] => {
const beacons = makeRoomWithBeacons(roomId, mockClient, beaconInfoEvents, locationEvents); const beacons = makeRoomWithBeacons(roomId, mockClient, beaconInfoEvents, locationEvents);
@ -104,71 +100,72 @@ describe('<BeaconListItem />', () => {
{ isLive: false }, { isLive: false },
); );
const [beacon] = setupRoomWithBeacons([notLiveBeacon]); const [beacon] = setupRoomWithBeacons([notLiveBeacon]);
const component = getComponent({ beacon }); const { container } = getComponent({ beacon });
expect(component.html()).toBeNull(); expect(container.innerHTML).toBeFalsy();
}); });
it('renders null when beacon has no location', () => { it('renders null when beacon has no location', () => {
const [beacon] = setupRoomWithBeacons([aliceBeaconEvent]); const [beacon] = setupRoomWithBeacons([aliceBeaconEvent]);
const component = getComponent({ beacon }); const { container } = getComponent({ beacon });
expect(component.html()).toBeNull(); expect(container.innerHTML).toBeFalsy();
}); });
describe('when a beacon is live and has locations', () => { describe('when a beacon is live and has locations', () => {
it('renders beacon info', () => { it('renders beacon info', () => {
const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]);
const component = getComponent({ beacon }); const { asFragment } = getComponent({ beacon });
expect(component.html()).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
describe('non-self beacons', () => { describe('non-self beacons', () => {
it('uses beacon description as beacon name', () => { it('uses beacon description as beacon name', () => {
const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]);
const component = getComponent({ beacon }); const { container } = getComponent({ beacon });
expect(component.find('BeaconStatus').props().label).toEqual("Alice's car"); expect(container.querySelector('.mx_BeaconStatus_label')).toHaveTextContent("Alice's car");
}); });
it('uses beacon owner mxid as beacon name for a beacon without description', () => { it('uses beacon owner mxid as beacon name for a beacon without description', () => {
const [beacon] = setupRoomWithBeacons([pinBeaconWithoutDescription], [aliceLocation1]); const [beacon] = setupRoomWithBeacons([pinBeaconWithoutDescription], [aliceLocation1]);
const component = getComponent({ beacon }); const { container } = getComponent({ beacon });
expect(component.find('BeaconStatus').props().label).toEqual(aliceId); expect(container.querySelector('.mx_BeaconStatus_label')).toHaveTextContent(aliceId);
}); });
it('renders location icon', () => { it('renders location icon', () => {
const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]);
const component = getComponent({ beacon }); const { container } = getComponent({ beacon });
expect(component.find('StyledLiveBeaconIcon').length).toBeTruthy(); expect(container.querySelector('.mx_StyledLiveBeaconIcon')).toBeTruthy();
}); });
}); });
describe('self locations', () => { describe('self locations', () => {
it('renders beacon owner avatar', () => { it('renders beacon owner avatar', () => {
const [beacon] = setupRoomWithBeacons([aliceBeaconEvent], [aliceLocation1]); const [beacon] = setupRoomWithBeacons([aliceBeaconEvent], [aliceLocation1]);
const component = getComponent({ beacon }); const { container } = getComponent({ beacon });
expect(component.find('MemberAvatar').length).toBeTruthy(); expect(container.querySelector('.mx_BaseAvatar')).toBeTruthy();
}); });
it('uses beacon owner name as beacon name', () => { it('uses beacon owner name as beacon name', () => {
const [beacon] = setupRoomWithBeacons([aliceBeaconEvent], [aliceLocation1]); const [beacon] = setupRoomWithBeacons([aliceBeaconEvent], [aliceLocation1]);
const component = getComponent({ beacon }); const { container } = getComponent({ beacon });
expect(component.find('BeaconStatus').props().label).toEqual('Alice'); expect(container.querySelector('.mx_BeaconStatus_label')).toHaveTextContent("Alice");
}); });
}); });
describe('on location updates', () => { describe('on location updates', () => {
it('updates last updated time on location updated', () => { it('updates last updated time on location updated', () => {
const [beacon] = setupRoomWithBeacons([aliceBeaconEvent], [aliceLocation2]); const [beacon] = setupRoomWithBeacons([aliceBeaconEvent], [aliceLocation2]);
const component = getComponent({ beacon }); const { container } = getComponent({ beacon });
expect(component.find('.mx_BeaconListItem_lastUpdated').text()).toEqual('Updated 9 minutes ago'); expect(container.querySelector('.mx_BeaconListItem_lastUpdated'))
.toHaveTextContent('Updated 9 minutes ago');
// update to a newer location // update to a newer location
act(() => { act(() => {
beacon.addLocations([aliceLocation1]); beacon.addLocations([aliceLocation1]);
component.setProps({});
}); });
expect(component.find('.mx_BeaconListItem_lastUpdated').text()).toEqual('Updated a few seconds ago'); expect(container.querySelector('.mx_BeaconListItem_lastUpdated'))
.toHaveTextContent('Updated a few seconds ago');
}); });
}); });
@ -176,23 +173,19 @@ describe('<BeaconListItem />', () => {
it('does not call onClick handler when clicking share button', () => { it('does not call onClick handler when clicking share button', () => {
const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]);
const onClick = jest.fn(); const onClick = jest.fn();
const component = getComponent({ beacon, onClick }); const { getByTestId } = getComponent({ beacon, onClick });
act(() => { fireEvent.click(getByTestId('open-location-in-osm'));
findByTestId(component, 'open-location-in-osm').at(0).simulate('click');
});
expect(onClick).not.toHaveBeenCalled(); expect(onClick).not.toHaveBeenCalled();
}); });
it('calls onClick handler when clicking outside of share buttons', () => { it('calls onClick handler when clicking outside of share buttons', () => {
const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]);
const onClick = jest.fn(); const onClick = jest.fn();
const component = getComponent({ beacon, onClick }); const { container } = getComponent({ beacon, onClick });
act(() => { // click the beacon name
// click the beacon name fireEvent.click(container.querySelector(".mx_BeaconStatus_description"));
component.find('.mx_BeaconStatus_description').simulate('click');
});
expect(onClick).toHaveBeenCalled(); expect(onClick).toHaveBeenCalled();
}); });
}); });

View file

@ -16,8 +16,7 @@ limitations under the License.
import React from 'react'; import React from 'react';
import { mocked } from 'jest-mock'; import { mocked } from 'jest-mock';
// eslint-disable-next-line deprecate/import import { fireEvent, render } from "@testing-library/react";
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils'; import { act } from 'react-dom/test-utils';
import { Beacon, BeaconIdentifier } from 'matrix-js-sdk/src/matrix'; import { Beacon, BeaconIdentifier } from 'matrix-js-sdk/src/matrix';
@ -48,9 +47,7 @@ jest.mock('../../../../src/stores/OwnBeaconStore', () => {
); );
describe('<LeftPanelLiveShareWarning />', () => { describe('<LeftPanelLiveShareWarning />', () => {
const defaultProps = {}; const getComponent = (props = {}) => render(<LeftPanelLiveShareWarning {...props} />);
const getComponent = (props = {}) =>
mount(<LeftPanelLiveShareWarning {...defaultProps} {...props} />);
const roomId1 = '!room1:server'; const roomId1 = '!room1:server';
const roomId2 = '!room2:server'; const roomId2 = '!room2:server';
@ -85,8 +82,8 @@ describe('<LeftPanelLiveShareWarning />', () => {
)); ));
it('renders nothing when user has no live beacons', () => { it('renders nothing when user has no live beacons', () => {
const component = getComponent(); const { container } = getComponent();
expect(component.html()).toBe(null); expect(container.innerHTML).toBeFalsy();
}); });
describe('when user has live location monitor', () => { describe('when user has live location monitor', () => {
@ -110,17 +107,15 @@ describe('<LeftPanelLiveShareWarning />', () => {
}); });
it('renders correctly when not minimized', () => { it('renders correctly when not minimized', () => {
const component = getComponent(); const { asFragment } = getComponent();
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
it('goes to room of latest beacon when clicked', () => { it('goes to room of latest beacon when clicked', () => {
const component = getComponent(); const { container } = getComponent();
const dispatchSpy = jest.spyOn(dispatcher, 'dispatch'); const dispatchSpy = jest.spyOn(dispatcher, 'dispatch');
act(() => { fireEvent.click(container.querySelector("[role=button]"));
component.simulate('click');
});
expect(dispatchSpy).toHaveBeenCalledWith({ expect(dispatchSpy).toHaveBeenCalledWith({
action: Action.ViewRoom, action: Action.ViewRoom,
@ -134,28 +129,26 @@ describe('<LeftPanelLiveShareWarning />', () => {
}); });
it('renders correctly when minimized', () => { it('renders correctly when minimized', () => {
const component = getComponent({ isMinimized: true }); const { asFragment } = getComponent({ isMinimized: true });
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
it('renders location publish error', () => { it('renders location publish error', () => {
mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithLocationPublishError.mockReturnValue( mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithLocationPublishError.mockReturnValue(
[beacon1.identifier], [beacon1.identifier],
); );
const component = getComponent(); const { asFragment } = getComponent();
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
it('goes to room of latest beacon with location publish error when clicked', () => { it('goes to room of latest beacon with location publish error when clicked', () => {
mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithLocationPublishError.mockReturnValue( mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithLocationPublishError.mockReturnValue(
[beacon1.identifier], [beacon1.identifier],
); );
const component = getComponent(); const { container } = getComponent();
const dispatchSpy = jest.spyOn(dispatcher, 'dispatch'); const dispatchSpy = jest.spyOn(dispatcher, 'dispatch');
act(() => { fireEvent.click(container.querySelector("[role=button]"));
component.simulate('click');
});
expect(dispatchSpy).toHaveBeenCalledWith({ expect(dispatchSpy).toHaveBeenCalledWith({
action: Action.ViewRoom, action: Action.ViewRoom,
@ -172,9 +165,9 @@ describe('<LeftPanelLiveShareWarning />', () => {
mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithLocationPublishError.mockReturnValue( mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithLocationPublishError.mockReturnValue(
[beacon1.identifier], [beacon1.identifier],
); );
const component = getComponent(); const { container, rerender } = getComponent();
// error mode // error mode
expect(component.find('.mx_LeftPanelLiveShareWarning').at(0).text()).toEqual( expect(container.querySelector('.mx_LeftPanelLiveShareWarning').textContent).toEqual(
'An error occurred whilst sharing your live location', 'An error occurred whilst sharing your live location',
); );
@ -183,18 +176,18 @@ describe('<LeftPanelLiveShareWarning />', () => {
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.LocationPublishError, 'abc'); OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.LocationPublishError, 'abc');
}); });
component.setProps({}); rerender(<LeftPanelLiveShareWarning />);
// default mode // default mode
expect(component.find('.mx_LeftPanelLiveShareWarning').at(0).text()).toEqual( expect(container.querySelector('.mx_LeftPanelLiveShareWarning').textContent).toEqual(
'You are sharing your live location', 'You are sharing your live location',
); );
}); });
it('removes itself when user stops having live beacons', async () => { it('removes itself when user stops having live beacons', async () => {
const component = getComponent({ isMinimized: true }); const { container, rerender } = getComponent({ isMinimized: true });
// started out rendered // started out rendered
expect(component.html()).toBeTruthy(); expect(container.innerHTML).toBeTruthy();
act(() => { act(() => {
mocked(OwnBeaconStore.instance).isMonitoringLiveLocation = false; mocked(OwnBeaconStore.instance).isMonitoringLiveLocation = false;
@ -202,9 +195,9 @@ describe('<LeftPanelLiveShareWarning />', () => {
}); });
await flushPromises(); await flushPromises();
component.setProps({}); rerender(<LeftPanelLiveShareWarning />);
expect(component.html()).toBe(null); expect(container.innerHTML).toBeFalsy();
}); });
it('refreshes beacon liveness monitors when pagevisibilty changes to visible', () => { it('refreshes beacon liveness monitors when pagevisibilty changes to visible', () => {
@ -228,21 +221,21 @@ describe('<LeftPanelLiveShareWarning />', () => {
describe('stopping errors', () => { describe('stopping errors', () => {
it('renders stopping error', () => { it('renders stopping error', () => {
OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error')); OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error'));
const component = getComponent(); const { container } = getComponent();
expect(component.text()).toEqual('An error occurred while stopping your live location'); expect(container.textContent).toEqual('An error occurred while stopping your live location');
}); });
it('starts rendering stopping error on beaconUpdateError emit', () => { it('starts rendering stopping error on beaconUpdateError emit', () => {
const component = getComponent(); const { container } = getComponent();
// no error // no error
expect(component.text()).toEqual('You are sharing your live location'); expect(container.textContent).toEqual('You are sharing your live location');
act(() => { act(() => {
OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error')); OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error'));
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.BeaconUpdateError, beacon2.identifier, true); OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.BeaconUpdateError, beacon2.identifier, true);
}); });
expect(component.text()).toEqual('An error occurred while stopping your live location'); expect(container.textContent).toEqual('An error occurred while stopping your live location');
}); });
it('renders stopping error when beacons have stopping and location errors', () => { it('renders stopping error when beacons have stopping and location errors', () => {
@ -250,8 +243,8 @@ describe('<LeftPanelLiveShareWarning />', () => {
[beacon1.identifier], [beacon1.identifier],
); );
OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error')); OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error'));
const component = getComponent(); const { container } = getComponent();
expect(component.text()).toEqual('An error occurred while stopping your live location'); expect(container.textContent).toEqual('An error occurred while stopping your live location');
}); });
it('goes to room of latest beacon with stopping error when clicked', () => { it('goes to room of latest beacon with stopping error when clicked', () => {
@ -259,12 +252,10 @@ describe('<LeftPanelLiveShareWarning />', () => {
[beacon1.identifier], [beacon1.identifier],
); );
OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error')); OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error'));
const component = getComponent(); const { container } = getComponent();
const dispatchSpy = jest.spyOn(dispatcher, 'dispatch'); const dispatchSpy = jest.spyOn(dispatcher, 'dispatch');
act(() => { fireEvent.click(container.querySelector("[role=button]"));
component.simulate('click');
});
expect(dispatchSpy).toHaveBeenCalledWith({ expect(dispatchSpy).toHaveBeenCalledWith({
action: Action.ViewRoom, action: Action.ViewRoom,

View file

@ -15,9 +15,7 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
// eslint-disable-next-line deprecate/import import { fireEvent, render } from "@testing-library/react";
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';
import ShareLatestLocation from '../../../../src/components/views/beacon/ShareLatestLocation'; import ShareLatestLocation from '../../../../src/components/views/beacon/ShareLatestLocation';
import { copyPlaintext } from '../../../../src/utils/strings'; import { copyPlaintext } from '../../../../src/utils/strings';
@ -34,26 +32,23 @@ describe('<ShareLatestLocation />', () => {
timestamp: 123, timestamp: 123,
}, },
}; };
const getComponent = (props = {}) => const getComponent = (props = {}) => render(<ShareLatestLocation {...defaultProps} {...props} />);
mount(<ShareLatestLocation {...defaultProps} {...props} />);
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks(); jest.clearAllMocks();
}); });
it('renders null when no location', () => { it('renders null when no location', () => {
const component = getComponent({ latestLocationState: undefined }); const { container } = getComponent({ latestLocationState: undefined });
expect(component.html()).toBeNull(); expect(container.innerHTML).toBeFalsy();
}); });
it('renders share buttons when there is a location', async () => { it('renders share buttons when there is a location', async () => {
const component = getComponent(); const { container, asFragment } = getComponent();
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
await act(async () => { fireEvent.click(container.querySelector('.mx_CopyableText_copyButton'));
component.find('.mx_CopyableText_copyButton').at(0).simulate('click'); await flushPromises();
await flushPromises();
});
expect(copyPlaintext).toHaveBeenCalledWith('51,42'); expect(copyPlaintext).toHaveBeenCalledWith('51,42');
}); });

View file

@ -15,18 +15,16 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
// eslint-disable-next-line deprecate/import import { render } from "@testing-library/react";
import { mount } from 'enzyme';
import StyledLiveBeaconIcon from '../../../../src/components/views/beacon/StyledLiveBeaconIcon'; import StyledLiveBeaconIcon from '../../../../src/components/views/beacon/StyledLiveBeaconIcon';
describe('<StyledLiveBeaconIcon />', () => { describe('<StyledLiveBeaconIcon />', () => {
const defaultProps = {}; const defaultProps = {};
const getComponent = (props = {}) => const getComponent = (props = {}) => render(<StyledLiveBeaconIcon {...defaultProps} {...props} />);
mount(<StyledLiveBeaconIcon {...defaultProps} {...props} />);
it('renders', () => { it('renders', () => {
const component = getComponent(); const { asFragment } = getComponent();
expect(component).toBeTruthy(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View file

@ -1,3 +1,68 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<BeaconListItem /> when a beacon is live and has locations renders beacon info 1`] = `"<li class=\\"mx_BeaconListItem\\"><div class=\\"mx_StyledLiveBeaconIcon mx_BeaconListItem_avatarIcon\\"></div><div class=\\"mx_BeaconListItem_info\\"><div class=\\"mx_BeaconStatus mx_BeaconStatus_Active mx_BeaconListItem_status\\"><div class=\\"mx_BeaconStatus_description\\"><span class=\\"mx_BeaconStatus_label\\">Alice's car</span><span class=\\"mx_BeaconStatus_expiryTime\\">Live until 16:04</span></div><div class=\\"mx_BeaconListItem_interactions\\"><div tabindex=\\"0\\"><a data-test-id=\\"open-location-in-osm\\" href=\\"https://www.openstreetmap.org/?mlat=51&amp;mlon=41#map=16/51/41\\" target=\\"_blank\\" rel=\\"noreferrer noopener\\"><div class=\\"mx_ShareLatestLocation_icon\\"></div></a></div><div class=\\"mx_CopyableText mx_ShareLatestLocation_copy\\"><div aria-label=\\"Copy\\" role=\\"button\\" tabindex=\\"0\\" class=\\"mx_AccessibleButton mx_CopyableText_copyButton\\"></div></div></div></div><span class=\\"mx_BeaconListItem_lastUpdated\\">Updated a few seconds ago</span></div></li>"`; exports[`<BeaconListItem /> when a beacon is live and has locations renders beacon info 1`] = `
<DocumentFragment>
<li
class="mx_BeaconListItem"
>
<div
class="mx_StyledLiveBeaconIcon mx_BeaconListItem_avatarIcon"
/>
<div
class="mx_BeaconListItem_info"
>
<div
class="mx_BeaconStatus mx_BeaconStatus_Active mx_BeaconListItem_status"
>
<div
class="mx_BeaconStatus_description"
>
<span
class="mx_BeaconStatus_label"
>
Alice's car
</span>
<span
class="mx_BeaconStatus_expiryTime"
>
Live until 16:04
</span>
</div>
<div
class="mx_BeaconListItem_interactions"
>
<div
tabindex="0"
>
<a
data-testid="open-location-in-osm"
href="https://www.openstreetmap.org/?mlat=51&mlon=41#map=16/51/41"
rel="noreferrer noopener"
target="_blank"
>
<div
class="mx_ShareLatestLocation_icon"
/>
</a>
</div>
<div
class="mx_CopyableText mx_ShareLatestLocation_copy"
>
<div
aria-label="Copy"
class="mx_AccessibleButton mx_CopyableText_copyButton"
role="button"
tabindex="0"
/>
</div>
</div>
</div>
<span
class="mx_BeaconListItem_lastUpdated"
>
Updated a few seconds ago
</span>
</div>
</li>
</DocumentFragment>
`;

View file

@ -75,7 +75,7 @@ exports[`<DialogSidebar /> renders sidebar correctly with beacons 1`] = `
tabindex="0" tabindex="0"
> >
<a <a
data-test-id="open-location-in-osm" data-testid="open-location-in-osm"
href="https://www.openstreetmap.org/?mlat=51&mlon=41#map=16/51/41" href="https://www.openstreetmap.org/?mlat=51&mlon=41#map=16/51/41"
rel="noreferrer noopener" rel="noreferrer noopener"
target="_blank" target="_blank"

View file

@ -1,76 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<LeftPanelLiveShareWarning /> when user has live location monitor renders correctly when minimized 1`] = ` exports[`<LeftPanelLiveShareWarning /> when user has live location monitor renders correctly when minimized 1`] = `
<LeftPanelLiveShareWarning <DocumentFragment>
isMinimized={true} <div
> class="mx_AccessibleButton mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__minimized"
<AccessibleButton
className="mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__minimized"
element="div"
onClick={[Function]}
role="button" role="button"
tabIndex={0} tabindex="0"
title="You are sharing your live location" title="You are sharing your live location"
> >
<div <div
className="mx_AccessibleButton mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__minimized" height="10"
onClick={[Function]} />
onKeyDown={[Function]} </div>
onKeyUp={[Function]} </DocumentFragment>
role="button"
tabIndex={0}
title="You are sharing your live location"
>
<div
height={10}
/>
</div>
</AccessibleButton>
</LeftPanelLiveShareWarning>
`; `;
exports[`<LeftPanelLiveShareWarning /> when user has live location monitor renders correctly when not minimized 1`] = ` exports[`<LeftPanelLiveShareWarning /> when user has live location monitor renders correctly when not minimized 1`] = `
<LeftPanelLiveShareWarning> <DocumentFragment>
<AccessibleButton <div
className="mx_LeftPanelLiveShareWarning" class="mx_AccessibleButton mx_LeftPanelLiveShareWarning"
element="div"
onClick={[Function]}
role="button" role="button"
tabIndex={0} tabindex="0"
> >
<div You are sharing your live location
className="mx_AccessibleButton mx_LeftPanelLiveShareWarning" </div>
onClick={[Function]} </DocumentFragment>
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
tabIndex={0}
>
You are sharing your live location
</div>
</AccessibleButton>
</LeftPanelLiveShareWarning>
`; `;
exports[`<LeftPanelLiveShareWarning /> when user has live location monitor renders location publish error 1`] = ` exports[`<LeftPanelLiveShareWarning /> when user has live location monitor renders location publish error 1`] = `
<LeftPanelLiveShareWarning> <DocumentFragment>
<AccessibleButton <div
className="mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__error" class="mx_AccessibleButton mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__error"
element="div"
onClick={[Function]}
role="button" role="button"
tabIndex={0} tabindex="0"
> >
<div An error occurred whilst sharing your live location
className="mx_AccessibleButton mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__error" </div>
onClick={[Function]} </DocumentFragment>
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
tabIndex={0}
>
An error occurred whilst sharing your live location
</div>
</AccessibleButton>
</LeftPanelLiveShareWarning>
`; `;

View file

@ -1,79 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<ShareLatestLocation /> renders share buttons when there is a location 1`] = ` exports[`<ShareLatestLocation /> renders share buttons when there is a location 1`] = `
<ShareLatestLocation <DocumentFragment>
latestLocationState={ <div
Object { tabindex="0"
"timestamp": 123, >
"uri": "geo:51,42;u=35", <a
} data-testid="open-location-in-osm"
} href="https://www.openstreetmap.org/?mlat=51&mlon=42#map=16/51/42"
> rel="noreferrer noopener"
<TooltipTarget target="_blank"
label="Open in OpenStreetMap" >
<div
class="mx_ShareLatestLocation_icon"
/>
</a>
</div>
<div
class="mx_CopyableText mx_ShareLatestLocation_copy"
> >
<div <div
onBlur={[Function]} aria-label="Copy"
onFocus={[Function]} class="mx_AccessibleButton mx_CopyableText_copyButton"
onMouseLeave={[Function]} role="button"
onMouseMove={[Function]} tabindex="0"
onMouseOver={[Function]} />
tabIndex={0} </div>
> </DocumentFragment>
<a
data-test-id="open-location-in-osm"
href="https://www.openstreetmap.org/?mlat=51&mlon=42#map=16/51/42"
rel="noreferrer noopener"
target="_blank"
>
<div
className="mx_ShareLatestLocation_icon"
/>
</a>
</div>
</TooltipTarget>
<CopyableText
border={false}
className="mx_ShareLatestLocation_copy"
getTextToCopy={[Function]}
>
<div
className="mx_CopyableText mx_ShareLatestLocation_copy"
>
<AccessibleTooltipButton
className="mx_CopyableText_copyButton"
onClick={[Function]}
onHideTooltip={[Function]}
title="Copy"
>
<AccessibleButton
aria-label="Copy"
className="mx_CopyableText_copyButton"
element="div"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseLeave={[Function]}
onMouseOver={[Function]}
role="button"
tabIndex={0}
>
<div
aria-label="Copy"
className="mx_AccessibleButton mx_CopyableText_copyButton"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
onMouseLeave={[Function]}
onMouseOver={[Function]}
role="button"
tabIndex={0}
/>
</AccessibleButton>
</AccessibleTooltipButton>
</div>
</CopyableText>
</ShareLatestLocation>
`; `;

View file

@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<StyledLiveBeaconIcon /> renders 1`] = `
<DocumentFragment>
<div
class="mx_StyledLiveBeaconIcon"
/>
</DocumentFragment>
`;

View file

@ -15,9 +15,7 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
// eslint-disable-next-line deprecate/import import { fireEvent, render } from "@testing-library/react";
import { mount } from 'enzyme';
import { act } from "react-dom/test-utils";
import StyledRadioGroup from "../../../../src/components/views/elements/StyledRadioGroup"; import StyledRadioGroup from "../../../../src/components/views/elements/StyledRadioGroup";
@ -44,16 +42,16 @@ describe('<StyledRadioGroup />', () => {
definitions: defaultDefinitions, definitions: defaultDefinitions,
onChange: jest.fn(), onChange: jest.fn(),
}; };
const getComponent = (props = {}) => mount(<StyledRadioGroup {...defaultProps} {...props} />); const getComponent = (props = {}) => render(<StyledRadioGroup {...defaultProps} {...props} />);
const getInputByValue = (component, value) => component.find(`input[value="${value}"]`); const getInputByValue = (component, value) => component.container.querySelector(`input[value="${value}"]`);
const getCheckedInput = component => component.find('input[checked=true]'); const getCheckedInput = component => component.container.querySelector('input[checked]');
it('renders radios correctly when no value is provided', () => { it('renders radios correctly when no value is provided', () => {
const component = getComponent(); const component = getComponent();
expect(component).toMatchSnapshot(); expect(component.asFragment()).toMatchSnapshot();
expect(getCheckedInput(component).length).toBeFalsy(); expect(getCheckedInput(component)).toBeFalsy();
}); });
it('selects correct button when value is provided', () => { it('selects correct button when value is provided', () => {
@ -61,7 +59,7 @@ describe('<StyledRadioGroup />', () => {
value: optionC.value, value: optionC.value,
}); });
expect(getCheckedInput(component).at(0).props().value).toEqual(optionC.value); expect(getCheckedInput(component).value).toEqual(optionC.value);
}); });
it('selects correct buttons when definitions have checked prop', () => { it('selects correct buttons when definitions have checked prop', () => {
@ -74,10 +72,10 @@ describe('<StyledRadioGroup />', () => {
value: optionC.value, definitions, value: optionC.value, definitions,
}); });
expect(getInputByValue(component, optionA.value).props().checked).toBeTruthy(); expect(getInputByValue(component, optionA.value)).toBeChecked();
expect(getInputByValue(component, optionB.value).props().checked).toBeFalsy(); expect(getInputByValue(component, optionB.value)).not.toBeChecked();
// optionC.checked = false overrides value matching // optionC.checked = false overrides value matching
expect(getInputByValue(component, optionC.value).props().checked).toBeFalsy(); expect(getInputByValue(component, optionC.value)).not.toBeChecked();
}); });
it('disables individual buttons based on definition.disabled', () => { it('disables individual buttons based on definition.disabled', () => {
@ -87,16 +85,16 @@ describe('<StyledRadioGroup />', () => {
{ ...optionC, disabled: true }, { ...optionC, disabled: true },
]; ];
const component = getComponent({ definitions }); const component = getComponent({ definitions });
expect(getInputByValue(component, optionA.value).props().disabled).toBeFalsy(); expect(getInputByValue(component, optionA.value)).not.toBeDisabled();
expect(getInputByValue(component, optionB.value).props().disabled).toBeTruthy(); expect(getInputByValue(component, optionB.value)).toBeDisabled();
expect(getInputByValue(component, optionC.value).props().disabled).toBeTruthy(); expect(getInputByValue(component, optionC.value)).toBeDisabled();
}); });
it('disables all buttons with disabled prop', () => { it('disables all buttons with disabled prop', () => {
const component = getComponent({ disabled: true }); const component = getComponent({ disabled: true });
expect(getInputByValue(component, optionA.value).props().disabled).toBeTruthy(); expect(getInputByValue(component, optionA.value)).toBeDisabled();
expect(getInputByValue(component, optionB.value).props().disabled).toBeTruthy(); expect(getInputByValue(component, optionB.value)).toBeDisabled();
expect(getInputByValue(component, optionC.value).props().disabled).toBeTruthy(); expect(getInputByValue(component, optionC.value)).toBeDisabled();
}); });
it('calls onChange on click', () => { it('calls onChange on click', () => {
@ -106,9 +104,7 @@ describe('<StyledRadioGroup />', () => {
onChange, onChange,
}); });
act(() => { fireEvent.click(getInputByValue(component, optionB.value));
getInputByValue(component, optionB.value).simulate('change');
});
expect(onChange).toHaveBeenCalledWith(optionB.value); expect(onChange).toHaveBeenCalledWith(optionB.value);
}); });

View file

@ -1,152 +1,83 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<StyledRadioGroup /> renders radios correctly when no value is provided 1`] = ` exports[`<StyledRadioGroup /> renders radios correctly when no value is provided 1`] = `
<StyledRadioGroup <DocumentFragment>
className="test-class" <label
definitions={ class="mx_StyledRadioButton test-class a-class mx_StyledRadioButton_enabled"
Array [
Object {
"className": "a-class",
"description": "anteater description",
"label": <span>
Anteater label
</span>,
"value": "Anteater",
},
Object {
"label": <span>
Badger label
</span>,
"value": "Badger",
},
Object {
"description": <span>
Canary description
</span>,
"label": <span>
Canary label
</span>,
"value": "Canary",
},
]
}
name="test"
onChange={[MockFunction]}
>
<StyledRadioButton
aria-describedby="test-Anteater-description"
checked={false}
childrenInLabel={true}
className="test-class a-class"
id="test-Anteater"
name="test"
onChange={[Function]}
value="Anteater"
> >
<label <input
className="mx_StyledRadioButton test-class a-class mx_StyledRadioButton_enabled" aria-describedby="test-Anteater-description"
id="test-Anteater"
name="test"
type="radio"
value="Anteater"
/>
<div>
<div />
</div>
<div
class="mx_StyledRadioButton_content"
> >
<input <span>
aria-describedby="test-Anteater-description" Anteater label
checked={false} </span>
id="test-Anteater" </div>
name="test" <div
onChange={[Function]} class="mx_StyledRadioButton_spacer"
type="radio" />
value="Anteater" </label>
/>
<div>
<div />
</div>
<div
className="mx_StyledRadioButton_content"
>
<span>
Anteater label
</span>
</div>
<div
className="mx_StyledRadioButton_spacer"
/>
</label>
</StyledRadioButton>
<span <span
id="test-Anteater-description" id="test-Anteater-description"
> >
anteater description anteater description
</span> </span>
<StyledRadioButton <label
checked={false} class="mx_StyledRadioButton test-class mx_StyledRadioButton_enabled"
childrenInLabel={true}
className="test-class"
id="test-Badger"
name="test"
onChange={[Function]}
value="Badger"
> >
<label <input
className="mx_StyledRadioButton test-class mx_StyledRadioButton_enabled" id="test-Badger"
name="test"
type="radio"
value="Badger"
/>
<div>
<div />
</div>
<div
class="mx_StyledRadioButton_content"
> >
<input <span>
checked={false} Badger label
id="test-Badger" </span>
name="test" </div>
onChange={[Function]} <div
type="radio" class="mx_StyledRadioButton_spacer"
value="Badger" />
/> </label>
<div> <label
<div /> class="mx_StyledRadioButton test-class mx_StyledRadioButton_enabled"
</div>
<div
className="mx_StyledRadioButton_content"
>
<span>
Badger label
</span>
</div>
<div
className="mx_StyledRadioButton_spacer"
/>
</label>
</StyledRadioButton>
<StyledRadioButton
aria-describedby="test-Canary-description"
checked={false}
childrenInLabel={true}
className="test-class"
id="test-Canary"
name="test"
onChange={[Function]}
value="Canary"
> >
<label <input
className="mx_StyledRadioButton test-class mx_StyledRadioButton_enabled" aria-describedby="test-Canary-description"
id="test-Canary"
name="test"
type="radio"
value="Canary"
/>
<div>
<div />
</div>
<div
class="mx_StyledRadioButton_content"
> >
<input <span>
aria-describedby="test-Canary-description" Canary label
checked={false} </span>
id="test-Canary" </div>
name="test" <div
onChange={[Function]} class="mx_StyledRadioButton_spacer"
type="radio" />
value="Canary" </label>
/>
<div>
<div />
</div>
<div
className="mx_StyledRadioButton_content"
>
<span>
Canary label
</span>
</div>
<div
className="mx_StyledRadioButton_spacer"
/>
</label>
</StyledRadioButton>
<span <span
id="test-Canary-description" id="test-Canary-description"
> >
@ -154,5 +85,5 @@ exports[`<StyledRadioGroup /> renders radios correctly when no value is provided
Canary description Canary description
</span> </span>
</span> </span>
</StyledRadioGroup> </DocumentFragment>
`; `;

View file

@ -15,8 +15,7 @@ limitations under the License.
*/ */
import React from "react"; import React from "react";
// eslint-disable-next-line deprecate/import import { render } from "@testing-library/react";
import { mount } from "enzyme";
import { TextInputField } from "@matrix-org/react-sdk-module-api/lib/components/TextInputField"; import { TextInputField } from "@matrix-org/react-sdk-module-api/lib/components/TextInputField";
import { Spinner as ModuleSpinner } from "@matrix-org/react-sdk-module-api/lib/components/Spinner"; import { Spinner as ModuleSpinner } from "@matrix-org/react-sdk-module-api/lib/components/Spinner";
@ -31,12 +30,12 @@ describe("Module Components", () => {
// ModuleRunner import to do its job (as per documentation in ModuleComponents). // ModuleRunner import to do its job (as per documentation in ModuleComponents).
it("should override the factory for a TextInputField", () => { it("should override the factory for a TextInputField", () => {
const component = mount(<TextInputField label="My Label" value="My Value" onChange={() => {}} />); const { asFragment } = render(<TextInputField label="My Label" value="My Value" onChange={() => {}} />);
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
it("should override the factory for a ModuleSpinner", () => { it("should override the factory for a ModuleSpinner", () => {
const component = mount(<ModuleSpinner />); const { asFragment } = render(<ModuleSpinner />);
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View file

@ -1,68 +1,39 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Module Components should override the factory for a ModuleSpinner 1`] = ` exports[`Module Components should override the factory for a ModuleSpinner 1`] = `
<Spinner> <DocumentFragment>
<Spinner <div
h={32} class="mx_Spinner"
w={32}
> >
<div <div
className="mx_Spinner" aria-label="Loading..."
> class="mx_Spinner_icon"
<div data-testid="spinner"
aria-label="Loading..." role="progressbar"
className="mx_Spinner_icon" style="width: 32px; height: 32px;"
data-testid="spinner" />
role="progressbar" </div>
style={ </DocumentFragment>
Object {
"height": 32,
"width": 32,
}
}
/>
</div>
</Spinner>
</Spinner>
`; `;
exports[`Module Components should override the factory for a TextInputField 1`] = ` exports[`Module Components should override the factory for a TextInputField 1`] = `
<TextInputField <DocumentFragment>
label="My Label" <div
onChange={[Function]} class="mx_Field mx_Field_input"
value="My Value"
>
<Field
autoComplete="off"
element="input"
label="My Label"
onChange={[Function]}
type="text"
validateOnBlur={true}
validateOnChange={true}
validateOnFocus={true}
value="My Value"
> >
<div <input
className="mx_Field mx_Field_input" autocomplete="off"
id="mx_Field_1"
label="My Label"
placeholder="My Label"
type="text"
value="My Value"
/>
<label
for="mx_Field_1"
> >
<input My Label
autoComplete="off" </label>
id="mx_Field_1" </div>
label="My Label" </DocumentFragment>
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
placeholder="My Label"
type="text"
value="My Value"
/>
<label
htmlFor="mx_Field_1"
>
My Label
</label>
</div>
</Field>
</TextInputField>
`; `;