Skip to content

Commit

Permalink
Merge branch 'service_rewrite_2023' into appium-setting
Browse files Browse the repository at this point in the history
  • Loading branch information
jiji14 committed Nov 16, 2023
2 parents 0f0930b + e0d892f commit 25bfdd5
Show file tree
Hide file tree
Showing 92 changed files with 2,815 additions and 1,976 deletions.
53 changes: 53 additions & 0 deletions www/__mocks__/cordovaMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const mockBEMUserCache = () => {
return new Promise<void>((rs, rj) =>
setTimeout(() => {
for (let p in _cache) delete _cache[p];
for (let doc in _storage) delete _storage[doc];
rs();
}, 100),
);
Expand Down Expand Up @@ -129,7 +130,59 @@ export const mockBEMDataCollection = () => {
_storage['config/consent'] = consentDoc;
}, 100);
},
getConfig: () => {
return new Promise<any>((rs, rj) => {
setTimeout(() => {
rs({ ios_use_remote_push_for_sync: true });
}, 100);
});
},
handleSilentPush: () => {
return new Promise<void>((rs, rj) =>
setTimeout(() => {
rs();
}, 100),
);
},
};
window['cordova'] ||= {};
window['cordova'].plugins.BEMDataCollection = mockBEMDataCollection;
};

export const mockBEMServerCom = () => {
const mockBEMServerCom = {
postUserPersonalData: (actionString, typeString, updateDoc, rs, rj) => {
setTimeout(() => {
console.log('set in mock', updateDoc);
_storage['user_data'] = updateDoc;
rs();
}, 100);
},

getUserPersonalData: (actionString, rs, rj) => {
setTimeout(() => {
rs(_storage['user_data']);
}, 100);
},
};
window['cordova'].plugins.BEMServerComm = mockBEMServerCom;
};

let _url_stash = '';

export const mockInAppBrowser = () => {
const mockInAppBrowser = {
open: (url: string, mode: string, options: {}) => {
_url_stash = url;
},
};
window['cordova'].InAppBrowser = mockInAppBrowser;
};

export const getURL = () => {
return _url_stash;
};

export const clearURL = () => {
_url_stash = '';
};
16 changes: 16 additions & 0 deletions www/__mocks__/globalMocks.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
export const mockLogger = () => {
window['Logger'] = { log: console.log };
};

let alerts = [];

export const mockAlert = () => {
window['alert'] = (message) => {
alerts.push(message);
};
};

export const clearAlerts = () => {
alerts = [];
};

export const getAlerts = () => {
return alerts;
};
33 changes: 33 additions & 0 deletions www/__mocks__/pushNotificationMocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
let notifSettings;
let onList: any = {};
let called = null;

export const mockPushNotification = () => {
window['PushNotification'] = {
init: (settings: Object) => {
notifSettings = settings;
return {
on: (event: string, callback: Function) => {
onList[event] = callback;
},
finish: (content: any, errorFcn: Function, notID: any) => {
called = notID;
},
};
},
};
};

export const clearNotifMock = function () {
notifSettings = {};
onList = {};
called = null;
};

export const getOnList = function () {
return onList;
};

export const getCalled = function () {
return called;
};
10 changes: 6 additions & 4 deletions www/__tests__/LoadMoreButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ describe('LoadMoreButton', () => {
await waitFor(() => {
expect(screen.getByTestId('load-button')).toBeTruthy();
});
});
}, 15000);

it('calls onPressFn when clicked', () => {
it('calls onPressFn when clicked', async () => {
const mockFn = jest.fn();
const { getByTestId } = render(<LoadMoreButton onPressFn={mockFn}>{}</LoadMoreButton>);
const loadButton = getByTestId('load-button');
fireEvent.press(loadButton);
expect(mockFn).toHaveBeenCalled();
});
await waitFor(() => {
expect(mockFn).toHaveBeenCalled();
});
}, 15000);
});
2 changes: 1 addition & 1 deletion www/__tests__/commHelper.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { mockLogger } from '../__mocks__/globalMocks';
import { fetchUrlCached } from '../js/commHelper';
import { fetchUrlCached } from '../js/services/commHelper';

mockLogger();

Expand Down
170 changes: 170 additions & 0 deletions www/__tests__/confirmHelper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { mockLogger } from '../__mocks__/globalMocks';
import * as CommHelper from '../js/services/commHelper';
import {
baseLabelInputDetails,
getLabelInputDetails,
getLabelOptions,
inferFinalLabels,
labelInputDetailsForTrip,
labelKeyToReadable,
labelKeyToRichMode,
labelOptionByValue,
readableLabelToKey,
verifiabilityForTrip,
} from '../js/survey/multilabel/confirmHelper';

import initializedI18next from '../js/i18nextInit';
window['i18next'] = initializedI18next;
mockLogger();

