Skip to content

Commit

Permalink
Merge branch 'service_rewrite_2023' into UnifiedDataLoader-rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
shankari authored Nov 10, 2023
2 parents bafdb47 + db08c76 commit 99534bf
Show file tree
Hide file tree
Showing 17 changed files with 1,111 additions and 878 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/prettier.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: prettier
on:
pull_request:

jobs:
run-prettier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npx prettier --check www

3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ www/dist
www/manual_lib
www/json

# Ignore all HTML files:
**/*.html

# This is the pattern to check only www directory
# Ignore all
/*
Expand Down
251 changes: 251 additions & 0 deletions www/__tests__/inputMatcher.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
import {
fmtTs,
printUserInput,
validUserInputForDraftTrip,
validUserInputForTimelineEntry,
getNotDeletedCandidates,
getUserInputForTrip,
getAdditionsForTimelineEntry,
getUniqueEntries,
} from '../js/survey/inputMatcher';
import { TlEntry, UserInput } from '../js/types/diaryTypes';

describe('input-matcher', () => {
let userTrip: UserInput;
let trip: TlEntry;

beforeEach(() => {
/*
Create a valid userTrip and trip object before each test case.
The trip data is from the 'real_examples' data (shankari_2015-07-22) on the server.
For some test cases, I need to generate fake data, such as labels, keys, and origin_keys.
In such cases, I referred to 'TestUserInputFakeData.py' on the server.
*/
userTrip = {
data: {
end_ts: 1437604764,
start_ts: 1437601247,
label: 'FOO',
status: 'ACTIVE',
},
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695921991,
platform: 'ios',
read_ts: 0,
key: 'manual/mode_confirm',
},
key: 'manual/place',
};
trip = {
key: 'FOO',
origin_key: 'FOO',
start_ts: 1437601000,
end_ts: 1437605000,
enter_ts: 1437605000,
exit_ts: 1437605000,
duration: 100,
getNextEntry: jest.fn(),
};

// mock Logger
window['Logger'] = { log: console.log };
});

it('tests fmtTs with valid input', () => {
const pstTime = fmtTs(1437601247.8459613, 'America/Los_Angeles');
const estTime = fmtTs(1437601247.8459613, 'America/New_York');

// Check if it contains correct year-mm-dd hr:mm
expect(pstTime).toContain('2015-07-22T14:40');
expect(estTime).toContain('2015-07-22T17:40');
});

it('tests fmtTs with invalid input', () => {
const formattedTime = fmtTs(0, '');
expect(formattedTime).toBeFalsy();
});

it('tests printUserInput prints the trip log correctly', () => {
const userTripLog = printUserInput(userTrip);
expect(userTripLog).toContain('1437604764');
expect(userTripLog).toContain('1437601247');
expect(userTripLog).toContain('FOO');
});

it('tests validUserInputForDraftTrip with valid trip input', () => {
const validTrp = {
end_ts: 1437604764,
start_ts: 1437601247,
};
const validUserInput = validUserInputForDraftTrip(validTrp, userTrip, false);
expect(validUserInput).toBeTruthy();
});

it('tests validUserInputForDraftTrip with invalid trip input', () => {
const invalidTrip = {
end_ts: 0,
start_ts: 0,
};
const invalidUserInput = validUserInputForDraftTrip(invalidTrip, userTrip, false);
expect(invalidUserInput).toBeFalsy();
});

it('tests validUserInputForTimelineEntry with valid trip object', () => {
// we need valid key and origin_key for validUserInputForTimelineEntry test
trip['key'] = 'analysis/confirmed_place';
trip['origin_key'] = 'analysis/confirmed_place';
const validTimelineEntry = validUserInputForTimelineEntry(trip, userTrip, false);
expect(validTimelineEntry).toBeTruthy();
});

