Merge branch 'develop' into travis/remove-skinning

This commit is contained in:
Travis Ralston 2022-03-31 19:25:43 -06:00
commit 97efdf7094
54 changed files with 1559 additions and 431 deletions

View file

@ -17,16 +17,22 @@ limitations under the License.
import React from 'react';
import { mocked } from 'jest-mock';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';
import { Beacon } from 'matrix-js-sdk/src/matrix';
import LeftPanelLiveShareWarning from '../../../../src/components/views/beacon/LeftPanelLiveShareWarning';
import { OwnBeaconStore, OwnBeaconStoreEvent } from '../../../../src/stores/OwnBeaconStore';
import { flushPromises } from '../../../test-utils';
import { flushPromises, makeBeaconInfoEvent } from '../../../test-utils';
import dispatcher from '../../../../src/dispatcher/dispatcher';
import { Action } from '../../../../src/dispatcher/actions';
jest.mock('../../../../src/stores/OwnBeaconStore', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const EventEmitter = require("events");
class MockOwnBeaconStore extends EventEmitter {
public hasLiveBeacons = jest.fn().mockReturnValue(false);
public getLiveBeaconIdsWithWireError = jest.fn().mockReturnValue([]);
public getBeaconById = jest.fn();
public getLiveBeaconIds = jest.fn().mockReturnValue([]);
}
return {
// @ts-ignore
@ -43,32 +49,136 @@ describe('<LeftPanelLiveShareWarning />', () => {
const getComponent = (props = {}) =>
mount(<LeftPanelLiveShareWarning {...defaultProps} {...props} />);
const roomId1 = '!room1:server';
const roomId2 = '!room2:server';
const aliceId = '@alive:server';
const now = 1647270879403;
const HOUR_MS = 3600000;
beforeEach(() => {
jest.spyOn(global.Date, 'now').mockReturnValue(now);
jest.spyOn(dispatcher, 'dispatch').mockClear().mockImplementation(() => { });
});
afterAll(() => {
jest.spyOn(global.Date, 'now').mockRestore();
jest.restoreAllMocks();
});
// 12h old, 12h left
const beacon1 = new Beacon(makeBeaconInfoEvent(aliceId,
roomId1,
{ timeout: HOUR_MS * 24, timestamp: now - 12 * HOUR_MS },
'$1',
));
// 10h left
const beacon2 = new Beacon(makeBeaconInfoEvent(aliceId,
roomId2,
{ timeout: HOUR_MS * 10, timestamp: now },
'$2',
));
it('renders nothing when user has no live beacons', () => {
const component = getComponent();
expect(component.html()).toBe(null);
});
describe('when user has live location monitor', () => {
beforeAll(() => {
mocked(OwnBeaconStore.instance).getBeaconById.mockImplementation(beaconId => {
if (beaconId === beacon1.identifier) {
return beacon1;
}
return beacon2;
});
});
beforeEach(() => {
mocked(OwnBeaconStore.instance).isMonitoringLiveLocation = true;
mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithWireError.mockReturnValue([]);
mocked(OwnBeaconStore.instance).getLiveBeaconIds.mockReturnValue([beacon2.identifier, beacon1.identifier]);
});
it('renders correctly when not minimized', () => {
const component = getComponent();
expect(component).toMatchSnapshot();
});
it('goes to room of latest beacon when clicked', () => {
const component = getComponent();
const dispatchSpy = jest.spyOn(dispatcher, 'dispatch');
act(() => {
component.simulate('click');
});
expect(dispatchSpy).toHaveBeenCalledWith({
action: Action.ViewRoom,
metricsTrigger: undefined,
// latest beacon's room
room_id: roomId2,
});
});
it('renders correctly when minimized', () => {
const component = getComponent({ isMinimized: true });
expect(component).toMatchSnapshot();
});
it('renders wire error', () => {
mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithWireError.mockReturnValue([beacon1.identifier]);
const component = getComponent();
expect(component).toMatchSnapshot();
});
it('goes to room of latest beacon with wire error when clicked', () => {
mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithWireError.mockReturnValue([beacon1.identifier]);
const component = getComponent();
const dispatchSpy = jest.spyOn(dispatcher, 'dispatch');
act(() => {
component.simulate('click');
});
expect(dispatchSpy).toHaveBeenCalledWith({
action: Action.ViewRoom,
metricsTrigger: undefined,
// error beacon's room
room_id: roomId1,
});
});
it('goes back to default style when wire errors are cleared', () => {
mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithWireError.mockReturnValue([beacon1.identifier]);
const component = getComponent();
// error mode
expect(component.find('.mx_LeftPanelLiveShareWarning').at(0).text()).toEqual(
'An error occured whilst sharing your live location',
);
act(() => {
mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithWireError.mockReturnValue([]);
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.WireError, 'abc');
});
component.setProps({});
// default mode
expect(component.find('.mx_LeftPanelLiveShareWarning').at(0).text()).toEqual(
'You are sharing your live location',
);
});
it('removes itself when user stops having live beacons', async () => {
const component = getComponent({ isMinimized: true });
// started out rendered
expect(component.html()).toBeTruthy();
mocked(OwnBeaconStore.instance).isMonitoringLiveLocation = false;
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.MonitoringLivePosition);
act(() => {
mocked(OwnBeaconStore.instance).isMonitoringLiveLocation = false;
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.MonitoringLivePosition);
});
await flushPromises();
component.setProps({});

View file

@ -25,6 +25,7 @@ import { OwnBeaconStore, OwnBeaconStoreEvent } from '../../../../src/stores/OwnB
import {
advanceDateAndTime,
findByTestId,
flushPromisesWithFakeTimers,
getMockClientWithEventEmitter,
makeBeaconInfoEvent,
mockGeolocation,
@ -95,10 +96,11 @@ describe('<RoomLiveShareWarning />', () => {
beforeEach(() => {
mockGeolocation();
jest.spyOn(global.Date, 'now').mockReturnValue(now);
mockClient.unstable_setLiveBeacon.mockClear();
mockClient.unstable_setLiveBeacon.mockReset().mockResolvedValue({ event_id: '1' });
});
afterEach(async () => {
jest.spyOn(OwnBeaconStore.instance, 'hasWireErrors').mockRestore();
await resetAsyncStoreWithClient(OwnBeaconStore.instance);
});
@ -236,13 +238,37 @@ describe('<RoomLiveShareWarning />', () => {
const component = getComponent({ roomId: room2Id });
act(() => {
findByTestId(component, 'room-live-share-stop-sharing').at(0).simulate('click');
findByTestId(component, 'room-live-share-primary-button').at(0).simulate('click');
component.setProps({});
});
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalledTimes(2);
expect(component.find('Spinner').length).toBeTruthy();
expect(findByTestId(component, 'room-live-share-stop-sharing').at(0).props().disabled).toBeTruthy();
expect(findByTestId(component, 'room-live-share-primary-button').at(0).props().disabled).toBeTruthy();
});
it('displays error when stop sharing fails', async () => {
const component = getComponent({ roomId: room1Id });
// fail first time
mockClient.unstable_setLiveBeacon
.mockRejectedValueOnce(new Error('oups'))
.mockResolvedValue(({ event_id: '1' }));
await act(async () => {
findByTestId(component, 'room-live-share-primary-button').at(0).simulate('click');
await flushPromisesWithFakeTimers();
});
component.setProps({});
expect(component.html()).toMatchSnapshot();
act(() => {
findByTestId(component, 'room-live-share-primary-button').at(0).simulate('click');
component.setProps({});
});
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalledTimes(2);
});
it('displays again with correct state after stopping a beacon', () => {
@ -251,7 +277,7 @@ describe('<RoomLiveShareWarning />', () => {
// stop the beacon
act(() => {
findByTestId(component, 'room-live-share-stop-sharing').at(0).simulate('click');
findByTestId(component, 'room-live-share-primary-button').at(0).simulate('click');
});
// time travel until room1Beacon1 is expired
act(() => {
@ -267,9 +293,83 @@ describe('<RoomLiveShareWarning />', () => {
});
// button not disabled and expiry time shown
expect(findByTestId(component, 'room-live-share-stop-sharing').at(0).props().disabled).toBeFalsy();
expect(findByTestId(component, 'room-live-share-primary-button').at(0).props().disabled).toBeFalsy();
expect(findByTestId(component, 'room-live-share-expiry').text()).toEqual('1h left');
});
});
describe('with wire errors', () => {
it('displays wire error when mounted with wire errors', async () => {
const hasWireErrorsSpy = jest.spyOn(OwnBeaconStore.instance, 'hasWireErrors').mockReturnValue(true);
const component = getComponent({ roomId: room2Id });
expect(component).toMatchSnapshot();
expect(hasWireErrorsSpy).toHaveBeenCalledWith(room2Id);
});
it('displays wire error when wireError event is emitted and beacons have errors', async () => {
const hasWireErrorsSpy = jest.spyOn(OwnBeaconStore.instance, 'hasWireErrors').mockReturnValue(false);
const component = getComponent({ roomId: room2Id });
// update mock and emit event
act(() => {
hasWireErrorsSpy.mockReturnValue(true);
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.WireError, room2Beacon1.getType());
});
component.setProps({});
// renders wire error ui
expect(component.find('.mx_RoomLiveShareWarning_label').text()).toEqual(
'An error occured whilst sharing your live location, please try again',
);
expect(findByTestId(component, 'room-live-share-wire-error-close-button').length).toBeTruthy();
});
it('stops displaying wire error when errors are cleared', async () => {
const hasWireErrorsSpy = jest.spyOn(OwnBeaconStore.instance, 'hasWireErrors').mockReturnValue(true);
const component = getComponent({ roomId: room2Id });
// update mock and emit event
act(() => {
hasWireErrorsSpy.mockReturnValue(false);
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.WireError, room2Beacon1.getType());
});
component.setProps({});
// renders error-free ui
expect(component.find('.mx_RoomLiveShareWarning_label').text()).toEqual(
'You are sharing your live location',
);
expect(findByTestId(component, 'room-live-share-wire-error-close-button').length).toBeFalsy();
});
it('clicking retry button resets wire errors', async () => {
jest.spyOn(OwnBeaconStore.instance, 'hasWireErrors').mockReturnValue(true);
const resetErrorSpy = jest.spyOn(OwnBeaconStore.instance, 'resetWireError');
const component = getComponent({ roomId: room2Id });
act(() => {
findByTestId(component, 'room-live-share-primary-button').at(0).simulate('click');
});
expect(resetErrorSpy).toHaveBeenCalledWith(room2Beacon1.getType());
expect(resetErrorSpy).toHaveBeenCalledWith(room2Beacon2.getType());
});
it('clicking close button stops beacons', async () => {
jest.spyOn(OwnBeaconStore.instance, 'hasWireErrors').mockReturnValue(true);
const stopBeaconSpy = jest.spyOn(OwnBeaconStore.instance, 'stopBeacon');
const component = getComponent({ roomId: room2Id });
act(() => {
findByTestId(component, 'room-live-share-wire-error-close-button').at(0).simulate('click');
});
expect(stopBeaconSpy).toHaveBeenCalledWith(room2Beacon1.getType());
expect(stopBeaconSpy).toHaveBeenCalledWith(room2Beacon2.getType());
});
});
});
});

View file

@ -4,23 +4,73 @@ exports[`<LeftPanelLiveShareWarning /> when user has live location monitor rende
<LeftPanelLiveShareWarning
isMinimized={true}
>
<div
<AccessibleButton
className="mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__minimized"
element="div"
onClick={[Function]}
role="button"
tabIndex={0}
title="You are sharing your live location"
>
<div
height={10}
/>
</div>
className="mx_AccessibleButton mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__minimized"
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
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`] = `
<LeftPanelLiveShareWarning>
<div
<AccessibleButton
className="mx_LeftPanelLiveShareWarning"
element="div"
onClick={[Function]}
role="button"
tabIndex={0}
>
You are sharing your live location
</div>
<div
className="mx_AccessibleButton mx_LeftPanelLiveShareWarning"
onClick={[Function]}
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 wire error 1`] = `
<LeftPanelLiveShareWarning>
<AccessibleButton
className="mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__error"
element="div"
onClick={[Function]}
role="button"
tabIndex={0}
>
<div
className="mx_AccessibleButton mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__error"
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
tabIndex={0}
>
An error occured whilst sharing your live location
</div>
</AccessibleButton>
</LeftPanelLiveShareWarning>
`;

View file

@ -1,5 +1,86 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<RoomLiveShareWarning /> when user has live beacons and geolocation is available renders correctly with one live beacon in room 1`] = `"<div class=\\"mx_RoomLiveShareWarning\\"><div class=\\"mx_StyledLiveBeaconIcon mx_RoomLiveShareWarning_icon\\"></div><span class=\\"mx_RoomLiveShareWarning_label\\">You are sharing your live location</span><span data-test-id=\\"room-live-share-expiry\\" class=\\"mx_RoomLiveShareWarning_expiry\\">1h left</span><button data-test-id=\\"room-live-share-stop-sharing\\" role=\\"button\\" tabindex=\\"0\\" class=\\"mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger\\">Stop sharing</button></div>"`;
exports[`<RoomLiveShareWarning /> when user has live beacons and geolocation is available renders correctly with one live beacon in room 1`] = `"<div class=\\"mx_RoomLiveShareWarning\\"><div class=\\"mx_StyledLiveBeaconIcon mx_RoomLiveShareWarning_icon\\"></div><span class=\\"mx_RoomLiveShareWarning_label\\">You are sharing your live location</span><span data-test-id=\\"room-live-share-expiry\\" class=\\"mx_RoomLiveShareWarning_expiry\\">1h left</span><button data-test-id=\\"room-live-share-primary-button\\" role=\\"button\\" tabindex=\\"0\\" class=\\"mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger\\">Stop sharing</button></div>"`;
exports[`<RoomLiveShareWarning /> when user has live beacons and geolocation is available renders correctly with two live beacons in room 1`] = `"<div class=\\"mx_RoomLiveShareWarning\\"><div class=\\"mx_StyledLiveBeaconIcon mx_RoomLiveShareWarning_icon\\"></div><span class=\\"mx_RoomLiveShareWarning_label\\">You are sharing your live location</span><span data-test-id=\\"room-live-share-expiry\\" class=\\"mx_RoomLiveShareWarning_expiry\\">12h left</span><button data-test-id=\\"room-live-share-stop-sharing\\" role=\\"button\\" tabindex=\\"0\\" class=\\"mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger\\">Stop sharing</button></div>"`;
exports[`<RoomLiveShareWarning /> when user has live beacons and geolocation is available renders correctly with two live beacons in room 1`] = `"<div class=\\"mx_RoomLiveShareWarning\\"><div class=\\"mx_StyledLiveBeaconIcon mx_RoomLiveShareWarning_icon\\"></div><span class=\\"mx_RoomLiveShareWarning_label\\">You are sharing your live location</span><span data-test-id=\\"room-live-share-expiry\\" class=\\"mx_RoomLiveShareWarning_expiry\\">12h left</span><button data-test-id=\\"room-live-share-primary-button\\" role=\\"button\\" tabindex=\\"0\\" class=\\"mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger\\">Stop sharing</button></div>"`;
exports[`<RoomLiveShareWarning /> when user has live beacons and geolocation is available stopping beacons displays error when stop sharing fails 1`] = `"<div class=\\"mx_RoomLiveShareWarning\\"><div class=\\"mx_StyledLiveBeaconIcon mx_RoomLiveShareWarning_icon mx_StyledLiveBeaconIcon_error\\"></div><span class=\\"mx_RoomLiveShareWarning_label\\">An error occurred while stopping your live location, please try again</span><button data-test-id=\\"room-live-share-primary-button\\" role=\\"button\\" tabindex=\\"0\\" class=\\"mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger\\">Retry</button></div>"`;
exports[`<RoomLiveShareWarning /> when user has live beacons and geolocation is available with wire errors displays wire error when mounted with wire errors 1`] = `
<RoomLiveShareWarning
roomId="$room2:server.org"
>
<RoomLiveShareWarningInner
liveBeaconIds={
Array [
"org.matrix.msc3489.beacon_info.@alice:server.org.3",
"org.matrix.msc3489.beacon_info.@alice:server.org.4",
]
}
roomId="$room2:server.org"
>
<div
className="mx_RoomLiveShareWarning"
>
<StyledLiveBeaconIcon
className="mx_RoomLiveShareWarning_icon"
withError={true}
>
<div
className="mx_StyledLiveBeaconIcon mx_RoomLiveShareWarning_icon mx_StyledLiveBeaconIcon_error"
/>
</StyledLiveBeaconIcon>
<span
className="mx_RoomLiveShareWarning_label"
>
An error occured whilst sharing your live location, please try again
</span>
<AccessibleButton
data-test-id="room-live-share-primary-button"
disabled={false}
element="button"
kind="danger"
onClick={[Function]}
role="button"
tabIndex={0}
>
<button
className="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger"
data-test-id="room-live-share-primary-button"
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
tabIndex={0}
>
Retry
</button>
</AccessibleButton>
<AccessibleButton
className="mx_RoomLiveShareWarning_closeButton"
data-test-id="room-live-share-wire-error-close-button"
element="button"
onClick={[Function]}
role="button"
tabIndex={0}
title="Stop sharing and close"
>
<button
className="mx_AccessibleButton mx_RoomLiveShareWarning_closeButton"
data-test-id="room-live-share-wire-error-close-button"
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
tabIndex={0}
title="Stop sharing and close"
>
<div
className="mx_RoomLiveShareWarning_closeButtonIcon"
/>
</button>
</AccessibleButton>
</div>
</RoomLiveShareWarningInner>
</RoomLiveShareWarning>
`;