const fakeAppConfig = {
label_options: 'json/label-options.json.sample',
};
const fakeAppConfigWithModeOfStudy = {
...fakeAppConfig,
intro: {
mode_studied: 'walk',
},
};
const fakeDefaultLabelOptions = {
MODE: [
{ value: 'walk', baseMode: 'WALKING', met_equivalent: 'WALKING', kgCo2PerKm: 0 },
{ value: 'bike', baseMode: 'BICYCLING', met_equivalent: 'BICYCLING', kgCo2PerKm: 0 },
],
PURPOSE: [{ value: 'home' }, { value: 'work' }],
REPLACED_MODE: [{ value: 'no_travel' }, { value: 'walk' }, { value: 'bike' }],
translations: {
en: {
walk: 'Walk',
bike: 'Regular Bike',
no_travel: 'No travel',
home: 'Home',
work: 'To Work',
},
},
};

CommHelper.fetchUrlCached = jest
.fn()
.mockImplementation(() => JSON.stringify(fakeDefaultLabelOptions));

describe('confirmHelper', () => {
it('returns labelOptions given an appConfig', async () => {
const labelOptions = await getLabelOptions(fakeAppConfig);
expect(labelOptions).toBeTruthy();
expect(labelOptions.MODE[0].text).toEqual('Walk'); // translation is filled in
});

it('returns base labelInputDetails for a labelUserInput which does not have mode of study', () => {
const fakeLabelUserInput = {
MODE: fakeDefaultLabelOptions.MODE[1],
PURPOSE: fakeDefaultLabelOptions.PURPOSE[0],
};
const labelInputDetails = labelInputDetailsForTrip(
fakeLabelUserInput,
fakeAppConfigWithModeOfStudy,
);
expect(labelInputDetails).toEqual(baseLabelInputDetails);
});

it('returns full labelInputDetails for a labelUserInput which has the mode of study', () => {
const fakeLabelUserInput = {
MODE: fakeDefaultLabelOptions.MODE[0], // 'walk' is mode of study
PURPOSE: fakeDefaultLabelOptions.PURPOSE[0],
};
const labelInputDetails = labelInputDetailsForTrip(
fakeLabelUserInput,
fakeAppConfigWithModeOfStudy,
);
const fullLabelInputDetails = getLabelInputDetails(fakeAppConfigWithModeOfStudy);
expect(labelInputDetails).toEqual(fullLabelInputDetails);
});

it(`converts 'other' text to a label key`, () => {
const mode1 = readableLabelToKey(`Scooby Doo Mystery Machine `);
expect(mode1).toEqual('scooby_doo_mystery_machine'); // trailing space is trimmed
const mode2 = readableLabelToKey(`My niece's tricycle . `);
expect(mode2).toEqual(`my_niece's_tricycle_.`); // apostrophe and period are preserved
const purpose1 = readableLabelToKey(`Going to the store to buy 12 eggs.`);
expect(purpose1).toEqual('going_to_the_store_to_buy_12_eggs.'); // numbers are preserved
});

it(`converts keys to readable labels`, () => {
const mode1 = labelKeyToReadable(`scooby_doo_mystery_machine`);
expect(mode1).toEqual(`Scooby Doo Mystery Machine`);
const mode2 = labelKeyToReadable(`my_niece's_tricycle_.`);
expect(mode2).toEqual(`My Niece's Tricycle .`);
const purpose1 = labelKeyToReadable(`going_to_the_store_to_buy_12_eggs.`);
expect(purpose1).toEqual(`Going To The Store To Buy 12 Eggs.`);
});

it('looks up a rich mode from a label key, or humanizes the label key if there is no rich mode', () => {
const key = 'walk';
const richMode = labelKeyToRichMode(key);
expect(richMode).toEqual('Walk');
const key2 = 'scooby_doo_mystery_machine';
const readableMode = labelKeyToRichMode(key2);
expect(readableMode).toEqual('Scooby Doo Mystery Machine');
});

/* BEGIN: tests for inferences, which are loosely based on the server-side tests from
e-mission-server -> emission/tests/storageTests/TestTripQueries.py -> testExpandFinalLabels() */

it('has no final label for a trip with no user labels or inferred labels', () => {
const fakeTrip = {};
const fakeUserInput = {};
expect(inferFinalLabels(fakeTrip, fakeUserInput)).toEqual({});
expect(verifiabilityForTrip(fakeTrip, fakeUserInput)).toEqual('cannot-verify');
});

it('returns a final inference for a trip no user labels and all high-confidence inferred labels', () => {
const fakeTrip = {
inferred_labels: [{ labels: { mode_confirm: 'walk', purpose_confirm: 'exercise' }, p: 0.9 }],
};
const fakeUserInput = {};
const final = inferFinalLabels(fakeTrip, fakeUserInput);
expect(final.MODE.value).toEqual('walk');
expect(final.PURPOSE.value).toEqual('exercise');
expect(verifiabilityForTrip(fakeTrip, fakeUserInput)).toEqual('can-verify');
});

it('gives no final inference when there are user labels and no inferred labels', () => {
const fakeTrip = {};
const fakeUserInput = {
MODE: labelOptionByValue('bike', 'MODE'),
PURPOSE: labelOptionByValue('shopping', 'PURPOSE'),
};
const final = inferFinalLabels(fakeTrip, fakeUserInput);
expect(final.MODE?.value).toBeUndefined();
expect(final.PURPOSE?.value).toBeUndefined();
expect(verifiabilityForTrip(fakeTrip, fakeUserInput)).toEqual('already-verified');
});

it('still gives no final inference when there are user labels and high-confidence inferred labels', () => {
const fakeTrip = {
inferred_labels: [{ labels: { mode_confirm: 'walk', purpose_confirm: 'exercise' }, p: 0.9 }],
};
const fakeUserInput = {
MODE: labelOptionByValue('bike', 'MODE'),
PURPOSE: labelOptionByValue('shopping', 'PURPOSE'),
};
const final = inferFinalLabels(fakeTrip, fakeUserInput);
expect(final.MODE?.value).toBeUndefined();
expect(final.PURPOSE?.value).toBeUndefined();
expect(verifiabilityForTrip(fakeTrip, fakeUserInput)).toEqual('already-verified');
});

it('mixes user input labels with mixed-confidence inferred labels', () => {
const fakeTrip = {
inferred_labels: [
{ labels: { mode_confirm: 'bike', purpose_confirm: 'shopping' }, p: 0.1 },
{ labels: { mode_confirm: 'walk', purpose_confirm: 'exercise' }, p: 0.9 },
],
};
const fakeUserInput = { MODE: labelOptionByValue('bike', 'MODE') };
const final = inferFinalLabels(fakeTrip, fakeUserInput);
expect(final.MODE.value).toEqual('bike');
expect(final.PURPOSE.value).toEqual('shopping');
expect(verifiabilityForTrip(fakeTrip, fakeUserInput)).toEqual('can-verify');
});
});
24 changes: 24 additions & 0 deletions www/__tests__/customEventHandler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { publish, subscribe, unsubscribe } from '../js/customEventHandler';
import { mockLogger } from '../__mocks__/globalMocks';