it('tests validUserInputForTimelineEntry with tlEntry with invalid key and origin_key', () => {
const invalidTlEntry = trip;
const invalidTimelineEntry = validUserInputForTimelineEntry(invalidTlEntry, userTrip, false);
expect(invalidTimelineEntry).toBeFalsy();
});

it('tests validUserInputForTimelineEntry with tlEntry with invalie start & end time', () => {
const invalidTlEntry: TlEntry = {
key: 'analysis/confirmed_place',
origin_key: 'analysis/confirmed_place',
start_ts: 1,
end_ts: 1,
enter_ts: 1,
exit_ts: 1,
duration: 1,
getNextEntry: jest.fn(),
};
const invalidTimelineEntry = validUserInputForTimelineEntry(invalidTlEntry, userTrip, false);
expect(invalidTimelineEntry).toBeFalsy();
});

it('tests getNotDeletedCandidates called with 0 candidates', () => {
jest.spyOn(console, 'log');
const candidates = getNotDeletedCandidates([]);

// check if the log printed collectly with
expect(console.log).toHaveBeenCalledWith('getNotDeletedCandidates called with 0 candidates');
expect(candidates).toStrictEqual([]);
});

it('tests getNotDeletedCandidates called with multiple candidates', () => {
const activeTrip = userTrip;
const deletedTrip = {
data: {
end_ts: 1437604764,
start_ts: 1437601247,
label: 'FOO',
status: 'DELETED',
match_id: 'FOO',
},
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695921991,
platform: 'ios',
read_ts: 0,
key: 'manual/mode_confirm',
},
key: 'manual/place',
};
const candidates = [activeTrip, deletedTrip];
const validCandidates = getNotDeletedCandidates(candidates);

// check if the result has only 'ACTIVE' data
expect(validCandidates).toHaveLength(1);
expect(validCandidates[0]).toMatchObject(userTrip);
});

it('tests getUserInputForTrip with valid userInputList', () => {
const userInputWriteFirst = {
data: {
end_ts: 1437607732,
label: 'bus',
start_ts: 1437606026,
},
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695830232,
platform: 'ios',
read_ts: 0,
key: 'manual/mode_confirm',
type: 'message',
},
};
const userInputWriteSecond = {
data: {
end_ts: 1437598393,
label: 'e-bike',
start_ts: 1437596745,
},
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695838268,
platform: 'ios',
read_ts: 0,
key: 'manual/mode_confirm',
type: 'message',
},
};
const userInputWriteThird = {
data: {
end_ts: 1437604764,
label: 'e-bike',
start_ts: 1437601247,
},
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695921991,
platform: 'ios',
read_ts: 0,
key: 'manual/mode_confirm',
type: 'message',
},
};

// make the linst unsorted and then check if userInputWriteThird(latest one) is return output
const userInputList = [userInputWriteSecond, userInputWriteThird, userInputWriteFirst];
const mostRecentEntry = getUserInputForTrip(trip, {}, userInputList);
expect(mostRecentEntry).toMatchObject(userInputWriteThird);
});

it('tests getUserInputForTrip with invalid userInputList', () => {
const userInputList = undefined;
const mostRecentEntry = getUserInputForTrip(trip, {}, userInputList);
expect(mostRecentEntry).toBe(undefined);
});

it('tests getAdditionsForTimelineEntry with valid additionsList', () => {
const additionsList = new Array(5).fill(userTrip);
trip['key'] = 'analysis/confirmed_place';
trip['origin_key'] = 'analysis/confirmed_place';

// check if the result keep the all valid userTrip items
const matchingAdditions = getAdditionsForTimelineEntry(trip, additionsList);
expect(matchingAdditions).toHaveLength(5);
});

it('tests getAdditionsForTimelineEntry with invalid additionsList', () => {
const additionsList = undefined;
const matchingAdditions = getAdditionsForTimelineEntry(trip, additionsList);
expect(matchingAdditions).toMatchObject([]);
});

