Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 40 additions & 1 deletion __tests__/fixtures/daily-data-providers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as dailyDataAggregateFunctions from '../../src/helpers/daily-data-providers/daily-data/daily-data-aggregate';
import { AggregateFunction } from '../../src/helpers/daily-data-providers/daily-data/daily-data-aggregate';
import * as dailyDataQueryFunctions from '../../src/helpers/daily-data-providers/daily-data/daily-data-query';
import { DailyData, DailyDataDateFunction, DailyDataV2, DailyDataValueFunction, DeviceDataV2QueryFilters } from '../../src/helpers/daily-data-providers/daily-data';
import * as dailyDataResultFunctions from '../../src/helpers/daily-data-providers/daily-data/daily-data-result';
Expand Down Expand Up @@ -108,6 +110,43 @@ export function setupDailyDataV2(
);
}

export function setupAggregateDailyData(
expectedNamespace: DeviceDataV2Namespace,
expectedType: string,
expectedStartDate: Date,
expectedEndDate: Date,
expectedAggregateFn: AggregateFunction,
result: DailyDataQueryResult,
optionalScaleFactor?: number
): void {
jest.spyOn(dailyDataAggregateFunctions, 'queryAggregateDailyData').mockImplementation(
(
actualNamespace: DeviceDataV2Namespace,
actualType: string,
actualStartDate: Date,
actualEndDate: Date,
actualAggregateFn: AggregateFunction,
actualScaleFactor: number | undefined
): Promise<DailyDataQueryResult> => {
if (actualNamespace !== expectedNamespace) return Promise.reject();
if (actualType !== expectedType) return Promise.reject();
if (!isEqual(actualStartDate, expectedStartDate)) return Promise.reject();
if (!isEqual(actualEndDate, expectedEndDate)) return Promise.reject();
if (actualAggregateFn !== expectedAggregateFn) return Promise.reject();
if (actualScaleFactor !== optionalScaleFactor) return Promise.reject();
return Promise.resolve(result);
}
);
}

export function setupMinValueResult(
dailyData: DailyData | DailyDataV2,
result: DailyDataQueryResult,
valueFunctionEvaluator?: (valueFn: DailyDataValueFunction | undefined) => boolean
): void {
setupResult('buildMinValueResult', dailyData, result, valueFunctionEvaluator ?? (valueFn => !valueFn));
}

