diff --git a/src/utils/beacon/duration.ts b/src/utils/beacon/duration.ts index 6be934b909a1..b85e2ff85f68 100644 --- a/src/utils/beacon/duration.ts +++ b/src/utils/beacon/duration.ts @@ -1,3 +1,5 @@ +import { Beacon } from "matrix-js-sdk/src/matrix"; + /** * Get ms until expiry * Returns 0 when expiry is already passed @@ -7,3 +9,12 @@ */ export const msUntilExpiry = (startTimestamp: number, durationMs: number): number => Math.max(0, (startTimestamp + durationMs) - Date.now()); + +export const getBeaconMsUntilExpiry = (beacon: Beacon): number => + msUntilExpiry(beacon.beaconInfo.timestamp, beacon.beaconInfo.timeout); + +export const getBeaconExpiryTimestamp = (beacon: Beacon): number => + beacon.beaconInfo.timestamp + beacon.beaconInfo.timeout; + +export const sortBeaconsByLatestExpiry = (left: Beacon, right: Beacon): number => + getBeaconExpiryTimestamp(right) - getBeaconExpiryTimestamp(left); diff --git a/test/test-utils/beacon.ts b/test/test-utils/beacon.ts index dffdfaf2510f..fbce6459b1d4 100644 --- a/test/test-utils/beacon.ts +++ b/test/test-utils/beacon.ts @@ -24,6 +24,7 @@ type InfoContentProps = { isLive?: boolean; assetType?: LocationAssetType; description?: string; + timestamp?: number; }; const DEFAULT_INFO_CONTENT_PROPS: InfoContentProps = { timeout: 3600000, @@ -45,6 +46,7 @@ export const makeBeaconInfoEvent = ( ): MatrixEvent => { const { timeout, isLive, description, assetType, + timestamp, } = { ...DEFAULT_INFO_CONTENT_PROPS, ...contentProps, @@ -53,7 +55,7 @@ export const makeBeaconInfoEvent = ( type: `${M_BEACON_INFO.name}.${sender}.${eventTypeSuffix || ++count}`, room_id: roomId, state_key: sender, - content: makeBeaconInfoContent(timeout, isLive, description, assetType), + content: makeBeaconInfoContent(timeout, isLive, description, assetType, timestamp), }); // live beacons use the beacon_info event id diff --git a/test/utils/beacon/duration-test.ts b/test/utils/beacon/duration-test.ts index 82247890dfd8..f5398e2bf8af 100644 --- a/test/utils/beacon/duration-test.ts +++ b/test/utils/beacon/duration-test.ts @@ -1,6 +1,9 @@ -import { msUntilExpiry } from "../../../src/utils/beacon"; +import { Beacon } from "matrix-js-sdk/src/matrix"; -describe('msUntilExpiry', () => { +import { msUntilExpiry, sortBeaconsByLatestExpiry } from "../../../src/utils/beacon"; +import { makeBeaconInfoEvent } from "../../test-utils"; + +describe('beacon utils', () => { // 14.03.2022 16:15 const now = 1647270879403; const HOUR_MS = 3600000; @@ -13,19 +16,52 @@ describe('msUntilExpiry', () => { jest.spyOn(global.Date, 'now').mockRestore(); }); - it('returns remaining duration', () => { - const start = now - HOUR_MS; - const durationMs = HOUR_MS * 3; + describe('msUntilExpiry', () => { + it('returns remaining duration', () => { + const start = now - HOUR_MS; + const durationMs = HOUR_MS * 3; + + expect(msUntilExpiry(start, durationMs)).toEqual(HOUR_MS * 2); + }); + + it('returns 0 when expiry has already passed', () => { + // created 3h ago + const start = now - HOUR_MS * 3; + // 1h durations + const durationMs = HOUR_MS; - expect(msUntilExpiry(start, durationMs)).toEqual(HOUR_MS * 2); + expect(msUntilExpiry(start, durationMs)).toEqual(0); + }); }); - it('returns 0 when expiry has already passed', () => { - // created 3h ago - const start = now - HOUR_MS * 3; - // 1h durations - const durationMs = HOUR_MS; + describe('sortBeaconsByLatestExpiry()', () => { + const roomId = '!room:server'; + const aliceId = '@alive:server'; + + // 12h old, 12h left + const beacon1 = new Beacon(makeBeaconInfoEvent(aliceId, + roomId, + { timeout: HOUR_MS * 24, timestamp: now - 12 * HOUR_MS }, + '$1', + )); + // 10h left + const beacon2 = new Beacon(makeBeaconInfoEvent(aliceId, + roomId, + { timeout: HOUR_MS * 10, timestamp: now }, + '$2', + )); + + // 1ms left + const beacon3 = new Beacon(makeBeaconInfoEvent(aliceId, + roomId, + { timeout: HOUR_MS + 1, timestamp: now - HOUR_MS }, + '$3', + )); - expect(msUntilExpiry(start, durationMs)).toEqual(0); + it('sorts beacons by descending expiry time', () => { + expect([beacon2, beacon3, beacon1].sort(sortBeaconsByLatestExpiry)).toEqual([ + beacon1, beacon2, beacon3, + ]); + }); }); });