Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

📊 🦶 Metrics Services Rewrites #1098

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
de49924
convert metrics services
Nov 8, 2023
70f7238
display message instead of error
Nov 8, 2023
5108352
reduce naming confusion
Nov 8, 2023
9118133
write footprinthelper tests
Nov 9, 2023
2cdd212
fix formatting
Nov 9, 2023
1a734f7
remove unused import
Nov 9, 2023
1d7bf5b
remove country-specific
Nov 9, 2023
1eec588
remove stale references
Nov 9, 2023
6102d62
remove dataset setting
Nov 9, 2023
b075738
increase message readability
Nov 9, 2023
ec4abff
ensure initialization of footprints
Nov 9, 2023
7820646
remove old MET code
Nov 9, 2023
7ebcc94
add tests for highest footprint
Nov 9, 2023
3943053
write tests for metHelper
Nov 9, 2023
7436502
custom dataset helper tests
Nov 9, 2023
974ac3a
remove carbon fallback
Nov 9, 2023
8c28737
remove unused code
Nov 9, 2023
deb7104
add docstrings
Nov 10, 2023
9153a60
resolve merge conflicts
Nov 10, 2023
9340297
working to debug dashboard
Nov 10, 2023
47daa3e
Merge remote-tracking branch 'upstream/service_rewrite_2023' into met…
Nov 10, 2023
acc8022
lift dataset initialization
Nov 10, 2023
a587440
Merge remote-tracking branch 'upstream/service_rewrite_2023' into met…
Nov 10, 2023
fa22ee4
remove use of `rootScope` in getAggregateData
JGreenlee Nov 10, 2023
14a4c0d
Merge branch 'service_rewrite_2023' of https://github.com/e-mission/e…
JGreenlee Nov 13, 2023
6cf3a80
patch for WSOD on dashboard
Nov 15, 2023
1693409
tweak to account for same mode both weeks
Nov 15, 2023
1f495e2
clean up bugfix
Nov 17, 2023
ef3bd59
renamed file
Nov 17, 2023
df8ec72
input Params -> labelOptions
Nov 17, 2023
c160788
footprint will always be custom
Nov 17, 2023
4c1a4a6
rename the metDatasets file
Nov 17, 2023
b655f4a
name updates, just one dataset
Nov 17, 2023
dec322f
prettier in Chart.tsx
Nov 17, 2023
a299574
remove debugging log statements
Nov 17, 2023
6272fb0
logDebug statements
Nov 17, 2023
6233af5
logWarn instead of console.warn
Nov 17, 2023
5918b6b
Rename CustomMetricsHelper.ts to customMetricsHelper.ts
Abby-Wheelis Nov 17, 2023
125faff
cleaning up customMetrics
Nov 17, 2023
e626f6e
clarify "in vehicle" calculations
Nov 17, 2023
b040691
all mets are custom
Nov 17, 2023
51f6ece
await instead of timeout
Nov 19, 2023
3dee26f
Use expect.any(Type) for stricter testing
Nov 19, 2023
9a5753b
code style cleanup
JGreenlee Nov 20, 2023
bc2543b
Merge branch 'service_rewrite_2023' into metrics-services-rewrite
shankari Dec 3, 2023
1006165
Merge branch 'service_rewrite_2023' into metrics-services-rewrite
shankari Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 208 additions & 0 deletions www/__mocks__/fakeLabels.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
{
"MODE": [
{
"value": "walk",
"baseMode": "WALKING",
"met_equivalent": "WALKING",
"kgCo2PerKm": 0
},
{
"value": "e-bike",
"baseMode": "E_BIKE",
"met": {
"ALL": {
"range": [0, -1],
"mets": 4.9
}
},
"kgCo2PerKm": 0.00728
},
{
"value": "bike",
"baseMode": "BICYCLING",
"met_equivalent": "BICYCLING",
"kgCo2PerKm": 0
},
{
"value": "bikeshare",
"baseMode": "BICYCLING",
"met_equivalent": "BICYCLING",
"kgCo2PerKm": 0
},
{
"value": "scootershare",
"baseMode": "E_SCOOTER",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.00894
},
{
"value": "drove_alone",
"baseMode": "CAR",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.22031
},
{
"value": "shared_ride",
"baseMode": "CAR",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.11015
},
{
"value": "hybrid_drove_alone",
"baseMode": "CAR",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.127
},
{
"value": "hybrid_shared_ride",
"baseMode": "CAR",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.0635
},
{
"value": "e_car_drove_alone",
"baseMode": "E_CAR",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.08216
},
{
"value": "e_car_shared_ride",
"baseMode": "E_CAR",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.04108
},
{
"value": "taxi",
"baseMode": "TAXI",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.30741
},
{
"value": "bus",
"baseMode": "BUS",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.20727
},
{
"value": "train",
"baseMode": "TRAIN",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.12256
},
{
"value": "free_shuttle",
"baseMode": "BUS",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.20727
},
{
"value": "air",
"baseMode": "AIR",
"met_equivalent": "IN_VEHICLE",
"kgCo2PerKm": 0.09975
},
{
"value": "not_a_trip",
"baseMode": "UNKNOWN",
"met_equivalent": "UNKNOWN",
"kgCo2PerKm": 0
},
{
"value": "other",
"baseMode": "OTHER",
"met_equivalent": "UNKNOWN",
"kgCo2PerKm": 0
}
],
"PURPOSE": [
{
"value": "home"
},
{
"value": "work"
},
{
"value": "at_work"
},
{
"value": "school"
},
{
"value": "transit_transfer"
},
{
"value": "shopping"
},
{
"value": "meal"
},
{
"value": "pick_drop_person"
},
{
"value": "pick_drop_item"
},
{
"value": "personal_med"
},
{
"value": "access_recreation"
},
{
"value": "exercise"
},
{
"value": "entertainment"
},
{
"value": "religious"
},
{
"value": "other"
}
],
"REPLACED_MODE": [
{
"value": "no_travel"
},
{
"value": "walk"
},
{
"value": "bike"
},
{
"value": "bikeshare"
},
{
"value": "scootershare"
},
{
"value": "drove_alone"
},
{
"value": "shared_ride"
},
{
"value": "e_car_drove_alone"
},
{
"value": "e_car_shared_ride"
},
{
"value": "taxi"
},
{
"value": "bus"
},
{
"value": "train"
},
{
"value": "free_shuttle"
},
{
"value": "other"
}
]
}
51 changes: 51 additions & 0 deletions www/__tests__/customMetricsHelper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { getConfig } from '../js/config/dynamicConfig';
import {
getCustomFootprint,
getCustomMETs,
initCustomDatasetHelper,
} from '../js/metrics/customMetricsHelper';
import { mockBEMUserCache } from '../__mocks__/cordovaMocks';
import { mockLogger } from '../__mocks__/globalMocks';
import fakeLabels from '../__mocks__/fakeLabels.json';