export function setupMaxValueResult(
dailyData: DailyData | DailyDataV2,
result: DailyDataQueryResult,
Expand Down Expand Up @@ -141,7 +180,7 @@ export function setupMostRecentValueResult(
}

function setupResult(
functionName: 'buildMaxValueResult' | 'buildTotalValueResult' | 'buildAverageValueResult' | 'buildMostRecentValueResult',
functionName: 'buildMinValueResult' | 'buildMaxValueResult' | 'buildTotalValueResult' | 'buildAverageValueResult' | 'buildMostRecentValueResult',
expectedDailyData: DailyData | DailyDataV2,
result: DailyDataQueryResult,
valueFunctionEvaluator: (valueFn: DailyDataValueFunction | undefined) => boolean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { describe, expect, it } from '@jest/globals';
import { sampleEndDate, sampleResult, sampleStartDate, setupAggregateDailyData } from '../../fixtures/daily-data-providers';
import appleHealthBloodGlucose from '../../../src/helpers/daily-data-providers/apple-health-blood-glucose';

describe('Daily Data Provider - Apple Health Blood Glucose', () => {
it('Should query for aggregate daily data and return the average values keyed by date.', async () => {
setupAggregateDailyData('AppleHealth', 'Blood Glucose', sampleStartDate, sampleEndDate, 'avg', sampleResult);
expect(await appleHealthBloodGlucose(sampleStartDate, sampleEndDate)).toBe(sampleResult);
});
});
Original file line number Diff line number Diff line change
@@ -1,50 +1,37 @@
import { describe, expect, it } from '@jest/globals';
import { sampleEndDate, sampleStartDate, setupDailyData, startDateFunctionEvaluator } from '../../fixtures/daily-data-providers';
import { describe, expect, it, jest } from '@jest/globals';
import { sampleEndDate, sampleStartDate, setupDailyDataProvider } from '../../fixtures/daily-data-providers';
import getDayKey from '../../../src/helpers/get-day-key';
import { DailyData } from '../../../src/helpers/daily-data-providers/daily-data';
import { DeviceDataPoint } from '@careevolution/mydatahelps-js';
import appleHealthHeartRateRange from '../../../src/helpers/daily-data-providers/apple-health-heart-rate-range';
import { appleHealthMaxHeartRateDataProvider, appleHealthMinHeartRateDataProvider } from '../../../src/helpers/daily-data-providers/index';

jest.mock('../../../src/helpers/daily-data-providers/index');

describe('Daily Data Provider - Apple Health Heart Rate Range', () => {
it('Should query for daily data and build a result keyed by start date.', async () => {
const dailyData: DailyData = {
[getDayKey(sampleStartDate)]: [
{ type: 'HourlyMaximumHeartRate', value: '120' } as DeviceDataPoint,
{ type: 'HourlyMinimumHeartRate', value: '65' } as DeviceDataPoint,
{ type: 'HourlyMaximumHeartRate', value: '100' } as DeviceDataPoint,
{ type: 'HourlyMinimumHeartRate', value: '60' } as DeviceDataPoint
]
};
setupDailyData('AppleHealth', ['HourlyMaximumHeartRate', 'HourlyMinimumHeartRate'], sampleStartDate, sampleEndDate, startDateFunctionEvaluator, dailyData);
it('Should query for daily data and compute ranges by subtracting min from max for each day.', async () => {
const dayKey = getDayKey(sampleStartDate);
setupDailyDataProvider(appleHealthMinHeartRateDataProvider as jest.Mock, sampleStartDate, sampleEndDate, { [dayKey]: 60 });
setupDailyDataProvider(appleHealthMaxHeartRateDataProvider as jest.Mock, sampleStartDate, sampleEndDate, { [dayKey]: 110 });

const result = await appleHealthHeartRateRange(sampleStartDate, sampleEndDate);

expect(Object.keys(result)).toHaveLength(1);
expect(result[getDayKey(sampleStartDate)]).toBe(60);
expect(result[dayKey]).toBe(50);
});

it('Should exclude days that do not have a minimum value.', async () => {
const dailyData: DailyData = {
[getDayKey(sampleStartDate)]: [
{ type: 'HourlyMaximumHeartRate', value: '120' } as DeviceDataPoint,
{ type: 'HourlyMaximumHeartRate', value: '100' } as DeviceDataPoint,
]
};
setupDailyData('AppleHealth', ['HourlyMaximumHeartRate', 'HourlyMinimumHeartRate'], sampleStartDate, sampleEndDate, startDateFunctionEvaluator, dailyData);
const dayKey = getDayKey(sampleStartDate);
setupDailyDataProvider(appleHealthMinHeartRateDataProvider as jest.Mock, sampleStartDate, sampleEndDate, {});
setupDailyDataProvider(appleHealthMaxHeartRateDataProvider as jest.Mock, sampleStartDate, sampleEndDate, { [dayKey]: 110 });

const result = await appleHealthHeartRateRange(sampleStartDate, sampleEndDate);

expect(Object.keys(result)).toHaveLength(0);
});

it('Should exclude days that do not have a maximum value.', async () => {
const dailyData: DailyData = {
[getDayKey(sampleStartDate)]: [
{ type: 'HourlyMinimumHeartRate', value: '65' } as DeviceDataPoint,
{ type: 'HourlyMinimumHeartRate', value: '60' } as DeviceDataPoint
]
};
setupDailyData('AppleHealth', ['HourlyMaximumHeartRate', 'HourlyMinimumHeartRate'], sampleStartDate, sampleEndDate, startDateFunctionEvaluator, dailyData);
const dayKey = getDayKey(sampleStartDate);
setupDailyDataProvider(appleHealthMinHeartRateDataProvider as jest.Mock, sampleStartDate, sampleEndDate, { [dayKey]: 60 });
setupDailyDataProvider(appleHealthMaxHeartRateDataProvider as jest.Mock, sampleStartDate, sampleEndDate, {});

const result = await appleHealthHeartRateRange(sampleStartDate, sampleEndDate);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { describe, expect, it } from '@jest/globals';
import { sampleEndDate, sampleResult, sampleStartDate, setupAggregateDailyData } from '../../fixtures/daily-data-providers';
import appleHealthMaxBloodGlucose from '../../../src/helpers/daily-data-providers/apple-health-max-blood-glucose';

describe('Daily Data Provider - Apple Health Max Blood Glucose', () => {
it('Should query for aggregate daily data and return the maximum values keyed by date.', async () => {
setupAggregateDailyData('AppleHealth', 'Blood Glucose', sampleStartDate, sampleEndDate, 'max', sampleResult);
expect(await appleHealthMaxBloodGlucose(sampleStartDate, sampleEndDate)).toBe(sampleResult);
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { describe, expect, it } from '@jest/globals';
import { sampleDailyData, sampleEndDate, sampleResult, sampleStartDate, setupDailyData, setupMaxValueResult, startDateFunctionEvaluator } from '../../fixtures/daily-data-providers';
import { sampleEndDate, sampleResult, sampleStartDate, setupAggregateDailyData } from '../../fixtures/daily-data-providers';
import appleHealthMaxHeartRate from '../../../src/helpers/daily-data-providers/apple-health-max-heart-rate';

describe('Daily Data Provider - Apple Health Max Heart Rate', () => {
it('Should query for daily data and build a max value result keyed by start date.', async () => {
setupDailyData('AppleHealth', 'HourlyMaximumHeartRate', sampleStartDate, sampleEndDate, startDateFunctionEvaluator, sampleDailyData);
setupMaxValueResult(sampleDailyData, sampleResult);
it('Should query for aggregate daily data and return the maximum values keyed by date.', async () => {
setupAggregateDailyData('AppleHealth', 'Hourly Maximum Heart Rate', sampleStartDate, sampleEndDate, 'max', sampleResult);
expect(await appleHealthMaxHeartRate(sampleStartDate, sampleEndDate)).toBe(sampleResult);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { describe, expect, it } from '@jest/globals';
import { sampleEndDate, sampleResult, sampleStartDate, setupAggregateDailyData } from '../../fixtures/daily-data-providers';
import appleHealthMinBloodGlucose from '../../../src/helpers/daily-data-providers/apple-health-min-blood-glucose';

describe('Daily Data Provider - Apple Health Min Blood Glucose', () => {
it('Should query for aggregate daily data and return the minimum values keyed by date.', async () => {
setupAggregateDailyData('AppleHealth', 'Blood Glucose', sampleStartDate, sampleEndDate, 'min', sampleResult);
expect(await appleHealthMinBloodGlucose(sampleStartDate, sampleEndDate)).toBe(sampleResult);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { describe, expect, it } from '@jest/globals';
import { sampleEndDate, sampleResult, sampleStartDate, setupAggregateDailyData } from '../../fixtures/daily-data-providers';
import appleHealthMinHeartRate from '../../../src/helpers/daily-data-providers/apple-health-min-heart-rate';

describe('Daily Data Provider - Apple Health Min Heart Rate', () => {
it('Should query for aggregate daily data and return the minimum values keyed by date.', async () => {
setupAggregateDailyData('AppleHealth', 'Hourly Minimum Heart Rate', sampleStartDate, sampleEndDate, 'min', sampleResult);
expect(await appleHealthMinHeartRate(sampleStartDate, sampleEndDate)).toBe(sampleResult);
});
});
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { describe, expect, it } from '@jest/globals';
import { sampleEndDate, sampleResult, sampleStartDate, sampleTimeRanges, setupDailyDataPoints, setupDailyTimeRanges, setupMinutesResult } from '../../fixtures/daily-data-providers';
import { DeviceDataPoint } from '@careevolution/mydatahelps-js';
import { sampleEndDate, sampleResult, sampleStartDate, sampleTimeRanges, setupDailyDataPointsV2, setupDailyTimeRanges, setupMinutesResult } from '../../fixtures/daily-data-providers';
import { DeviceDataV2Point } from '@careevolution/mydatahelps-js';
import * as mindfulTherapyFunctions from '../../../src/helpers/daily-data-providers/common-mindful-and-therapy';
import appleHealthMindfulMinutes from '../../../src/helpers/daily-data-providers/apple-health-mindful-minutes';

describe('Daily Data Provider - Apple Health Mindful Minutes', () => {
it('Should query for daily data points, filter out therapy data points, and build a minutes result.', async () => {
const mindfulDataPoint: DeviceDataPoint = { identifier: 'Mindful' } as DeviceDataPoint;
const therapyDataPoint: DeviceDataPoint = { identifier: 'Therapy' } as DeviceDataPoint;
const mindfulDataPoint = { identifier: 'Mindful' } as DeviceDataV2Point;
const therapyDataPoint = { identifier: 'Therapy' } as DeviceDataV2Point;
jest.spyOn(mindfulTherapyFunctions, 'isSilverCloudCbtDataPoint').mockImplementation(dataPoint => dataPoint === therapyDataPoint);

setupDailyDataPoints('AppleHealth', 'MindfulSession', sampleStartDate, sampleEndDate, undefined, [mindfulDataPoint, therapyDataPoint]);
setupDailyDataPointsV2('AppleHealth', 'Mindful Sessions', sampleStartDate, sampleEndDate, undefined, undefined, [mindfulDataPoint, therapyDataPoint]);
setupDailyTimeRanges([mindfulDataPoint], sampleTimeRanges);
setupMinutesResult(sampleStartDate, sampleEndDate, sampleTimeRanges, sampleResult);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { describe, expect, it } from '@jest/globals';
import { sampleDailyData, sampleEndDate, sampleResult, sampleStartDate, setupAverageValueResult, setupDailyData, startDateFunctionEvaluator } from '../../fixtures/daily-data-providers';
import { sampleEndDate, sampleResult, sampleStartDate, setupAggregateDailyData } from '../../fixtures/daily-data-providers';
import appleHealthRestingHeartRate from '../../../src/helpers/daily-data-providers/apple-health-resting-heart-rate';

describe('Daily Data Provider - Apple Health Resting Heart Rate', () => {
it('Should query for daily data and build an average value result keyed by start date.', async () => {
setupDailyData('AppleHealth', 'RestingHeartRate', sampleStartDate, sampleEndDate, startDateFunctionEvaluator, sampleDailyData);
setupAverageValueResult(sampleDailyData, sampleResult);
it('Should query for aggregate daily data and return the average values keyed by date.', async () => {
setupAggregateDailyData('AppleHealth', 'Resting Heart Rate', sampleStartDate, sampleEndDate, 'avg', sampleResult);
expect(await appleHealthRestingHeartRate(sampleStartDate, sampleEndDate)).toBe(sampleResult);
});
});

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, test } from '@jest/globals';
import { sampleEndDate, sampleResult, sampleStartDate, sampleTimeRanges, setupDailyDataPoints, setupDailyTimeRanges, setupMinutesResult } from '../../fixtures/daily-data-providers';
import { DeviceDataPoint } from '@careevolution/mydatahelps-js';
import { sampleEndDate, sampleResult, sampleStartDate, sampleTimeRanges, setupDailyDataPointsV2, setupDailyTimeRanges, setupMinutesResult } from '../../fixtures/daily-data-providers';
import { DeviceDataV2Point } from '@careevolution/mydatahelps-js';
import { asleepCoreTime, asleepDeepTime, asleepRemTime, asleepTime, inBedTime } from '../../../src/helpers/daily-data-providers/apple-health-sleep';

describe('Daily Data Provider - Apple Health Sleep', () => {
Expand All @@ -11,12 +11,12 @@ describe('Daily Data Provider - Apple Health Sleep', () => {
{ title: 'Deep', sleepFunction: asleepDeepTime, sleepTypes: ['AsleepDeep'] },
{ title: 'Total', sleepFunction: asleepTime, sleepTypes: ['AsleepCore', 'AsleepREM', 'AsleepDeep', 'Asleep'] }
])('$title - Should query for daily data points, filter by sleep type, and build a minutes result.', async ({ sleepFunction, sleepTypes }) => {
const dataPoints: DeviceDataPoint[] = [{ value: 'Other' } as DeviceDataPoint];
const dataPoints = [{ value: 'Other' } as DeviceDataV2Point];
sleepTypes.forEach(sleepType => {
dataPoints.push({ value: sleepType } as DeviceDataPoint);
dataPoints.push({ value: sleepType } as DeviceDataV2Point);
});

setupDailyDataPoints('AppleHealth', 'SleepAnalysisInterval', sampleStartDate, sampleEndDate, undefined, dataPoints);
setupDailyDataPointsV2('AppleHealth', 'Sleep Analysis', sampleStartDate, sampleEndDate, undefined, undefined, dataPoints);
setupDailyTimeRanges(dataPoints.slice(1), sampleTimeRanges, -6);
setupMinutesResult(sampleStartDate, sampleEndDate, sampleTimeRanges, sampleResult);

Expand Down
Loading
Loading