mockLogger();

it('subscribes and publishes to an event', () => {
const listener = jest.fn();
subscribe('test', listener);
publish('test', 'test data');
expect(listener).toHaveBeenCalledWith(
expect.objectContaining({
type: 'test',
detail: 'test data',
}),
);
});

it('can unsubscribe', () => {
const listener = jest.fn();
subscribe('test', listener);
unsubscribe('test', listener);
publish('test', 'test data');
expect(listener).not.toHaveBeenCalled();
});
33 changes: 22 additions & 11 deletions www/__tests__/diaryHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,29 @@ it('returns true/false is multi day', () => {
expect(isMultiDay('', '2023-09-18T00:00:00-09:00')).toBeFalsy();
});

//created a fake trip with relevant sections by examining log statements
/* fake trips with 'distance' in their section summaries
('count' and 'duration' are not used bygetDetectedModes) */
let myFakeTrip = {
sections: [
{ sensed_mode_str: 'BICYCLING', distance: 6013.73657416706 },
{ sensed_mode_str: 'WALKING', distance: 715.3078629361006 },
],
};
distance: 6729.0444371031606,
cleaned_section_summary: {
// count: {...}
// duration: {...}
distance: {
BICYCLING: 6013.73657416706,
WALKING: 715.3078629361006,
},
},
} as any;

let myFakeTrip2 = {
sections: [
{ sensed_mode_str: 'BICYCLING', distance: 6013.73657416706 },
{ sensed_mode_str: 'BICYCLING', distance: 715.3078629361006 },
],
...myFakeTrip,
inferred_section_summary: {
// count: {...}
// duration: {...}
distance: {
BICYCLING: 6729.0444371031606,
},
},
};

let myFakeDetectedModes = [
Expand All @@ -82,5 +93,5 @@ let myFakeDetectedModes2 = [{ mode: 'BICYCLING', icon: 'bike', color: modeColors
it('returns the detected modes, with percentages, for a trip', () => {
expect(getDetectedModes(myFakeTrip)).toEqual(myFakeDetectedModes);
expect(getDetectedModes(myFakeTrip2)).toEqual(myFakeDetectedModes2);
expect(getDetectedModes({})).toEqual([]); // empty trip, no sections, no modes
expect(getDetectedModes({} as any)).toEqual([]); // empty trip, no sections, no modes
});
Loading

0 comments on commit 25bfdd5

Please sign in to comment.