From e196d6c44e7ef4c655acae4d80f9a48f0a26098a Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 28 Apr 2022 17:16:55 +0200 Subject: [PATCH 1/3] handle safari cocoa core data timestamps Signed-off-by: Kerry Archibald --- src/utils/beacon/geolocation.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/utils/beacon/geolocation.ts b/src/utils/beacon/geolocation.ts index b21fddad63b..898698fca28 100644 --- a/src/utils/beacon/geolocation.ts +++ b/src/utils/beacon/geolocation.ts @@ -86,8 +86,13 @@ export const genericPositionFromGeolocation = (geoPosition: GeolocationPosition) const { latitude, longitude, altitude, accuracy, } = geoPosition.coords; + return { - timestamp: geoPosition.timestamp, + // safari reports geolocation timestamps as Apple Cocoa Core Data timestamp + // or ms since 1/1/2001 instead of the regular epoch + // they also use local time, not utc + // to simplify, just use Date.now() + timestamp: Date.now(), latitude, longitude, altitude, accuracy, }; }; From 51ab771d613247f984145c61379aa387f495cad7 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 28 Apr 2022 18:20:47 +0200 Subject: [PATCH 2/3] actually fix safari timestamp issue properly Signed-off-by: Kerry Archibald --- src/utils/beacon/geolocation.ts | 3 ++- test/stores/OwnBeaconStore-test.ts | 8 +++----- test/utils/beacon/geolocation-test.ts | 7 ++++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/utils/beacon/geolocation.ts b/src/utils/beacon/geolocation.ts index 898698fca28..c21ccf2f2e2 100644 --- a/src/utils/beacon/geolocation.ts +++ b/src/utils/beacon/geolocation.ts @@ -114,7 +114,8 @@ export const getGeoUri = (position: GenericPosition): string => { }; export const mapGeolocationPositionToTimedGeo = (position: GeolocationPosition): TimedGeoUri => { - return { timestamp: position.timestamp, geoUri: getGeoUri(genericPositionFromGeolocation(position)) }; + const genericPosition = genericPositionFromGeolocation(position); + return { timestamp: genericPosition.timestamp, geoUri: getGeoUri(genericPosition) }; }; /** diff --git a/test/stores/OwnBeaconStore-test.ts b/test/stores/OwnBeaconStore-test.ts index d44c12620c7..66204580fc1 100644 --- a/test/stores/OwnBeaconStore-test.ts +++ b/test/stores/OwnBeaconStore-test.ts @@ -37,7 +37,6 @@ import { } from "../test-utils"; import { makeBeaconInfoEvent, - makeGeolocationPosition, mockGeolocation, watchPositionMockImplementation, } from "../test-utils/beacon"; @@ -70,7 +69,6 @@ describe('OwnBeaconStore', () => { const room2Id = '$room2:server.org'; // returned by default geolocation mocks - const defaultLocation = makeGeolocationPosition({}); const defaultLocationUri = 'geo:54.001927,-8.253491;u=1'; // beacon_info events @@ -245,7 +243,7 @@ describe('OwnBeaconStore', () => { expect(mockClient.sendEvent).not.toHaveBeenCalled(); }); - it('does geolocation and sends location immediatley when user has live beacons', async () => { + it('does geolocation and sends location immediately when user has live beacons', async () => { localStorageGetSpy.mockReturnValue(JSON.stringify([ alicesRoom1BeaconInfo.getId(), alicesRoom2BeaconInfo.getId(), @@ -261,12 +259,12 @@ describe('OwnBeaconStore', () => { expect(mockClient.sendEvent).toHaveBeenCalledWith( room1Id, M_BEACON.name, - makeBeaconContent(defaultLocationUri, defaultLocation.timestamp, alicesRoom1BeaconInfo.getId()), + makeBeaconContent(defaultLocationUri, now, alicesRoom1BeaconInfo.getId()), ); expect(mockClient.sendEvent).toHaveBeenCalledWith( room2Id, M_BEACON.name, - makeBeaconContent(defaultLocationUri, defaultLocation.timestamp, alicesRoom2BeaconInfo.getId()), + makeBeaconContent(defaultLocationUri, now, alicesRoom2BeaconInfo.getId()), ); }); }); diff --git a/test/utils/beacon/geolocation-test.ts b/test/utils/beacon/geolocation-test.ts index 6d701830705..3807e7b7eca 100644 --- a/test/utils/beacon/geolocation-test.ts +++ b/test/utils/beacon/geolocation-test.ts @@ -34,11 +34,16 @@ describe('geolocation utilities', () => { let geolocation; const defaultPosition = makeGeolocationPosition({}); + // 14.03.2022 16:15 + const now = 1647270879403; + beforeEach(() => { geolocation = mockGeolocation(); + jest.spyOn(Date, 'now').mockReturnValue(now); }); afterEach(() => { + jest.spyOn(Date, 'now').mockRestore(); jest.spyOn(logger, 'error').mockRestore(); }); @@ -136,7 +141,7 @@ describe('geolocation utilities', () => { describe('mapGeolocationPositionToTimedGeo()', () => { it('maps geolocation position correctly', () => { expect(mapGeolocationPositionToTimedGeo(defaultPosition)).toEqual({ - timestamp: 1647256791840, geoUri: 'geo:54.001927,-8.253491;u=1', + timestamp: now, geoUri: 'geo:54.001927,-8.253491;u=1', }); }); }); From 2c6204495d8b624e823a241c56207f5e9988c2ce Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 28 Apr 2022 18:20:47 +0200 Subject: [PATCH 3/3] actually fix safari timestamp issue properly Signed-off-by: Kerry Archibald --- src/utils/beacon/geolocation.ts | 3 ++- test/stores/OwnBeaconStore-test.ts | 8 +++----- test/utils/beacon/geolocation-test.ts | 7 ++++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/utils/beacon/geolocation.ts b/src/utils/beacon/geolocation.ts index e8923afbf2f..efc3a9b44c3 100644 --- a/src/utils/beacon/geolocation.ts +++ b/src/utils/beacon/geolocation.ts @@ -114,7 +114,8 @@ export const getGeoUri = (position: GenericPosition): string => { }; export const mapGeolocationPositionToTimedGeo = (position: GeolocationPosition): TimedGeoUri => { - return { timestamp: position.timestamp, geoUri: getGeoUri(genericPositionFromGeolocation(position)) }; + const genericPosition = genericPositionFromGeolocation(position); + return { timestamp: genericPosition.timestamp, geoUri: getGeoUri(genericPosition) }; }; /** diff --git a/test/stores/OwnBeaconStore-test.ts b/test/stores/OwnBeaconStore-test.ts index d44c12620c7..66204580fc1 100644 --- a/test/stores/OwnBeaconStore-test.ts +++ b/test/stores/OwnBeaconStore-test.ts @@ -37,7 +37,6 @@ import { } from "../test-utils"; import { makeBeaconInfoEvent, - makeGeolocationPosition, mockGeolocation, watchPositionMockImplementation, } from "../test-utils/beacon"; @@ -70,7 +69,6 @@ describe('OwnBeaconStore', () => { const room2Id = '$room2:server.org'; // returned by default geolocation mocks - const defaultLocation = makeGeolocationPosition({}); const defaultLocationUri = 'geo:54.001927,-8.253491;u=1'; // beacon_info events @@ -245,7 +243,7 @@ describe('OwnBeaconStore', () => { expect(mockClient.sendEvent).not.toHaveBeenCalled(); }); - it('does geolocation and sends location immediatley when user has live beacons', async () => { + it('does geolocation and sends location immediately when user has live beacons', async () => { localStorageGetSpy.mockReturnValue(JSON.stringify([ alicesRoom1BeaconInfo.getId(), alicesRoom2BeaconInfo.getId(), @@ -261,12 +259,12 @@ describe('OwnBeaconStore', () => { expect(mockClient.sendEvent).toHaveBeenCalledWith( room1Id, M_BEACON.name, - makeBeaconContent(defaultLocationUri, defaultLocation.timestamp, alicesRoom1BeaconInfo.getId()), + makeBeaconContent(defaultLocationUri, now, alicesRoom1BeaconInfo.getId()), ); expect(mockClient.sendEvent).toHaveBeenCalledWith( room2Id, M_BEACON.name, - makeBeaconContent(defaultLocationUri, defaultLocation.timestamp, alicesRoom2BeaconInfo.getId()), + makeBeaconContent(defaultLocationUri, now, alicesRoom2BeaconInfo.getId()), ); }); }); diff --git a/test/utils/beacon/geolocation-test.ts b/test/utils/beacon/geolocation-test.ts index f28c3748383..9b64105e622 100644 --- a/test/utils/beacon/geolocation-test.ts +++ b/test/utils/beacon/geolocation-test.ts @@ -34,11 +34,16 @@ describe('geolocation utilities', () => { let geolocation; const defaultPosition = makeGeolocationPosition({}); + // 14.03.2022 16:15 + const now = 1647270879403; + beforeEach(() => { geolocation = mockGeolocation(); + jest.spyOn(Date, 'now').mockReturnValue(now); }); afterEach(() => { + jest.spyOn(Date, 'now').mockRestore(); jest.spyOn(logger, 'error').mockRestore(); }); @@ -136,7 +141,7 @@ describe('geolocation utilities', () => { describe('mapGeolocationPositionToTimedGeo()', () => { it('maps geolocation position correctly', () => { expect(mapGeolocationPositionToTimedGeo(defaultPosition)).toEqual({ - timestamp: 1647256791840, geoUri: 'geo:54.001927,-8.253491;u=1', + timestamp: now, geoUri: 'geo:54.001927,-8.253491;u=1', }); }); });