it('tests getUniqueEntries with valid combinedList', () => {
const combinedList = new Array(5).fill(userTrip);

// check if the result keeps only unique userTrip items
const uniqueEntires = getUniqueEntries(combinedList);
expect(uniqueEntires).toHaveLength(1);
});

it('tests getUniqueEntries with empty combinedList', () => {
const uniqueEntires = getUniqueEntries([]);
expect(uniqueEntires).toMatchObject([]);
});
});
5 changes: 5 additions & 0 deletions www/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,14 @@
"errors": {
"registration-check-token": "User registration error. Please check your token and try again.",
"not-registered-cant-contact": "User is not registered, so the server cannot be contacted.",
"while-initializing-label": "While initializing Label tab: ",
"while-populating-composite": "Error while populating composite trips",
"while-loading-another-week": "Error while loading travel of {{when}} week",
"while-loading-specific-week": "Error while loading travel for the week of {{day}}",
"while-updating-timeline": "While updating timeline: ",
"while-refreshing-label": "While refreshing Label tab: ",
"while-repopulating-entry": "While repopulating timeline entry: ",
"while-loading-metrics": "While loading metrics: ",
"while-log-messages": "While getting messages from the log ",
"while-max-index": "While getting max index "
},
Expand Down
1 change: 0 additions & 1 deletion www/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import './js/controllers.js';
import './js/services.js';
import './js/i18n-utils.js';
import './js/main.js';
import './js/survey/input-matcher.js';
import './js/survey/multilabel/multi-label-ui.js';
import './js/diary.js';
import './js/diary/services.js';
Expand Down
7 changes: 4 additions & 3 deletions www/js/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { setServerConnSettings } from './config/serverConn';
import AppStatusModal from './control/AppStatusModal';
import usePermissionStatus from './usePermissionStatus';
import { withErrorBoundary } from './plugin/ErrorBoundary';

const defaultRoutes = (t) => [
{
Expand Down Expand Up @@ -55,9 +56,9 @@ const App = () => {
}, [appConfig, t]);

const renderScene = BottomNavigation.SceneMap({
label: LabelTab,
metrics: MetricsTab,
control: ProfileSettings,
label: withErrorBoundary(LabelTab),
metrics: withErrorBoundary(MetricsTab),
control: withErrorBoundary(ProfileSettings),
});

const refreshOnboardingState = () => getPendingOnboardingState().then(setOnboardingState);
Expand Down
8 changes: 7 additions & 1 deletion www/js/components/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Chart as ChartJS, registerables } from 'chart.js';
import { Chart as ChartJSChart } from 'react-chartjs-2';
import Annotation, { AnnotationOptions, LabelPosition } from 'chartjs-plugin-annotation';
import { dedupColors, getChartHeight, darkenOrLighten } from './charting';
import { logDebug } from '../plugin/logger';

ChartJS.register(...registerables, Annotation);

Expand Down Expand Up @@ -134,6 +135,9 @@ const Chart = ({
? {}
: {
callback: (value, i) => {
logDebug(`Horizontal axis callback: i = ${i};
chartDatasets = ${JSON.stringify(chartDatasets)};
chartDatasets[0].data = ${JSON.stringify(chartDatasets[0].data)}`);
const label = chartDatasets[0].data[i].y;
if (typeof label == 'string' && label.includes('\n'))
return label.split('\n');
Expand Down Expand Up @@ -168,7 +172,9 @@ const Chart = ({
? {}
: {
callback: (value, i) => {
console.log('testing vertical', chartData, i);
logDebug(`Vertical axis callback: i = ${i};
chartDatasets = ${JSON.stringify(chartDatasets)};
chartDatasets[0].data = ${JSON.stringify(chartDatasets[0].data)}`);
const label = chartDatasets[0].data[i].x;
if (typeof label == 'string' && label.includes('\n'))
return label.split('\n');
Expand Down
Loading

0 comments on commit 99534bf

Please sign in to comment.