mockBEMUserCache();
mockLogger();

global.fetch = (url: string) =>
new Promise((rs, rj) => {
setTimeout(() =>
rs({
text: () =>
new Promise((rs, rj) => {
let myJSON = JSON.stringify(fakeLabels);
setTimeout(() => rs(myJSON), 100);
}),
}),
);
}) as any;

it('gets the custom mets', async () => {
const appConfig = await getConfig();
await initCustomDatasetHelper(appConfig);
expect(getCustomMETs()).toMatchObject({
walk: expect.any(Object),
bike: expect.any(Object),
bikeshare: expect.any(Object),
Comment on lines +31 to +33
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason you are not checking against the actual numbers? These are going to be the same numbers as in fakeLabels.json, correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I probably did not do this originally, because I was mostly trying to test the keys. The default keys are WALKING, BICYCLING, etc, while the custom keys are walk, bike, etc.

I updated the footprint test, since that is a single value, but I have not updated the MET testing, since those objects are complex (some are speed dependent, etc), and taking the time to copy them over from fakeLabels.json seems like it would do more to test the test than the code, but I'll add a note about checking the keys!

'e-bike': expect.any(Object),
scootershare: expect.any(Object),
drove_alone: expect.any(Object),
});
});

it('gets the custom footprint', async () => {
const appConfig = await getConfig();
await initCustomDatasetHelper(appConfig);
expect(getCustomFootprint()).toMatchObject({
walk: expect.any(Number),
bike: expect.any(Number),
bikeshare: expect.any(Number),
'e-bike': expect.any(Number),
scootershare: expect.any(Number),
drove_alone: expect.any(Number),
});
});
63 changes: 63 additions & 0 deletions www/__tests__/footprintHelper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { initCustomDatasetHelper } from '../js/metrics/customMetricsHelper';
import {
clearHighestFootprint,
getFootprintForMetrics,
getHighestFootprint,
getHighestFootprintForDistance,
} from '../js/metrics/footprintHelper';
import { getConfig } from '../js/config/dynamicConfig';
import { mockBEMUserCache } from '../__mocks__/cordovaMocks';
import { mockLogger } from '../__mocks__/globalMocks';
import fakeLabels from '../__mocks__/fakeLabels.json';

