mirror of https://github.com/vector-im/riot-web
Live location sharing - update beacon_info implementation to latest MSC (#8256)
* update calls to set and createLiveBeacon Signed-off-by: Kerry Archibald <kerrya@element.io> * fix stop beacon Signed-off-by: Kerry Archibald <kerrya@element.io> * remove variable event type from beacon utils Signed-off-by: Kerry Archibald <kerrya@element.io> * use beacon identifier Signed-off-by: Kerry Archibald <kerrya@element.io> * fix RoomLiveShareWarning tests Signed-off-by: Kerry Archibald <kerrya@element.io> * add case for beacon update Signed-off-by: Kerry Archibald <kerrya@element.io> * lint Signed-off-by: Kerry Archibald <kerrya@element.io> * more lint Signed-off-by: Kerry Archibald <kerrya@element.io>pull/21833/head
parent
610225aef2
commit
03d0969ae3
|
@ -16,7 +16,12 @@ limitations under the License.
|
||||||
|
|
||||||
import React, { useCallback, useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Room, Beacon } from 'matrix-js-sdk/src/matrix';
|
import {
|
||||||
|
Room,
|
||||||
|
Beacon,
|
||||||
|
BeaconEvent,
|
||||||
|
BeaconIdentifier,
|
||||||
|
} from 'matrix-js-sdk/src/matrix';
|
||||||
|
|
||||||
import { formatDuration } from '../../../DateUtils';
|
import { formatDuration } from '../../../DateUtils';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
@ -45,16 +50,22 @@ const getUpdateInterval = (ms: number) => {
|
||||||
return 1000;
|
return 1000;
|
||||||
};
|
};
|
||||||
const useMsRemaining = (beacon: Beacon): number => {
|
const useMsRemaining = (beacon: Beacon): number => {
|
||||||
const [msRemaining, setMsRemaining] = useState(() => getBeaconMsUntilExpiry(beacon));
|
const beaconInfo = useEventEmitterState(
|
||||||
|
beacon,
|
||||||
|
BeaconEvent.Update,
|
||||||
|
() => beacon.beaconInfo,
|
||||||
|
);
|
||||||
|
|
||||||
|
const [msRemaining, setMsRemaining] = useState(() => getBeaconMsUntilExpiry(beaconInfo));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMsRemaining(getBeaconMsUntilExpiry(beacon));
|
setMsRemaining(getBeaconMsUntilExpiry(beaconInfo));
|
||||||
}, [beacon]);
|
}, [beaconInfo]);
|
||||||
|
|
||||||
const updateMsRemaining = useCallback(() => {
|
const updateMsRemaining = useCallback(() => {
|
||||||
const ms = getBeaconMsUntilExpiry(beacon);
|
const ms = getBeaconMsUntilExpiry(beaconInfo);
|
||||||
setMsRemaining(ms);
|
setMsRemaining(ms);
|
||||||
}, [beacon]);
|
}, [beaconInfo]);
|
||||||
|
|
||||||
useInterval(updateMsRemaining, getUpdateInterval(msRemaining));
|
useInterval(updateMsRemaining, getUpdateInterval(msRemaining));
|
||||||
|
|
||||||
|
@ -74,7 +85,7 @@ type LiveBeaconsState = {
|
||||||
hasStopSharingError?: boolean;
|
hasStopSharingError?: boolean;
|
||||||
hasWireError?: boolean;
|
hasWireError?: boolean;
|
||||||
};
|
};
|
||||||
const useLiveBeacons = (liveBeaconIds: string[], roomId: string): LiveBeaconsState => {
|
const useLiveBeacons = (liveBeaconIds: BeaconIdentifier[], roomId: string): LiveBeaconsState => {
|
||||||
const [stoppingInProgress, setStoppingInProgress] = useState(false);
|
const [stoppingInProgress, setStoppingInProgress] = useState(false);
|
||||||
const [error, setError] = useState<Error>();
|
const [error, setError] = useState<Error>();
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,7 @@ export const shareLiveLocation = (
|
||||||
description,
|
description,
|
||||||
LocationAssetType.Self,
|
LocationAssetType.Self,
|
||||||
),
|
),
|
||||||
// use timestamp as unique suffix in interim
|
);
|
||||||
`${Date.now()}`);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleShareError(error, openMenu, LocationShareType.Live);
|
handleShareError(error, openMenu, LocationShareType.Live);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
import { debounce } from "lodash";
|
import { debounce } from "lodash";
|
||||||
import {
|
import {
|
||||||
Beacon,
|
Beacon,
|
||||||
|
BeaconIdentifier,
|
||||||
BeaconEvent,
|
BeaconEvent,
|
||||||
MatrixEvent,
|
MatrixEvent,
|
||||||
Room,
|
Room,
|
||||||
|
@ -58,22 +59,22 @@ const STATIC_UPDATE_INTERVAL = 30000;
|
||||||
const BAIL_AFTER_CONSECUTIVE_ERROR_COUNT = 2;
|
const BAIL_AFTER_CONSECUTIVE_ERROR_COUNT = 2;
|
||||||
|
|
||||||
type OwnBeaconStoreState = {
|
type OwnBeaconStoreState = {
|
||||||
beacons: Map<string, Beacon>;
|
beacons: Map<BeaconIdentifier, Beacon>;
|
||||||
beaconWireErrors: Map<string, Beacon>;
|
beaconWireErrors: Map<string, Beacon>;
|
||||||
beaconsByRoomId: Map<Room['roomId'], Set<string>>;
|
beaconsByRoomId: Map<Room['roomId'], Set<BeaconIdentifier>>;
|
||||||
liveBeaconIds: string[];
|
liveBeaconIds: BeaconIdentifier[];
|
||||||
};
|
};
|
||||||
export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
|
export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
|
||||||
private static internalInstance = new OwnBeaconStore();
|
private static internalInstance = new OwnBeaconStore();
|
||||||
// users beacons, keyed by event type
|
// users beacons, keyed by event type
|
||||||
public readonly beacons = new Map<string, Beacon>();
|
public readonly beacons = new Map<BeaconIdentifier, Beacon>();
|
||||||
public readonly beaconsByRoomId = new Map<Room['roomId'], Set<string>>();
|
public readonly beaconsByRoomId = new Map<Room['roomId'], Set<BeaconIdentifier>>();
|
||||||
/**
|
/**
|
||||||
* Track over the wire errors for published positions
|
* Track over the wire errors for published positions
|
||||||
* Counts consecutive wire errors per beacon
|
* Counts consecutive wire errors per beacon
|
||||||
* Reset on successful publish of location
|
* Reset on successful publish of location
|
||||||
*/
|
*/
|
||||||
public readonly beaconWireErrorCounts = new Map<string, number>();
|
public readonly beaconWireErrorCounts = new Map<BeaconIdentifier, number>();
|
||||||
/**
|
/**
|
||||||
* ids of live beacons
|
* ids of live beacons
|
||||||
* ordered by creation time descending
|
* ordered by creation time descending
|
||||||
|
@ -108,6 +109,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
|
||||||
protected async onNotReady() {
|
protected async onNotReady() {
|
||||||
this.matrixClient.removeListener(BeaconEvent.LivenessChange, this.onBeaconLiveness);
|
this.matrixClient.removeListener(BeaconEvent.LivenessChange, this.onBeaconLiveness);
|
||||||
this.matrixClient.removeListener(BeaconEvent.New, this.onNewBeacon);
|
this.matrixClient.removeListener(BeaconEvent.New, this.onNewBeacon);
|
||||||
|
this.matrixClient.removeListener(BeaconEvent.Update, this.onUpdateBeacon);
|
||||||
this.matrixClient.removeListener(RoomStateEvent.Members, this.onRoomStateMembers);
|
this.matrixClient.removeListener(RoomStateEvent.Members, this.onRoomStateMembers);
|
||||||
|
|
||||||
this.beacons.forEach(beacon => beacon.destroy());
|
this.beacons.forEach(beacon => beacon.destroy());
|
||||||
|
@ -122,6 +124,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
|
||||||
protected async onReady(): Promise<void> {
|
protected async onReady(): Promise<void> {
|
||||||
this.matrixClient.on(BeaconEvent.LivenessChange, this.onBeaconLiveness);
|
this.matrixClient.on(BeaconEvent.LivenessChange, this.onBeaconLiveness);
|
||||||
this.matrixClient.on(BeaconEvent.New, this.onNewBeacon);
|
this.matrixClient.on(BeaconEvent.New, this.onNewBeacon);
|
||||||
|
this.matrixClient.removeListener(BeaconEvent.Update, this.onUpdateBeacon);
|
||||||
this.matrixClient.on(RoomStateEvent.Members, this.onRoomStateMembers);
|
this.matrixClient.on(RoomStateEvent.Members, this.onRoomStateMembers);
|
||||||
|
|
||||||
this.initialiseBeaconState();
|
this.initialiseBeaconState();
|
||||||
|
@ -177,8 +180,8 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
|
||||||
return this.beacons.get(beaconId);
|
return this.beacons.get(beaconId);
|
||||||
};
|
};
|
||||||
|
|
||||||
public stopBeacon = async (beaconInfoType: string): Promise<void> => {
|
public stopBeacon = async (beaconIdentifier: string): Promise<void> => {
|
||||||
const beacon = this.beacons.get(beaconInfoType);
|
const beacon = this.beacons.get(beaconIdentifier);
|
||||||
// if no beacon, or beacon is already explicitly set isLive: false
|
// if no beacon, or beacon is already explicitly set isLive: false
|
||||||
// do nothing
|
// do nothing
|
||||||
if (!beacon?.beaconInfo?.live) {
|
if (!beacon?.beaconInfo?.live) {
|
||||||
|
@ -200,6 +203,17 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
|
||||||
this.checkLiveness();
|
this.checkLiveness();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will be called when a beacon is replaced
|
||||||
|
*/
|
||||||
|
private onUpdateBeacon = (_event: MatrixEvent, beacon: Beacon): void => {
|
||||||
|
if (!isOwnBeacon(beacon, this.matrixClient.getUserId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.checkLiveness();
|
||||||
|
};
|
||||||
|
|
||||||
private onBeaconLiveness = (isLive: boolean, beacon: Beacon): void => {
|
private onBeaconLiveness = (isLive: boolean, beacon: Beacon): void => {
|
||||||
// check if we care about this beacon
|
// check if we care about this beacon
|
||||||
if (!this.beacons.has(beacon.identifier)) {
|
if (!this.beacons.has(beacon.identifier)) {
|
||||||
|
@ -439,7 +453,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
|
||||||
assetType,
|
assetType,
|
||||||
timestamp);
|
timestamp);
|
||||||
|
|
||||||
await this.matrixClient.unstable_setLiveBeacon(beacon.roomId, beacon.beaconInfoEventType, updateContent);
|
await this.matrixClient.unstable_setLiveBeacon(beacon.roomId, updateContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { BeaconInfoState } from "matrix-js-sdk/src/content-helpers";
|
||||||
import { Beacon } from "matrix-js-sdk/src/matrix";
|
import { Beacon } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,8 +27,8 @@ import { Beacon } from "matrix-js-sdk/src/matrix";
|
||||||
export const msUntilExpiry = (startTimestamp: number, durationMs: number): number =>
|
export const msUntilExpiry = (startTimestamp: number, durationMs: number): number =>
|
||||||
Math.max(0, (startTimestamp + durationMs) - Date.now());
|
Math.max(0, (startTimestamp + durationMs) - Date.now());
|
||||||
|
|
||||||
export const getBeaconMsUntilExpiry = (beacon: Beacon): number =>
|
export const getBeaconMsUntilExpiry = (beaconInfo: BeaconInfoState): number =>
|
||||||
msUntilExpiry(beacon.beaconInfo.timestamp, beacon.beaconInfo.timeout);
|
msUntilExpiry(beaconInfo.timestamp, beaconInfo.timeout);
|
||||||
|
|
||||||
export const getBeaconExpiryTimestamp = (beacon: Beacon): number =>
|
export const getBeaconExpiryTimestamp = (beacon: Beacon): number =>
|
||||||
beacon.beaconInfo.timestamp + beacon.beaconInfo.timeout;
|
beacon.beaconInfo.timestamp + beacon.beaconInfo.timeout;
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import { Room, Beacon, BeaconEvent } from 'matrix-js-sdk/src/matrix';
|
import { Room, Beacon, BeaconEvent, getBeaconInfoIdentifier } from 'matrix-js-sdk/src/matrix';
|
||||||
import { logger } from 'matrix-js-sdk/src/logger';
|
import { logger } from 'matrix-js-sdk/src/logger';
|
||||||
|
|
||||||
import RoomLiveShareWarning from '../../../../src/components/views/beacon/RoomLiveShareWarning';
|
import RoomLiveShareWarning from '../../../../src/components/views/beacon/RoomLiveShareWarning';
|
||||||
|
@ -221,6 +221,25 @@ describe('<RoomLiveShareWarning />', () => {
|
||||||
expect(getExpiryText(component)).toEqual('35m left');
|
expect(getExpiryText(component)).toEqual('35m left');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('updates beacon time left when beacon updates', () => {
|
||||||
|
const component = getComponent({ roomId: room1Id });
|
||||||
|
expect(getExpiryText(component)).toEqual('1h left');
|
||||||
|
|
||||||
|
expect(getExpiryText(component)).toEqual('1h left');
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
const beacon = OwnBeaconStore.instance.getBeaconById(getBeaconInfoIdentifier(room1Beacon1));
|
||||||
|
const room1Beacon1Update = makeBeaconInfoEvent(aliceId, room1Id, {
|
||||||
|
isLive: true,
|
||||||
|
timeout: 3 * HOUR_MS,
|
||||||
|
}, '$0');
|
||||||
|
beacon.update(room1Beacon1Update);
|
||||||
|
});
|
||||||
|
|
||||||
|
// update to expiry of new beacon
|
||||||
|
expect(getExpiryText(component)).toEqual('3h left');
|
||||||
|
});
|
||||||
|
|
||||||
it('clears expiry time interval on unmount', () => {
|
it('clears expiry time interval on unmount', () => {
|
||||||
const clearIntervalSpy = jest.spyOn(global, 'clearInterval');
|
const clearIntervalSpy = jest.spyOn(global, 'clearInterval');
|
||||||
const component = getComponent({ roomId: room1Id });
|
const component = getComponent({ roomId: room1Id });
|
||||||
|
@ -242,7 +261,7 @@ describe('<RoomLiveShareWarning />', () => {
|
||||||
component.setProps({});
|
component.setProps({});
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalledTimes(2);
|
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalled();
|
||||||
expect(component.find('Spinner').length).toBeTruthy();
|
expect(component.find('Spinner').length).toBeTruthy();
|
||||||
expect(findByTestId(component, 'room-live-share-primary-button').at(0).props().disabled).toBeTruthy();
|
expect(findByTestId(component, 'room-live-share-primary-button').at(0).props().disabled).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
@ -314,7 +333,7 @@ describe('<RoomLiveShareWarning />', () => {
|
||||||
// update mock and emit event
|
// update mock and emit event
|
||||||
act(() => {
|
act(() => {
|
||||||
hasWireErrorsSpy.mockReturnValue(true);
|
hasWireErrorsSpy.mockReturnValue(true);
|
||||||
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.WireError, room2Beacon1.getType());
|
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.WireError, getBeaconInfoIdentifier(room2Beacon1));
|
||||||
});
|
});
|
||||||
component.setProps({});
|
component.setProps({});
|
||||||
|
|
||||||
|
@ -332,7 +351,7 @@ describe('<RoomLiveShareWarning />', () => {
|
||||||
// update mock and emit event
|
// update mock and emit event
|
||||||
act(() => {
|
act(() => {
|
||||||
hasWireErrorsSpy.mockReturnValue(false);
|
hasWireErrorsSpy.mockReturnValue(false);
|
||||||
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.WireError, room2Beacon1.getType());
|
OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.WireError, getBeaconInfoIdentifier(room2Beacon1));
|
||||||
});
|
});
|
||||||
component.setProps({});
|
component.setProps({});
|
||||||
|
|
||||||
|
@ -353,8 +372,7 @@ describe('<RoomLiveShareWarning />', () => {
|
||||||
findByTestId(component, 'room-live-share-primary-button').at(0).simulate('click');
|
findByTestId(component, 'room-live-share-primary-button').at(0).simulate('click');
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(resetErrorSpy).toHaveBeenCalledWith(room2Beacon1.getType());
|
expect(resetErrorSpy).toHaveBeenCalledWith(getBeaconInfoIdentifier(room2Beacon1));
|
||||||
expect(resetErrorSpy).toHaveBeenCalledWith(room2Beacon2.getType());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clicking close button stops beacons', async () => {
|
it('clicking close button stops beacons', async () => {
|
||||||
|
@ -367,8 +385,7 @@ describe('<RoomLiveShareWarning />', () => {
|
||||||
findByTestId(component, 'room-live-share-wire-error-close-button').at(0).simulate('click');
|
findByTestId(component, 'room-live-share-wire-error-close-button').at(0).simulate('click');
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(stopBeaconSpy).toHaveBeenCalledWith(room2Beacon1.getType());
|
expect(stopBeaconSpy).toHaveBeenCalledWith(getBeaconInfoIdentifier(room2Beacon1));
|
||||||
expect(stopBeaconSpy).toHaveBeenCalledWith(room2Beacon2.getType());
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,8 +13,7 @@ exports[`<RoomLiveShareWarning /> when user has live beacons and geolocation is
|
||||||
<RoomLiveShareWarningInner
|
<RoomLiveShareWarningInner
|
||||||
liveBeaconIds={
|
liveBeaconIds={
|
||||||
Array [
|
Array [
|
||||||
"org.matrix.msc3489.beacon_info.@alice:server.org.3",
|
"$room2:server.org_@alice:server.org",
|
||||||
"org.matrix.msc3489.beacon_info.@alice:server.org.4",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
roomId="$room2:server.org"
|
roomId="$room2:server.org"
|
||||||
|
|
|
@ -20,7 +20,6 @@ import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
|
||||||
import { MatrixClient } from 'matrix-js-sdk/src/client';
|
import { MatrixClient } from 'matrix-js-sdk/src/client';
|
||||||
import { mocked } from 'jest-mock';
|
import { mocked } from 'jest-mock';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
import { M_BEACON_INFO } from 'matrix-js-sdk/src/@types/beacon';
|
|
||||||
import { M_ASSET, LocationAssetType } from 'matrix-js-sdk/src/@types/location';
|
import { M_ASSET, LocationAssetType } from 'matrix-js-sdk/src/@types/location';
|
||||||
import { logger } from 'matrix-js-sdk/src/logger';
|
import { logger } from 'matrix-js-sdk/src/logger';
|
||||||
|
|
||||||
|
@ -310,16 +309,13 @@ describe('<LocationShareMenu />', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(onFinished).toHaveBeenCalled();
|
expect(onFinished).toHaveBeenCalled();
|
||||||
const [eventRoomId, eventContent, eventTypeSuffix] = mockClient.unstable_createLiveBeacon.mock.calls[0];
|
const [eventRoomId, eventContent] = mockClient.unstable_createLiveBeacon.mock.calls[0];
|
||||||
expect(eventRoomId).toEqual(defaultProps.roomId);
|
expect(eventRoomId).toEqual(defaultProps.roomId);
|
||||||
expect(eventTypeSuffix).toBeTruthy();
|
|
||||||
expect(eventContent).toEqual(expect.objectContaining({
|
expect(eventContent).toEqual(expect.objectContaining({
|
||||||
[M_BEACON_INFO.name]: {
|
// default timeout
|
||||||
// default timeout
|
timeout: DEFAULT_DURATION_MS,
|
||||||
timeout: DEFAULT_DURATION_MS,
|
description: `Ernie's live location`,
|
||||||
description: `Ernie's live location`,
|
live: true,
|
||||||
live: true,
|
|
||||||
},
|
|
||||||
[M_ASSET.name]: {
|
[M_ASSET.name]: {
|
||||||
type: LocationAssetType.Self,
|
type: LocationAssetType.Self,
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,12 +18,13 @@ import {
|
||||||
Room,
|
Room,
|
||||||
Beacon,
|
Beacon,
|
||||||
BeaconEvent,
|
BeaconEvent,
|
||||||
|
getBeaconInfoIdentifier,
|
||||||
MatrixEvent,
|
MatrixEvent,
|
||||||
RoomStateEvent,
|
RoomStateEvent,
|
||||||
RoomMember,
|
RoomMember,
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
import { makeBeaconContent } from "matrix-js-sdk/src/content-helpers";
|
import { makeBeaconContent } from "matrix-js-sdk/src/content-helpers";
|
||||||
import { M_BEACON, M_BEACON_INFO } from "matrix-js-sdk/src/@types/beacon";
|
import { M_BEACON } from "matrix-js-sdk/src/@types/beacon";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
import { OwnBeaconStore, OwnBeaconStoreEvent } from "../../src/stores/OwnBeaconStore";
|
import { OwnBeaconStore, OwnBeaconStoreEvent } from "../../src/stores/OwnBeaconStore";
|
||||||
|
@ -80,32 +81,27 @@ describe('OwnBeaconStore', () => {
|
||||||
const alicesRoom1BeaconInfo = makeBeaconInfoEvent(aliceId,
|
const alicesRoom1BeaconInfo = makeBeaconInfoEvent(aliceId,
|
||||||
room1Id,
|
room1Id,
|
||||||
{ isLive: true },
|
{ isLive: true },
|
||||||
'$alice-room1-1'
|
'$alice-room1-1',
|
||||||
, '$alice-room1-1',
|
|
||||||
);
|
);
|
||||||
const alicesRoom2BeaconInfo = makeBeaconInfoEvent(aliceId,
|
const alicesRoom2BeaconInfo = makeBeaconInfoEvent(aliceId,
|
||||||
room2Id,
|
room2Id,
|
||||||
{ isLive: true },
|
{ isLive: true },
|
||||||
'$alice-room2-1'
|
'$alice-room2-1',
|
||||||
, '$alice-room2-1',
|
|
||||||
);
|
);
|
||||||
const alicesOldRoomIdBeaconInfo = makeBeaconInfoEvent(aliceId,
|
const alicesOldRoomIdBeaconInfo = makeBeaconInfoEvent(aliceId,
|
||||||
room1Id,
|
room1Id,
|
||||||
{ isLive: false },
|
{ isLive: false },
|
||||||
'$alice-room1-2'
|
'$alice-room1-2',
|
||||||
, '$alice-room1-2',
|
|
||||||
);
|
);
|
||||||
const bobsRoom1BeaconInfo = makeBeaconInfoEvent(bobId,
|
const bobsRoom1BeaconInfo = makeBeaconInfoEvent(bobId,
|
||||||
room1Id,
|
room1Id,
|
||||||
{ isLive: true },
|
{ isLive: true },
|
||||||
'$bob-room1-1'
|
'$bob-room1-1',
|
||||||
, '$bob-room1-1',
|
|
||||||
);
|
);
|
||||||
const bobsOldRoom1BeaconInfo = makeBeaconInfoEvent(bobId,
|
const bobsOldRoom1BeaconInfo = makeBeaconInfoEvent(bobId,
|
||||||
room1Id,
|
room1Id,
|
||||||
{ isLive: false },
|
{ isLive: false },
|
||||||
'$bob-room1-2'
|
'$bob-room1-2',
|
||||||
, '$bob-room1-2',
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// make fresh rooms every time
|
// make fresh rooms every time
|
||||||
|
@ -129,7 +125,7 @@ describe('OwnBeaconStore', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const expireBeaconAndEmit = (store, beaconInfoEvent: MatrixEvent): void => {
|
const expireBeaconAndEmit = (store, beaconInfoEvent: MatrixEvent): void => {
|
||||||
const beacon = store.getBeaconById(beaconInfoEvent.getType());
|
const beacon = store.getBeaconById(getBeaconInfoIdentifier(beaconInfoEvent));
|
||||||
// time travel until beacon is expired
|
// time travel until beacon is expired
|
||||||
advanceDateAndTime(beacon.beaconInfo.timeout + 100);
|
advanceDateAndTime(beacon.beaconInfo.timeout + 100);
|
||||||
|
|
||||||
|
@ -141,16 +137,14 @@ describe('OwnBeaconStore', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateBeaconLivenessAndEmit = (store, beaconInfoEvent: MatrixEvent, isLive: boolean): void => {
|
const updateBeaconLivenessAndEmit = (store, beaconInfoEvent: MatrixEvent, isLive: boolean): void => {
|
||||||
const beacon = store.getBeaconById(beaconInfoEvent.getType());
|
const beacon = store.getBeaconById(getBeaconInfoIdentifier(beaconInfoEvent));
|
||||||
// matches original state of event content
|
// matches original state of event content
|
||||||
// except for live property
|
// except for live property
|
||||||
const updateEvent = makeBeaconInfoEvent(
|
const updateEvent = makeBeaconInfoEvent(
|
||||||
beaconInfoEvent.getSender(),
|
beaconInfoEvent.getSender(),
|
||||||
beaconInfoEvent.getRoomId(),
|
beaconInfoEvent.getRoomId(),
|
||||||
{ isLive, timeout: beacon.beaconInfo.timeout },
|
{ isLive, timeout: beacon.beaconInfo.timeout },
|
||||||
undefined,
|
|
||||||
);
|
);
|
||||||
updateEvent.event.type = beaconInfoEvent.getType();
|
|
||||||
beacon.update(updateEvent);
|
beacon.update(updateEvent);
|
||||||
|
|
||||||
mockClient.emit(BeaconEvent.Update, beaconInfoEvent, beacon);
|
mockClient.emit(BeaconEvent.Update, beaconInfoEvent, beacon);
|
||||||
|
@ -197,15 +191,14 @@ describe('OwnBeaconStore', () => {
|
||||||
makeRoomsWithStateEvents([
|
makeRoomsWithStateEvents([
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
alicesRoom2BeaconInfo,
|
alicesRoom2BeaconInfo,
|
||||||
alicesOldRoomIdBeaconInfo,
|
|
||||||
bobsRoom1BeaconInfo,
|
bobsRoom1BeaconInfo,
|
||||||
bobsOldRoom1BeaconInfo,
|
bobsOldRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
const store = await makeOwnBeaconStore();
|
const store = await makeOwnBeaconStore();
|
||||||
expect(store.hasLiveBeacons()).toBe(true);
|
expect(store.hasLiveBeacons()).toBe(true);
|
||||||
expect(store.getLiveBeaconIds()).toEqual([
|
expect(store.getLiveBeaconIds()).toEqual([
|
||||||
alicesRoom1BeaconInfo.getType(),
|
getBeaconInfoIdentifier(alicesRoom1BeaconInfo),
|
||||||
alicesRoom2BeaconInfo.getType(),
|
getBeaconInfoIdentifier(alicesRoom2BeaconInfo),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -251,7 +244,8 @@ describe('OwnBeaconStore', () => {
|
||||||
|
|
||||||
expect(removeSpy.mock.calls[0]).toEqual(expect.arrayContaining([BeaconEvent.LivenessChange]));
|
expect(removeSpy.mock.calls[0]).toEqual(expect.arrayContaining([BeaconEvent.LivenessChange]));
|
||||||
expect(removeSpy.mock.calls[1]).toEqual(expect.arrayContaining([BeaconEvent.New]));
|
expect(removeSpy.mock.calls[1]).toEqual(expect.arrayContaining([BeaconEvent.New]));
|
||||||
expect(removeSpy.mock.calls[2]).toEqual(expect.arrayContaining([RoomStateEvent.Members]));
|
expect(removeSpy.mock.calls[2]).toEqual(expect.arrayContaining([BeaconEvent.Update]));
|
||||||
|
expect(removeSpy.mock.calls[3]).toEqual(expect.arrayContaining([RoomStateEvent.Members]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('destroys beacons', async () => {
|
it('destroys beacons', async () => {
|
||||||
|
@ -259,7 +253,7 @@ describe('OwnBeaconStore', () => {
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
const store = await makeOwnBeaconStore();
|
const store = await makeOwnBeaconStore();
|
||||||
const beacon = room1.currentState.beacons.get(alicesRoom1BeaconInfo.getType());
|
const beacon = room1.currentState.beacons.get(getBeaconInfoIdentifier(alicesRoom1BeaconInfo));
|
||||||
const destroySpy = jest.spyOn(beacon, 'destroy');
|
const destroySpy = jest.spyOn(beacon, 'destroy');
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
store.onNotReady();
|
store.onNotReady();
|
||||||
|
@ -273,7 +267,6 @@ describe('OwnBeaconStore', () => {
|
||||||
makeRoomsWithStateEvents([
|
makeRoomsWithStateEvents([
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
alicesRoom2BeaconInfo,
|
alicesRoom2BeaconInfo,
|
||||||
alicesOldRoomIdBeaconInfo,
|
|
||||||
bobsRoom1BeaconInfo,
|
bobsRoom1BeaconInfo,
|
||||||
bobsOldRoom1BeaconInfo,
|
bobsOldRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
|
@ -282,7 +275,6 @@ describe('OwnBeaconStore', () => {
|
||||||
it('returns true when user has live beacons', async () => {
|
it('returns true when user has live beacons', async () => {
|
||||||
makeRoomsWithStateEvents([
|
makeRoomsWithStateEvents([
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
alicesOldRoomIdBeaconInfo,
|
|
||||||
bobsRoom1BeaconInfo,
|
bobsRoom1BeaconInfo,
|
||||||
bobsOldRoom1BeaconInfo,
|
bobsOldRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
|
@ -302,7 +294,6 @@ describe('OwnBeaconStore', () => {
|
||||||
it('returns true when user has live beacons for roomId', async () => {
|
it('returns true when user has live beacons for roomId', async () => {
|
||||||
makeRoomsWithStateEvents([
|
makeRoomsWithStateEvents([
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
alicesOldRoomIdBeaconInfo,
|
|
||||||
bobsRoom1BeaconInfo,
|
bobsRoom1BeaconInfo,
|
||||||
bobsOldRoom1BeaconInfo,
|
bobsOldRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
|
@ -313,7 +304,6 @@ describe('OwnBeaconStore', () => {
|
||||||
it('returns false when user does not have live beacons for roomId', async () => {
|
it('returns false when user does not have live beacons for roomId', async () => {
|
||||||
makeRoomsWithStateEvents([
|
makeRoomsWithStateEvents([
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
alicesOldRoomIdBeaconInfo,
|
|
||||||
bobsRoom1BeaconInfo,
|
bobsRoom1BeaconInfo,
|
||||||
bobsOldRoom1BeaconInfo,
|
bobsOldRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
|
@ -327,7 +317,6 @@ describe('OwnBeaconStore', () => {
|
||||||
makeRoomsWithStateEvents([
|
makeRoomsWithStateEvents([
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
alicesRoom2BeaconInfo,
|
alicesRoom2BeaconInfo,
|
||||||
alicesOldRoomIdBeaconInfo,
|
|
||||||
bobsRoom1BeaconInfo,
|
bobsRoom1BeaconInfo,
|
||||||
bobsOldRoom1BeaconInfo,
|
bobsOldRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
|
@ -336,13 +325,12 @@ describe('OwnBeaconStore', () => {
|
||||||
it('returns live beacons when user has live beacons', async () => {
|
it('returns live beacons when user has live beacons', async () => {
|
||||||
makeRoomsWithStateEvents([
|
makeRoomsWithStateEvents([
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
alicesOldRoomIdBeaconInfo,
|
|
||||||
bobsRoom1BeaconInfo,
|
bobsRoom1BeaconInfo,
|
||||||
bobsOldRoom1BeaconInfo,
|
bobsOldRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
const store = await makeOwnBeaconStore();
|
const store = await makeOwnBeaconStore();
|
||||||
expect(store.getLiveBeaconIds()).toEqual([
|
expect(store.getLiveBeaconIds()).toEqual([
|
||||||
alicesRoom1BeaconInfo.getType(),
|
getBeaconInfoIdentifier(alicesRoom1BeaconInfo),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -359,23 +347,21 @@ describe('OwnBeaconStore', () => {
|
||||||
makeRoomsWithStateEvents([
|
makeRoomsWithStateEvents([
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
alicesRoom2BeaconInfo,
|
alicesRoom2BeaconInfo,
|
||||||
alicesOldRoomIdBeaconInfo,
|
|
||||||
bobsRoom1BeaconInfo,
|
bobsRoom1BeaconInfo,
|
||||||
bobsOldRoom1BeaconInfo,
|
bobsOldRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
const store = await makeOwnBeaconStore();
|
const store = await makeOwnBeaconStore();
|
||||||
expect(store.getLiveBeaconIds(room1Id)).toEqual([
|
expect(store.getLiveBeaconIds(room1Id)).toEqual([
|
||||||
alicesRoom1BeaconInfo.getType(),
|
getBeaconInfoIdentifier(alicesRoom1BeaconInfo),
|
||||||
]);
|
]);
|
||||||
expect(store.getLiveBeaconIds(room2Id)).toEqual([
|
expect(store.getLiveBeaconIds(room2Id)).toEqual([
|
||||||
alicesRoom2BeaconInfo.getType(),
|
getBeaconInfoIdentifier(alicesRoom2BeaconInfo),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns empty array when user does not have live beacons for roomId', async () => {
|
it('returns empty array when user does not have live beacons for roomId', async () => {
|
||||||
makeRoomsWithStateEvents([
|
makeRoomsWithStateEvents([
|
||||||
alicesRoom1BeaconInfo,
|
alicesRoom1BeaconInfo,
|
||||||
alicesOldRoomIdBeaconInfo,
|
|
||||||
bobsRoom1BeaconInfo,
|
bobsRoom1BeaconInfo,
|
||||||
bobsOldRoom1BeaconInfo,
|
bobsOldRoom1BeaconInfo,
|
||||||
]);
|
]);
|
||||||
|
@ -419,7 +405,7 @@ describe('OwnBeaconStore', () => {
|
||||||
|
|
||||||
mockClient.emit(BeaconEvent.New, alicesRoom1BeaconInfo, alicesLiveBeacon);
|
mockClient.emit(BeaconEvent.New, alicesRoom1BeaconInfo, alicesLiveBeacon);
|
||||||
|
|
||||||
expect(emitSpy).toHaveBeenCalledWith(OwnBeaconStoreEvent.LivenessChange, [alicesRoom1BeaconInfo.getType()]);
|
expect(emitSpy).toHaveBeenCalledWith(OwnBeaconStoreEvent.LivenessChange, [alicesLiveBeacon.identifier]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('emits a liveness change event when new beacons do not change live state', async () => {
|
it('emits a liveness change event when new beacons do not change live state', async () => {
|
||||||
|
@ -485,14 +471,10 @@ describe('OwnBeaconStore', () => {
|
||||||
// except for live property
|
// except for live property
|
||||||
const expectedUpdateContent = {
|
const expectedUpdateContent = {
|
||||||
...prevEventContent,
|
...prevEventContent,
|
||||||
[M_BEACON_INFO.name]: {
|
live: false,
|
||||||
...prevEventContent[M_BEACON_INFO.name],
|
|
||||||
live: false,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalledWith(
|
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalledWith(
|
||||||
room1Id,
|
room1Id,
|
||||||
alicesRoom1BeaconInfo.getType(),
|
|
||||||
expectedUpdateContent,
|
expectedUpdateContent,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -513,7 +495,7 @@ describe('OwnBeaconStore', () => {
|
||||||
expect(store.hasLiveBeacons(room1Id)).toBe(true);
|
expect(store.hasLiveBeacons(room1Id)).toBe(true);
|
||||||
expect(emitSpy).toHaveBeenCalledWith(
|
expect(emitSpy).toHaveBeenCalledWith(
|
||||||
OwnBeaconStoreEvent.LivenessChange,
|
OwnBeaconStoreEvent.LivenessChange,
|
||||||
[alicesOldRoomIdBeaconInfo.getType()],
|
[getBeaconInfoIdentifier(alicesOldRoomIdBeaconInfo)],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -603,7 +585,7 @@ describe('OwnBeaconStore', () => {
|
||||||
alicesRoom2BeaconInfo,
|
alicesRoom2BeaconInfo,
|
||||||
]);
|
]);
|
||||||
const store = await makeOwnBeaconStore();
|
const store = await makeOwnBeaconStore();
|
||||||
const room1BeaconInstance = store.beacons.get(alicesRoom1BeaconInfo.getType());
|
const room1BeaconInstance = store.beacons.get(getBeaconInfoIdentifier(alicesRoom1BeaconInfo));
|
||||||
const beaconDestroySpy = jest.spyOn(room1BeaconInstance, 'destroy');
|
const beaconDestroySpy = jest.spyOn(room1BeaconInstance, 'destroy');
|
||||||
const emitSpy = jest.spyOn(store, 'emit');
|
const emitSpy = jest.spyOn(store, 'emit');
|
||||||
|
|
||||||
|
@ -617,7 +599,7 @@ describe('OwnBeaconStore', () => {
|
||||||
expect(emitSpy).toHaveBeenCalledWith(
|
expect(emitSpy).toHaveBeenCalledWith(
|
||||||
OwnBeaconStoreEvent.LivenessChange,
|
OwnBeaconStoreEvent.LivenessChange,
|
||||||
// other rooms beacons still live
|
// other rooms beacons still live
|
||||||
[alicesRoom2BeaconInfo.getType()],
|
[getBeaconInfoIdentifier(alicesRoom2BeaconInfo)],
|
||||||
);
|
);
|
||||||
expect(beaconDestroySpy).toHaveBeenCalledTimes(1);
|
expect(beaconDestroySpy).toHaveBeenCalledTimes(1);
|
||||||
expect(store.getLiveBeaconIds(room1Id)).toEqual([]);
|
expect(store.getLiveBeaconIds(room1Id)).toEqual([]);
|
||||||
|
@ -640,57 +622,53 @@ describe('OwnBeaconStore', () => {
|
||||||
|
|
||||||
it('does nothing for a beacon that is already not live', async () => {
|
it('does nothing for a beacon that is already not live', async () => {
|
||||||
const store = await makeOwnBeaconStore();
|
const store = await makeOwnBeaconStore();
|
||||||
await store.stopBeacon(alicesOldRoomIdBeaconInfo.getId());
|
await store.stopBeacon(getBeaconInfoIdentifier(alicesOldRoomIdBeaconInfo));
|
||||||
expect(mockClient.unstable_setLiveBeacon).not.toHaveBeenCalled();
|
expect(mockClient.unstable_setLiveBeacon).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates beacon to live:false when it is unexpired', async () => {
|
it('updates beacon to live:false when it is unexpired', async () => {
|
||||||
|
makeRoomsWithStateEvents([
|
||||||
|
alicesRoom1BeaconInfo,
|
||||||
|
]);
|
||||||
const store = await makeOwnBeaconStore();
|
const store = await makeOwnBeaconStore();
|
||||||
|
|
||||||
await store.stopBeacon(alicesOldRoomIdBeaconInfo.getType());
|
|
||||||
const prevEventContent = alicesRoom1BeaconInfo.getContent();
|
const prevEventContent = alicesRoom1BeaconInfo.getContent();
|
||||||
|
|
||||||
await store.stopBeacon(alicesRoom1BeaconInfo.getType());
|
await store.stopBeacon(getBeaconInfoIdentifier(alicesRoom1BeaconInfo));
|
||||||
|
|
||||||
// matches original state of event content
|
// matches original state of event content
|
||||||
// except for live property
|
// except for live property
|
||||||
const expectedUpdateContent = {
|
const expectedUpdateContent = {
|
||||||
...prevEventContent,
|
...prevEventContent,
|
||||||
[M_BEACON_INFO.name]: {
|
live: false,
|
||||||
...prevEventContent[M_BEACON_INFO.name],
|
|
||||||
live: false,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalledWith(
|
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalledWith(
|
||||||
room1Id,
|
room1Id,
|
||||||
alicesRoom1BeaconInfo.getType(),
|
|
||||||
expectedUpdateContent,
|
expectedUpdateContent,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates beacon to live:false when it is expired but live property is true', async () => {
|
it('updates beacon to live:false when it is expired but live property is true', async () => {
|
||||||
|
makeRoomsWithStateEvents([
|
||||||
|
alicesRoom1BeaconInfo,
|
||||||
|
]);
|
||||||
const store = await makeOwnBeaconStore();
|
const store = await makeOwnBeaconStore();
|
||||||
|
|
||||||
await store.stopBeacon(alicesOldRoomIdBeaconInfo.getType());
|
|
||||||
const prevEventContent = alicesRoom1BeaconInfo.getContent();
|
const prevEventContent = alicesRoom1BeaconInfo.getContent();
|
||||||
|
|
||||||
// time travel until beacon is expired
|
// time travel until beacon is expired
|
||||||
advanceDateAndTime(HOUR_MS * 3);
|
advanceDateAndTime(HOUR_MS * 3);
|
||||||
|
|
||||||
await store.stopBeacon(alicesRoom1BeaconInfo.getType());
|
await store.stopBeacon(getBeaconInfoIdentifier(alicesRoom1BeaconInfo));
|
||||||
|
|
||||||
// matches original state of event content
|
// matches original state of event content
|
||||||
// except for live property
|
// except for live property
|
||||||
const expectedUpdateContent = {
|
const expectedUpdateContent = {
|
||||||
...prevEventContent,
|
...prevEventContent,
|
||||||
[M_BEACON_INFO.name]: {
|
live: false,
|
||||||
...prevEventContent[M_BEACON_INFO.name],
|
|
||||||
live: false,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalledWith(
|
expect(mockClient.unstable_setLiveBeacon).toHaveBeenCalledWith(
|
||||||
room1Id,
|
room1Id,
|
||||||
alicesRoom1BeaconInfo.getType(),
|
|
||||||
expectedUpdateContent,
|
expectedUpdateContent,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -863,7 +841,7 @@ describe('OwnBeaconStore', () => {
|
||||||
|
|
||||||
// called for each position from watchPosition
|
// called for each position from watchPosition
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledTimes(5);
|
expect(mockClient.sendEvent).toHaveBeenCalledTimes(5);
|
||||||
expect(store.beaconHasWireError(alicesRoom1BeaconInfo.getType())).toBe(false);
|
expect(store.beaconHasWireError(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toBe(false);
|
||||||
expect(store.hasWireErrors()).toBe(false);
|
expect(store.hasWireErrors()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -890,10 +868,10 @@ describe('OwnBeaconStore', () => {
|
||||||
|
|
||||||
// called for each position from watchPosition
|
// called for each position from watchPosition
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledTimes(5);
|
expect(mockClient.sendEvent).toHaveBeenCalledTimes(5);
|
||||||
expect(store.beaconHasWireError(alicesRoom1BeaconInfo.getType())).toBe(false);
|
expect(store.beaconHasWireError(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toBe(false);
|
||||||
expect(store.hasWireErrors()).toBe(false);
|
expect(store.hasWireErrors()).toBe(false);
|
||||||
expect(emitSpy).not.toHaveBeenCalledWith(
|
expect(emitSpy).not.toHaveBeenCalledWith(
|
||||||
OwnBeaconStoreEvent.WireError, alicesRoom1BeaconInfo.getType(),
|
OwnBeaconStoreEvent.WireError, getBeaconInfoIdentifier(alicesRoom1BeaconInfo),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -913,10 +891,10 @@ describe('OwnBeaconStore', () => {
|
||||||
|
|
||||||
// only two allowed failures
|
// only two allowed failures
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledTimes(2);
|
expect(mockClient.sendEvent).toHaveBeenCalledTimes(2);
|
||||||
expect(store.beaconHasWireError(alicesRoom1BeaconInfo.getType())).toBe(true);
|
expect(store.beaconHasWireError(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toBe(true);
|
||||||
expect(store.hasWireErrors()).toBe(true);
|
expect(store.hasWireErrors()).toBe(true);
|
||||||
expect(emitSpy).toHaveBeenCalledWith(
|
expect(emitSpy).toHaveBeenCalledWith(
|
||||||
OwnBeaconStoreEvent.WireError, alicesRoom1BeaconInfo.getType(),
|
OwnBeaconStoreEvent.WireError, getBeaconInfoIdentifier(alicesRoom1BeaconInfo),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -936,18 +914,18 @@ describe('OwnBeaconStore', () => {
|
||||||
|
|
||||||
// only two allowed failures
|
// only two allowed failures
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledTimes(2);
|
expect(mockClient.sendEvent).toHaveBeenCalledTimes(2);
|
||||||
expect(store.beaconHasWireError(alicesRoom1BeaconInfo.getType())).toBe(true);
|
expect(store.beaconHasWireError(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toBe(true);
|
||||||
expect(store.hasWireErrors()).toBe(true);
|
expect(store.hasWireErrors()).toBe(true);
|
||||||
expect(store.hasWireErrors(room1Id)).toBe(true);
|
expect(store.hasWireErrors(room1Id)).toBe(true);
|
||||||
expect(emitSpy).toHaveBeenCalledWith(
|
expect(emitSpy).toHaveBeenCalledWith(
|
||||||
OwnBeaconStoreEvent.WireError, alicesRoom1BeaconInfo.getType(),
|
OwnBeaconStoreEvent.WireError, getBeaconInfoIdentifier(alicesRoom1BeaconInfo),
|
||||||
);
|
);
|
||||||
|
|
||||||
// reset emitSpy mock counts to asser on wireError again
|
// reset emitSpy mock counts to asser on wireError again
|
||||||
emitSpy.mockClear();
|
emitSpy.mockClear();
|
||||||
store.resetWireError(alicesRoom1BeaconInfo.getType());
|
store.resetWireError(getBeaconInfoIdentifier(alicesRoom1BeaconInfo));
|
||||||
|
|
||||||
expect(store.beaconHasWireError(alicesRoom1BeaconInfo.getType())).toBe(false);
|
expect(store.beaconHasWireError(getBeaconInfoIdentifier(alicesRoom1BeaconInfo))).toBe(false);
|
||||||
|
|
||||||
// 2 more positions from watchPosition in this period
|
// 2 more positions from watchPosition in this period
|
||||||
await advanceAndFlushPromises(10000);
|
await advanceAndFlushPromises(10000);
|
||||||
|
@ -955,7 +933,7 @@ describe('OwnBeaconStore', () => {
|
||||||
// 2 from before, 2 new ones
|
// 2 from before, 2 new ones
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledTimes(4);
|
expect(mockClient.sendEvent).toHaveBeenCalledTimes(4);
|
||||||
expect(emitSpy).toHaveBeenCalledWith(
|
expect(emitSpy).toHaveBeenCalledWith(
|
||||||
OwnBeaconStoreEvent.WireError, alicesRoom1BeaconInfo.getType(),
|
OwnBeaconStoreEvent.WireError, getBeaconInfoIdentifier(alicesRoom1BeaconInfo),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,8 +33,6 @@ const DEFAULT_INFO_CONTENT_PROPS: InfoContentProps = {
|
||||||
timeout: 3600000,
|
timeout: 3600000,
|
||||||
};
|
};
|
||||||
|
|
||||||
let count = 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an m.beacon_info event
|
* Create an m.beacon_info event
|
||||||
* all required properties are mocked
|
* all required properties are mocked
|
||||||
|
@ -45,7 +43,6 @@ export const makeBeaconInfoEvent = (
|
||||||
roomId: string,
|
roomId: string,
|
||||||
contentProps: Partial<InfoContentProps> = {},
|
contentProps: Partial<InfoContentProps> = {},
|
||||||
eventId?: string,
|
eventId?: string,
|
||||||
eventTypeSuffix?: string,
|
|
||||||
): MatrixEvent => {
|
): MatrixEvent => {
|
||||||
const {
|
const {
|
||||||
timeout,
|
timeout,
|
||||||
|
@ -58,12 +55,15 @@ export const makeBeaconInfoEvent = (
|
||||||
...contentProps,
|
...contentProps,
|
||||||
};
|
};
|
||||||
const event = new MatrixEvent({
|
const event = new MatrixEvent({
|
||||||
type: `${M_BEACON_INFO.name}.${sender}.${eventTypeSuffix || ++count}`,
|
type: M_BEACON_INFO.name,
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
state_key: sender,
|
state_key: sender,
|
||||||
|
sender,
|
||||||
content: makeBeaconInfoContent(timeout, isLive, description, assetType, timestamp),
|
content: makeBeaconInfoContent(timeout, isLive, description, assetType, timestamp),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
event.event.origin_server_ts = Date.now();
|
||||||
|
|
||||||
// live beacons use the beacon_info event id
|
// live beacons use the beacon_info event id
|
||||||
// set or default this
|
// set or default this
|
||||||
event.replaceLocalEventId(eventId || `$${Math.random()}-${Math.random()}`);
|
event.replaceLocalEventId(eventId || `$${Math.random()}-${Math.random()}`);
|
||||||
|
|
Loading…
Reference in New Issue