Skip to content

Commit

Permalink
add tests for TimelineContext
Browse files Browse the repository at this point in the history
Basic test for loading composite trips into the timeline.
Mocks a unified query response with 3 composite trips.
Then checks to make sure those 3 trips can be rendered in a dummy component by reading 'timelineMap'.

in timelineHelper.ts, do not attempt to unpack server data that doesn't exist (added because start_confirmed_place and end_confirmed_place don't exist on the dummy trips used for testing)

In cordovaMocks.ts, resolve with [] instead of returning undefined
  • Loading branch information
JGreenlee committed Apr 2, 2024
1 parent dfd3376 commit 4ca6e3f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 7 deletions.
4 changes: 3 additions & 1 deletion www/__mocks__/cordovaMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export const mockBEMUserCache = (config?) => {
}, 100),
);
} else {
return undefined;
return Promise.resolve([]);
}
},
};
Expand Down Expand Up @@ -229,6 +229,8 @@ export const mockBEMServerCom = () => {
}, 100);
},
};
window['cordova'] ||= {};
window['cordova'].plugins ||= {};
window['cordova'].plugins.BEMServerComm = mockBEMServerCom;
};

Expand Down
74 changes: 74 additions & 0 deletions www/__tests__/TimelineContext.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useEffect } from 'react';
import { View, Text } from 'react-native';
import { act, render, screen, waitFor } from '@testing-library/react-native';
import { useTimelineContext } from '../js/TimelineContext';
import { mockLogger } from '../__mocks__/globalMocks';
import { mockBEMServerCom, mockBEMUserCache } from '../__mocks__/cordovaMocks';

mockLogger();
mockBEMUserCache();

jest.mock('../js/services/commHelper', () => ({
getPipelineRangeTs: jest.fn(() => Promise.resolve({ start_ts: 1, end_ts: 10 })),
getRawEntries: jest.fn((key_list, _, __) => {
let phone_data: any[] = [];
if (key_list.includes('analysis/composite_trip')) {
phone_data = [
{
_id: { $oid: 'trip1' },
metadata: { write_ts: 1, origin_key: 'analysis/confirmed_trip' },
data: { start_ts: 1, end_ts: 2 },
},
{
_id: { $oid: 'trip2' },
metadata: { write_ts: 2, origin_key: 'analysis/confirmed_trip' },
data: { start_ts: 3, end_ts: 4 },
},
{
_id: { $oid: 'trip3' },
metadata: { write_ts: 3, origin_key: 'analysis/confirmed_trip' },
data: { start_ts: 5, end_ts: 6 },
},
];
}
return Promise.resolve({ phone_data });
}),
fetchUrlCached: jest.fn(() => Promise.resolve(null)),
}));

// Mock useAppConfig default export
jest.mock('../js/useAppConfig', () => {
return jest.fn(() => ({ intro: {} }));
});

const TimelineContextTestComponent = () => {
const { timelineMap, setDateRange } = useTimelineContext();

useEffect(() => {
// setDateRange(['2021-01-01', '2021-01-07']);
}, []);

if (!timelineMap) return null;

console.debug('timelineMap', timelineMap);

return (
<View testID="timeline-entries">
{[...timelineMap.values()].map((entry, i) => (
<Text key={i}>{'entry ID: ' + entry._id.$oid}</Text>
))}
</View>
);
};

describe('TimelineContext', () => {
it('renders correctly', async () => {
render(<TimelineContextTestComponent />);
await waitFor(() => {
// make sure timeline entries are rendered
expect(screen.getByTestId('timeline-entries')).toBeTruthy();
// make sure number of Text components matches number of timeline entries
expect(screen.getAllByText(/entry ID:/).length).toBe(3);
});
});
});
13 changes: 7 additions & 6 deletions www/js/diary/timelineHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,13 @@ function locations2GeojsonTrajectory(
// DB entries retrieved from the server have '_id', 'metadata', and 'data' fields.
// This function returns a shallow copy of the obj, which flattens the
// 'data' field into the top level, while also including '_id' and 'metadata.key'
const unpackServerData = (obj: BEMData<any>) => ({
...obj.data,
_id: obj._id,
key: obj.metadata.key,
origin_key: obj.metadata.origin_key || obj.metadata.key,
});
const unpackServerData = (obj: BEMData<any>) =>
obj && {
...obj.data,
_id: obj._id,
key: obj.metadata.key,
origin_key: obj.metadata.origin_key || obj.metadata.key,
};

export function readAllCompositeTrips(startTs: number, endTs: number) {
const readPromises = [getRawEntries(['analysis/composite_trip'], startTs, endTs, 'data.end_ts')];
Expand Down

0 comments on commit 4ca6e3f

Please sign in to comment.