mockBEMUserCache();
mockLogger();

global.fetch = (url: string) =>
new Promise((rs, rj) => {
setTimeout(() =>
rs({
text: () =>
new Promise((rs, rj) => {
let myJSON = JSON.stringify(fakeLabels);
setTimeout(() => rs(myJSON), 100);
}),
}),
);
}) as any;

beforeEach(() => {
clearHighestFootprint();
});

const custom_metrics = [
{ key: 'walk', values: 3000 },
{ key: 'bike', values: 6500 },
{ key: 'drove_alone', values: 10000 },
{ key: 'scootershare', values: 25000 },
{ key: 'unicycle', values: 5000 },
];

it('gets footprint for metrics (custom, fallback 0)', async () => {
const appConfig = await getConfig();
await initCustomDatasetHelper(appConfig);
expect(getFootprintForMetrics(custom_metrics, 0)).toBe(2.4266);
});

it('gets footprint for metrics (custom, fallback 0.1)', async () => {
const appConfig = await getConfig();
await initCustomDatasetHelper(appConfig);
expect(getFootprintForMetrics(custom_metrics, 0.1)).toBe(2.4266 + 0.5);
});

it('gets the highest footprint from the dataset, custom', async () => {
const appConfig = await getConfig();
await initCustomDatasetHelper(appConfig);
expect(getHighestFootprint()).toBe(0.30741);
});

it('gets the highest footprint for distance, custom', async () => {
const appConfig = await getConfig();
await initCustomDatasetHelper(appConfig);
expect(getHighestFootprintForDistance(12345)).toBe(0.30741 * (12345 / 1000));
});
40 changes: 40 additions & 0 deletions www/__tests__/metHelper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { getMet } from '../js/metrics/metHelper';
import { mockBEMUserCache } from '../__mocks__/cordovaMocks';
import { mockLogger } from '../__mocks__/globalMocks';
import fakeLabels from '../__mocks__/fakeLabels.json';
import { getConfig } from '../js/config/dynamicConfig';
import { initCustomDatasetHelper } from '../js/metrics/customMetricsHelper';

mockBEMUserCache();
mockLogger();

global.fetch = (url: string) =>
new Promise((rs, rj) => {
setTimeout(() =>
rs({
text: () =>
new Promise((rs, rj) => {
let myJSON = JSON.stringify(fakeLabels);
setTimeout(() => rs(myJSON), 100);
}),
}),
);
}) as any;

it('gets met for mode and speed', () => {
expect(getMet('WALKING', 1.47523, 0)).toBe(4.3);
expect(getMet('BICYCLING', 4.5, 0)).toBe(6.8);
expect(getMet('UNICYCLE', 100, 0)).toBe(0);
expect(getMet('CAR', 25, 1)).toBe(0);
});

it('gets custom met for mode and speed', async () => {
const appConfig = await getConfig();
await initCustomDatasetHelper(appConfig);
expect(getMet('walk', 1.47523, 0)).toBe(4.3);
expect(getMet('bike', 4.5, 0)).toBe(6.8);
expect(getMet('unicycle', 100, 0)).toBe(0);
expect(getMet('drove_alone', 25, 1)).toBe(0);
expect(getMet('e-bike', 6, 1)).toBe(4.9);
expect(getMet('e-bike', 12, 1)).toBe(4.9);
});
2 changes: 0 additions & 2 deletions www/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,4 @@ import './js/i18n-utils.js';
import './js/main.js';
import './js/diary.js';
import './js/diary/services.js';
import './js/metrics-factory.js';
import './js/metrics-mappings.js';
import './js/plugin/logger.ts';
2 changes: 2 additions & 0 deletions www/js/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { initPushNotify } from './splash/pushNotifySettings';
import { initStoreDeviceSettings } from './splash/storeDeviceSettings';
import { initRemoteNotifyHandler } from './splash/remoteNotifyHandler';
import { withErrorBoundary } from './plugin/ErrorBoundary';
import { initCustomDatasetHelper } from './metrics/customMetricsHelper';

const defaultRoutes = (t) => [
{
Expand Down Expand Up @@ -77,6 +78,7 @@ const App = () => {
initPushNotify();
initStoreDeviceSettings();
initRemoteNotifyHandler();
initCustomDatasetHelper(appConfig);
}, [appConfig]);

const appContextValue = {
Expand Down
Loading
Loading