diff --git a/App.test.tsx b/App.test.tsx
index 17f96c9..38a1d72 100644
--- a/App.test.tsx
+++ b/App.test.tsx
@@ -4,6 +4,7 @@ import Home from './src/screens/Home';
import * as Location from 'expo-location';
import {getOrCreateRealtimeRecord} from './src/lib/data';
import {startRide} from './src/lib/ride';
+import {RideModel, RealtimeDataModel} from './src/database';
it('App renders correctly for signed user.', async () => {
// check the home pages renders
@@ -17,6 +18,7 @@ it('App renders correctly for signed user.', async () => {
it('App registers location service and logs to db with distance calculated with active ride', async () => {
let tree!: ReactTestRenderer;
+ let record!: RealtimeDataModel;
await renderer.act(() => {
tree = renderer.create();
});
@@ -44,7 +46,9 @@ it('App registers location service and logs to db with distance calculated with
Location._emitLocation(newLocation);
});
- let record = await getOrCreateRealtimeRecord();
+ await renderer.act(async () => {
+ record = await getOrCreateRealtimeRecord();
+ });
expect(record.distance).toBe(0);
expect(record.latitude).toBe(newLocation.coords.latitude);
expect(record.longitude).toBe(newLocation.coords.longitude);
@@ -79,8 +83,80 @@ it('App registers location service and logs to db with distance calculated with
tree.unmount();
});
+it('MovingTime correctly handles locations recorded before the ride start.', async () => {
+ let tree!: ReactTestRenderer;
+ let ride!: RideModel;
+ let record!: RealtimeDataModel;
+
+ const coords = {
+ accuracy: 110,
+ latitude: 41.4027,
+ longitude: 2.1743,
+ heading: 10,
+ altitude: 41.0,
+ altitudeAccuracy: 0,
+ };
+
+ await renderer.act(async () => {
+ tree = renderer.create();
+ });
+
+ tree.root.findByType(Home);
+
+ await renderer.act(async () => {
+ record = await getOrCreateRealtimeRecord();
+ });
+
+ const startTime = Date.now();
+
+ // Trigger a location update
+ // before starting ride
+ await renderer.act(async () => {
+ // @ts-ignore
+ // this is a mock method
+ await Location._emitLocation({
+ timestamp: startTime - 5000,
+ mocked: true,
+ coords: {
+ ...coords,
+ speed: 1,
+ },
+ });
+ });
+
+ await renderer.act(async () => {
+ // ensure there is an active ride
+ ride = await startRide();
+ // @ts-ignore
+ // this is a mock method
+ });
+
+ // Trigger a location update
+ // during ride
+ await renderer.act(async () => {
+ // @ts-ignore
+ // this is a mock method
+ await Location._emitLocation({
+ timestamp: ride.startedAt.getTime() + 1000,
+ mocked: true,
+ coords: {
+ ...coords,
+ speed: 1,
+ },
+ });
+ });
+
+ // now ensure record.movingTime is back to zero.
+ // and doesn't take the location recorded
+ // before ride start into account.
+ expect(record.ride!.id).toBeTruthy();
+ expect(record.movingTime).toBe(1000);
+});
+
it('App registers location service and logs to db with movingTime calculated with active ride', async () => {
let tree!: ReactTestRenderer;
+ let record!: RealtimeDataModel;
+
const coords = {
accuracy: 110,
latitude: 41.4027,
@@ -96,7 +172,6 @@ it('App registers location service and logs to db with movingTime calculated wit
tree.root.findByType(Home);
- // Trigger a location update.
await renderer.act(async () => {
// ensure there is an active ride
await startRide();
@@ -104,7 +179,9 @@ it('App registers location service and logs to db with movingTime calculated wit
// this is a mock method
});
- const record = await getOrCreateRealtimeRecord();
+ await renderer.act(async () => {
+ record = await getOrCreateRealtimeRecord();
+ });
expect(record.movingTime).toBe(0);
expect(record.lastLocationAt).toBe(null);
const startTime = Date.now();
@@ -138,7 +215,6 @@ it('App registers location service and logs to db with movingTime calculated wit
});
});
- // check that
expect(record.movingTime).toBe(1000);
// Trigger a location update.
@@ -155,7 +231,6 @@ it('App registers location service and logs to db with movingTime calculated wit
});
});
- // check that
expect(record.movingTime).toBe(2000);
// Trigger a location update.
@@ -176,12 +251,13 @@ it('App registers location service and logs to db with movingTime calculated wit
// because speed is == 0
expect(record.movingTime).toBe(2000);
- // Now check for record in realtime db.
tree.unmount();
});
it('App registers location service and logs to db with without movingTime calculated with inactive ride', async () => {
let tree!: ReactTestRenderer;
+ let record!: RealtimeDataModel;
+
const coords = {
accuracy: 110,
latitude: 41.4027,
@@ -197,7 +273,9 @@ it('App registers location service and logs to db with without movingTime calcul
tree.root.findByType(Home);
- const record = await getOrCreateRealtimeRecord();
+ await renderer.act(async () => {
+ record = await getOrCreateRealtimeRecord();
+ });
expect(record.movingTime).toBe(0);
expect(record.lastLocationAt).toBe(null);
@@ -240,6 +318,8 @@ it('App registers location service and logs to db with without movingTime calcul
it('App registers location service and logs to db without distance calculated with inactive ride', async () => {
let tree!: ReactTestRenderer;
+ let record!: RealtimeDataModel;
+
await renderer.act(() => {
tree = renderer.create();
});
@@ -265,8 +345,9 @@ it('App registers location service and logs to db without distance calculated wi
Location._emitLocation(newLocation);
});
- let record = await getOrCreateRealtimeRecord();
-
+ await renderer.act(async () => {
+ record = await getOrCreateRealtimeRecord();
+ });
expect(record.distance).toBe(0);
expect(record.latitude).toBe(newLocation.coords.latitude);
expect(record.longitude).toBe(newLocation.coords.longitude);
diff --git a/setup.ts b/setup.ts
index 84c99dc..4b7a998 100644
--- a/setup.ts
+++ b/setup.ts
@@ -1,5 +1,6 @@
import 'react-native-gesture-handler/jestSetup';
+jest.useFakeTimers();
jest.mock(
'@nozbe/watermelondb/adapters/sqlite/makeDispatcher/index.native.js',
() => {
diff --git a/src/components/MapFollowLocation/index.test.tsx b/src/components/MapFollowLocation/index.test.tsx
index 581a245..a4d094e 100644
--- a/src/components/MapFollowLocation/index.test.tsx
+++ b/src/components/MapFollowLocation/index.test.tsx
@@ -8,7 +8,7 @@ jest.mock('@react-navigation/elements', () => ({
it('map renders correctly', async () => {
// not much to test on this.
let tree!: ReactTestRenderer;
- await renderer.act(() => {
+ renderer.act(() => {
tree = renderer.create();
});
tree.root.findByType(MapWidget);
diff --git a/src/lib/data/movingTime.ts b/src/lib/data/movingTime.ts
index 3411039..c2585fb 100644
--- a/src/lib/data/movingTime.ts
+++ b/src/lib/data/movingTime.ts
@@ -2,10 +2,10 @@ import {LocationObject} from 'expo-location';
import {RealtimeDataModel} from '../../database';
import constants from '../../constants';
-export function accumulateMovingTime(
+export async function accumulateMovingTime(
lastRealTimeRecord: RealtimeDataModel,
currentLocation: LocationObject,
-): number {
+): Promise {
// If we don't have a speed we return the previous
// if we have stopped we return the previous value
if (
@@ -13,9 +13,17 @@ export function accumulateMovingTime(
currentLocation.coords.speed < constants.movingSpeed ||
!lastRealTimeRecord.lastLocationAt
) {
+ // we need to ensure that the
return lastRealTimeRecord.movingTime;
}
+ const ride = await lastRealTimeRecord.ride?.fetch();
+
+ if (ride && lastRealTimeRecord.lastLocationAt < ride?.startedAt) {
+ // check if we have a ride but this is the first location
+ return currentLocation.timestamp - ride.startedAt.getTime();
+ }
+
// we are moving and have speed.
// we should increment the movingTime
const diff =
diff --git a/src/lib/data/realtime.ts b/src/lib/data/realtime.ts
index e99e279..7fb7436 100644
--- a/src/lib/data/realtime.ts
+++ b/src/lib/data/realtime.ts
@@ -57,7 +57,7 @@ export async function onLocation(
: 0;
const movingTime = realtimeData.ride?.id
- ? accumulateMovingTime(realtimeData, location)
+ ? await accumulateMovingTime(realtimeData, location)
: 0;
console.log('accumulated distance: ', distance);