diff --git a/www/__tests__/metricsHelper.test.ts b/www/__tests__/metricsHelper.test.ts index 07fe64736..a6afc7d63 100644 --- a/www/__tests__/metricsHelper.test.ts +++ b/www/__tests__/metricsHelper.test.ts @@ -1,10 +1,20 @@ +import { DateTime } from 'luxon'; import { calculatePercentChange, formatDate, formatDateRangeOfDays, getLabelsForDay, getUniqueLabelsForDays, + secondsToHours, + secondsToMinutes, segmentDaysByWeeks, + metricToValue, + tsForDayOfMetricData, + valueForFieldOnDay, + generateSummaryFromData, + isCustomLabels, + isAllCustom, + isOnFoot, } from '../js/metrics/metricsHelper'; import { DayOfMetricData } from '../js/metrics/metricsTypes'; @@ -27,9 +37,17 @@ describe('metricsHelper', () => { }); }); - // secondsToMinutes + describe('secondsToMinutes', () => { + it("should convert from seconds to minutes properly", () => { + expect(secondsToMinutes(360)).toEqual(6); + }); + }); - // secondsToHours + describe('secondsToHours', () => { + it("should convert from seconds to hours properly", () => { + expect(secondsToHours(3600)).toEqual(1); + }); + }); describe('segmentDaysByWeeks', () => { const days1 = [ @@ -73,4 +91,149 @@ describe('metricsHelper', () => { expect(formatDateRangeOfDays(days1)).toEqual('1/1 - 1/4'); }); }); + + describe('metricToValue', () => { + const metric = { + walking: 10, + nUsers: 5, + }; + it('returns correct value for user population', () => { + const result = metricToValue('user', metric, 'walking'); + expect(result).toBe(10); + }); + + it('returns correct value for aggregate population', () => { + const result = metricToValue('aggregate', metric, 'walking'); + expect(result).toBe(2); + }); + }); + + describe('isOnFoot', () => { + it('returns true for on foot mode', () => { + const result = isOnFoot('WALKING'); + expect(result).toBe(true); + }); + + it('returns false for non on foot mode', () => { + const result = isOnFoot('DRIVING'); + expect(result).toBe(false); + }); + }); + + describe('calculatePercentChange', () => { + it('calculates percent change correctly for low and high values', () => { + const pastWeekRange = { low: 10, high: 30 }; + const previousWeekRange = { low: 5, high: 10 }; + const result = calculatePercentChange(pastWeekRange, previousWeekRange); + expect(result.low).toBe(100); + expect(result.high).toBe(200); + }); + }); + + describe('tsForDayOfMetricData', () => { + const mockDay = { + date: '2024-05-28T12:00:00Z', + nUsers: 10, + }; + let _datesTsCache; + beforeEach(() => { + _datesTsCache = {}; + }); + + it('calculates timestamp for a given day', () => { + const expectedTimestamp = DateTime.fromISO(mockDay.date).toSeconds(); + const result = tsForDayOfMetricData(mockDay); + expect(result).toBe(expectedTimestamp); + }); + + it('caches the timestamp for subsequent calls with the same day', () => { + const firstResult = tsForDayOfMetricData(mockDay); + const secondResult = tsForDayOfMetricData(mockDay); + expect(secondResult).toBe(firstResult); + }); + }); + + describe('valueForFieldOnDay', () => { + const mockDay = { + date: '2024-05-28T12:00:00Z', + nUsers: 10, + field_key: 'example_value' + }; + + it('returns the value for a specified field and key', () => { + const result = valueForFieldOnDay(mockDay, 'field', 'key'); + expect(result).toBe('example_value'); + }); + }); + + describe('generateSummaryFromData', () => { + const modeMap = [ + { key: 'mode1', values: [['value1', 10], ['value2', 20]] }, + { key: 'mode2', values: [['value3', 30], ['value4', 40]] }, + ]; + it('returns summary with sum for non-speed metric', () => { + const metric = 'some_metric'; + const expectedResult = [ + { key: 'mode1', values: 30 }, + { key: 'mode2', values: 70 }, + ]; + const result = generateSummaryFromData(modeMap, metric); + expect(result).toEqual(expectedResult); + }); + + it('returns summary with average for speed metric', () => { + const metric = 'mean_speed'; + const expectedResult = [ + { key: 'mode1', values: 15 }, + { key: 'mode2', values: 35 }, + ]; + const result = generateSummaryFromData(modeMap, metric); + expect(result).toEqual(expectedResult); + }); + }); + + describe('isCustomLabels', () => { + const modeMap = [ + { key: 'label_mode1', values: [['value1', 10], ['value2', 20]] }, + { key: 'label_mode2', values: [['value3', 30], ['value4', 40]] }, + ]; + + it('returns true for all custom labels', () => { + const result = isCustomLabels(modeMap); + expect(result).toBe(true); + }); + + it('returns true for all sensed labels', () => { + const result = isCustomLabels(modeMap); + expect(result).toBe(true); + }); + + it('returns false for mixed custom and sensed labels', () => { + const result = isCustomLabels(modeMap); + expect(result).toBe(false); + }); + }); + + describe('isAllCustom', () => { + it('returns true when all keys are custom', () => { + const isSensedKeys = [false, false, false]; + const isCustomKeys = [true, true, true]; + const result = isAllCustom(isSensedKeys, isCustomKeys); + expect(result).toBe(true); + }); + + it('returns false when all keys are sensed', () => { + const isSensedKeys = [true, true, true]; + const isCustomKeys = [false, false, false]; + const result = isAllCustom(isSensedKeys, isCustomKeys); + expect(result).toBe(false); + }); + + it('returns undefined for mixed custom and sensed keys', () => { + const isSensedKeys = [true, false, true]; + const isCustomKeys = [false, true, false]; + const result = isAllCustom(isSensedKeys, isCustomKeys); + expect(result).toBe(undefined); + }); + }); });