diff --git a/src/stores/OwnBeaconStore.ts b/src/stores/OwnBeaconStore.ts index 941a5a82cdb3..74d42382851d 100644 --- a/src/stores/OwnBeaconStore.ts +++ b/src/stores/OwnBeaconStore.ts @@ -25,6 +25,7 @@ import { BeaconInfoState, makeBeaconContent, makeBeaconInfoContent, } from "matrix-js-sdk/src/content-helpers"; import { M_BEACON } from "matrix-js-sdk/src/@types/beacon"; +import { logger } from "matrix-js-sdk/src/logger"; import defaultDispatcher from "../dispatcher/dispatcher"; import { ActionPayload } from "../dispatcher/payloads"; @@ -63,10 +64,11 @@ export class OwnBeaconStore extends AsyncStoreWithClient { private geolocationError: GeolocationError | undefined; private clearPositionWatch: ClearWatchCallback | undefined; /** - * Track the last published position and when it was published - * so it can be republished while the user is static + * Track when the last position was published + * So we can manually get position on slow interval + * when the target is status */ - private lastPublishedPosition: { position: TimedGeoUri, publishedTimestamp: number } | undefined; + private lastPublishedPositionTimestamp: number | undefined; public constructor() { super(defaultDispatcher); @@ -241,13 +243,12 @@ export class OwnBeaconStore extends AsyncStoreWithClient { this.clearPositionWatch = await watchPosition(this.onWatchedPosition, this.onWatchedPositionError); this.locationInterval = setInterval(() => { - if (!this.lastPublishedPosition) { + if (!this.lastPublishedPositionTimestamp) { return; } - const { publishedTimestamp } = this.lastPublishedPosition; // if position was last updated STATIC_UPDATE_INTERVAL ms ago or more // get our position and publish it - if (publishedTimestamp <= Date.now() - STATIC_UPDATE_INTERVAL) { + if (this.lastPublishedPositionTimestamp <= Date.now() - STATIC_UPDATE_INTERVAL) { this.publishCurrentLocationToBeacons(); } }, STATIC_UPDATE_INTERVAL); @@ -257,7 +258,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient { const timedGeoPosition = mapGeolocationPositionToTimedGeo(position); // if this is our first position, publish immediateley - if (!this.lastPublishedPosition) { + if (!this.lastPublishedPositionTimestamp) { this.publishLocationToBeacons(timedGeoPosition); } else { this.debouncedPublishLocationToBeacons(timedGeoPosition); @@ -266,13 +267,13 @@ export class OwnBeaconStore extends AsyncStoreWithClient { private onWatchedPositionError = (error: GeolocationError) => { this.geolocationError = error; - console.log(this.geolocationError); + logger.error(this.geolocationError); }; private stopPollingLocation = () => { clearInterval(this.locationInterval); this.locationInterval = undefined; - this.lastPublishedPosition = undefined; + this.lastPublishedPositionTimestamp = undefined; this.geolocationError = undefined; if (this.clearPositionWatch) { @@ -286,7 +287,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient { * Sets last published beacon */ private publishLocationToBeacons = async (position: TimedGeoUri) => { - this.lastPublishedPosition = { position, publishedTimestamp: Date.now() }; + this.lastPublishedPositionTimestamp = Date.now(); // TODO handle failure in individual beacon without rejecting rest await Promise.all(this.liveBeaconIds.map(beaconId => this.sendLocationToBeacon(this.beacons.get(beaconId), position)), diff --git a/test/components/views/beacon/RoomLiveShareWarning-test.tsx b/test/components/views/beacon/RoomLiveShareWarning-test.tsx index 75c3710c2335..ad3cbdf5ff6d 100644 --- a/test/components/views/beacon/RoomLiveShareWarning-test.tsx +++ b/test/components/views/beacon/RoomLiveShareWarning-test.tsx @@ -23,6 +23,7 @@ import '../../../skinned-sdk'; import RoomLiveShareWarning from '../../../../src/components/views/beacon/RoomLiveShareWarning'; import { OwnBeaconStore } from '../../../../src/stores/OwnBeaconStore'; import { + advanceDateAndTime, findByTestId, getMockClientWithEventEmitter, makeBeaconInfoEvent, @@ -72,14 +73,6 @@ describe('', () => { return [room1, room2]; }; - const advanceDateAndTime = (ms: number) => { - // bc liveness check uses Date.now we have to advance this mock - jest.spyOn(global.Date, 'now').mockReturnValue(Date.now() + ms); - - // then advance time for the interval by the same amount - jest.advanceTimersByTime(ms); - }; - const makeOwnBeaconStore = async () => { const store = OwnBeaconStore.instance; diff --git a/test/stores/OwnBeaconStore-test.ts b/test/stores/OwnBeaconStore-test.ts index 0cc5dcb78cfe..55da90a1b790 100644 --- a/test/stores/OwnBeaconStore-test.ts +++ b/test/stores/OwnBeaconStore-test.ts @@ -19,7 +19,12 @@ import { makeBeaconContent } from "matrix-js-sdk/src/content-helpers"; import { M_BEACON, M_BEACON_INFO } from "matrix-js-sdk/src/@types/beacon"; import { OwnBeaconStore, OwnBeaconStoreEvent } from "../../src/stores/OwnBeaconStore"; -import { flushPromisesWithFakeTimers, resetAsyncStoreWithClient, setupAsyncStoreWithClient } from "../test-utils"; +import { + advanceDateAndTime, + flushPromisesWithFakeTimers, + resetAsyncStoreWithClient, + setupAsyncStoreWithClient, +} from "../test-utils"; import { makeBeaconInfoEvent, makeGeolocationPosition, @@ -107,13 +112,6 @@ describe('OwnBeaconStore', () => { return [room1, room2]; }; - const advanceDateAndTime = (ms: number) => { - // bc liveness check uses Date.now we have to advance this mock - jest.spyOn(global.Date, 'now').mockReturnValue(Date.now() + ms); - // then advance time for the interval by the same amount - jest.advanceTimersByTime(ms); - }; - const makeOwnBeaconStore = async () => { const store = OwnBeaconStore.instance; diff --git a/test/test-utils/utilities.ts b/test/test-utils/utilities.ts index e93cbff10c0e..a4370fbc9e1e 100644 --- a/test/test-utils/utilities.ts +++ b/test/test-utils/utilities.ts @@ -32,7 +32,7 @@ export const findByTagAndTestId = findByTagAndAttr('data-test-id'); export const flushPromises = async () => await new Promise(resolve => setTimeout(resolve)); // with jest's modern fake timers process.nextTick is also mocked, -// flushing promises in the normal way waiting for some advancement +// flushing promises in the normal way then waits for some advancement // of the fake timers // https://gist.github.com/apieceofbart/e6dea8d884d29cf88cdb54ef14ddbcc4?permalink_comment_id=4018174#gistcomment-4018174 export const flushPromisesWithFakeTimers = async (): Promise => { @@ -67,3 +67,13 @@ export function waitForUpdate(inst: React.Component, updates = 1): Promise }; }); } + +/** + * Advance jests fake timers and Date.now mock by ms + * Useful for testing code using timeouts or intervals + * that also checks timestamps + */ +export const advanceDateAndTime = (ms: number) => { + jest.spyOn(global.Date, 'now').mockReturnValue(Date.now() + ms); + jest.advanceTimersByTime(ms); +};