Skip to content
This repository has been archived by the owner on Jun 24, 2022. It is now read-only.

Commit

Permalink
Merge pull request #564 from cds-snc/hotfix/lastCheckPeriod
Browse files Browse the repository at this point in the history
Fix ExposureNotificationService is out of synced with upstream
  • Loading branch information
henrytao-me authored Jul 9, 2020
2 parents f5182b7 + 623e3ce commit d598211
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 33 deletions.
4 changes: 2 additions & 2 deletions src/components/LastCheckedDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export interface LastCheckedDisplayProps {
export const LastCheckedDisplay = ({textDark}: LastCheckedDisplayProps) => {
const [i18n] = useI18n();
const [exposureStatus] = useExposureStatus();
if (!exposureStatus.lastCheckedTimestamp) return null;
if (!exposureStatus.lastChecked?.timestamp) return null;

const lastCheckedDate = new Date(exposureStatus.lastCheckedTimestamp);
const lastCheckedDate = new Date(exposureStatus.lastChecked.timestamp);
const daysDiff = daysFromNow(lastCheckedDate);
const hoursDiff = hoursFromNow(lastCheckedDate);
const minutesDiff = Math.max(minutesFromNow(lastCheckedDate), 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,32 @@ describe('ExposureNotificationService', () => {
});

service.exposureStatus.append({
lastCheckedTimestamp: new OriginalDate('2020-05-19T06:10:00+0000').getTime(),
lastCheckedPeriod: periodSinceEpoch(new OriginalDate('2020-05-19T06:10:00+0000'), HOURS_PER_PERIOD),
lastChecked: {
timestamp: new OriginalDate('2020-05-19T06:10:00+0000').getTime(),
period: periodSinceEpoch(new OriginalDate('2020-05-19T06:10:00+0000'), HOURS_PER_PERIOD),
},
});
await service.updateExposureStatus();
expect(server.retrieveDiagnosisKeys).toHaveBeenCalledTimes(0);

server.retrieveDiagnosisKeys.mockClear();

service.exposureStatus.append({
lastCheckedTimestamp: new OriginalDate('2020-05-18T05:10:00+0000').getTime(),
lastCheckedPeriod: periodSinceEpoch(new OriginalDate('2020-05-18T05:10:00+0000'), HOURS_PER_PERIOD),
lastChecked: {
timestamp: new OriginalDate('2020-05-18T05:10:00+0000').getTime(),
period: periodSinceEpoch(new OriginalDate('2020-05-18T05:10:00+0000'), HOURS_PER_PERIOD),
},
});
await service.updateExposureStatus();
expect(server.retrieveDiagnosisKeys).toHaveBeenCalledTimes(1);

server.retrieveDiagnosisKeys.mockClear();

service.exposureStatus.append({
lastCheckedTimestamp: new OriginalDate('2020-05-17T23:10:00+0000').getTime(),
lastCheckedPeriod: periodSinceEpoch(new OriginalDate('2020-05-17T23:10:00+0000'), HOURS_PER_PERIOD),
lastChecked: {
timestamp: new OriginalDate('2020-05-17T23:10:00+0000').getTime(),
period: periodSinceEpoch(new OriginalDate('2020-05-17T23:10:00+0000'), HOURS_PER_PERIOD),
},
});
await service.updateExposureStatus();
expect(server.retrieveDiagnosisKeys).toHaveBeenCalledTimes(2);
Expand All @@ -132,8 +138,10 @@ describe('ExposureNotificationService', () => {
});

service.exposureStatus.append({
lastCheckedTimestamp: new OriginalDate('2020-05-18T04:10:00+0000').getTime(),
lastCheckedPeriod: periodSinceEpoch(new OriginalDate('2020-05-18T04:10:00+0000'), HOURS_PER_PERIOD),
lastChecked: {
timestamp: new OriginalDate('2020-05-18T04:10:00+0000').getTime(),
period: periodSinceEpoch(new OriginalDate('2020-05-18T04:10:00+0000'), HOURS_PER_PERIOD),
},
});

const currentPeriod = periodSinceEpoch(currentDatetime, HOURS_PER_PERIOD);
Expand All @@ -146,8 +154,10 @@ describe('ExposureNotificationService', () => {
expect(storage.setItem).toHaveBeenCalledWith(
EXPOSURE_STATUS,
expect.jsonStringContaining({
lastCheckedTimestamp: currentDatetime.getTime(),
lastCheckedPeriod: currentPeriod - 1,
lastChecked: {
timestamp: currentDatetime.getTime(),
period: currentPeriod - 1,
},
}),
);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {Platform} from 'react-native';
import ExposureNotification, {
ExposureConfiguration,
ExposureSummary,
Status as SystemStatus,
ExposureConfiguration,
} from 'bridge/ExposureNotification';
import PushNotification from 'bridge/PushNotification';
import {addDays, daysBetween, periodSinceEpoch} from 'shared/date-fns';
Expand All @@ -15,7 +15,7 @@ import {BackendInterface, SubmissionKeySet} from '../BackendService';
import defaultExposureConfiguration from './DefaultExposureConfiguration.json';

const SUBMISSION_AUTH_KEYS = 'submissionAuthKeys';
const EXPOSURE_CONFIGURATION = 'exposure-configuration';
const EXPOSURE_CONFIGURATION = 'exposureConfiguration';

const SECURE_OPTIONS = {
sharedPreferencesName: 'covidShieldSharedPreferences',
Expand All @@ -34,23 +34,29 @@ export {SystemStatus};
export type ExposureStatus =
| {
type: 'monitoring';
lastCheckedPeriod?: number;
lastCheckedTimestamp?: number;
lastChecked?: {
period: number;
timestamp: number;
};
}
| {
type: 'exposed';
summary: ExposureSummary;
lastCheckedPeriod?: number;
lastCheckedTimestamp?: number;
lastChecked?: {
period: number;
timestamp: number;
};
}
| {
type: 'diagnosed';
needsSubmission: boolean;
submissionLastCompletedAt?: number;
cycleStartsAt: number;
cycleEndsAt: number;
lastCheckedPeriod?: number;
lastCheckedTimestamp?: number;
lastChecked?: {
period: number;
timestamp: number;
};
};

export interface PersistencyProvider {
Expand Down Expand Up @@ -196,7 +202,7 @@ export class ExposureNotificationService {
* If the exposureConfiguration is not available from the server for some reason,
* try and use a previously stored configuration, or use the default configuration bundled with the app.
*/
async getAlternateExposureConfiguration(): Promise<ExposureConfiguration> {
private async getAlternateExposureConfiguration(): Promise<ExposureConfiguration> {
try {
const exposureConfigurationStr = await this.secureStorage.getItem(
EXPOSURE_CONFIGURATION,
Expand Down Expand Up @@ -244,12 +250,8 @@ export class ExposureNotificationService {
): AsyncGenerator<{keysFileUrl: string; period: number} | null> {
const runningDate = new Date();

let lastCheckedPeriod =
const lastCheckedPeriod =
_lastCheckedPeriod || periodSinceEpoch(addDays(runningDate, -EXPOSURE_NOTIFICATION_CYCLE), HOURS_PER_PERIOD);
if (TEST_MODE) {
lastCheckedPeriod = periodSinceEpoch(addDays(runningDate, -EXPOSURE_NOTIFICATION_CYCLE), HOURS_PER_PERIOD);
}

let runningPeriod = periodSinceEpoch(runningDate, HOURS_PER_PERIOD);

while (runningPeriod > lastCheckedPeriod) {
Expand Down Expand Up @@ -282,9 +284,15 @@ export class ExposureNotificationService {
exposureConfiguration = await this.getAlternateExposureConfiguration();
}

const finalize = async (status: Partial<ExposureStatus> = {}) => {
const finalize = async (status: Partial<ExposureStatus> = {}, lastCheckedPeriod = 0) => {
const timestamp = new Date().getTime();
this.exposureStatus.append({...status, lastCheckedTimestamp: timestamp});
this.exposureStatus.append({
...status,
lastChecked: {
timestamp,
period: lastCheckedPeriod,
},
});
};

const currentStatus = this.exposureStatus.get();
Expand All @@ -306,15 +314,21 @@ export class ExposureNotificationService {
}

const keysFileUrls: string[] = [];
const generator = this.keysSinceLastFetch(currentStatus.lastCheckedPeriod);
let lastCheckedPeriod = currentStatus.lastCheckedPeriod;
const generator = this.keysSinceLastFetch(currentStatus.lastChecked?.period);
let lastCheckedPeriod = currentStatus.lastChecked?.period;
while (true) {
const {value, done} = await generator.next();
if (done) break;
if (!value) continue;
const {keysFileUrl, period} = value;
keysFileUrls.push(keysFileUrl);

// Temporarily disable lastCheckPeriod
// Ref https://github.com/cds-snc/covid-shield-server/pull/158
if (TEST_MODE) {
continue;
}

// Temporarily disable persisting lastCheckPeriod on Android
// Ref https://github.com/cds-snc/covid-shield-mobile/issues/453
if (Platform.OS !== 'android') {
Expand All @@ -325,12 +339,18 @@ export class ExposureNotificationService {
try {
const summary = await this.exposureNotification.detectExposure(exposureConfiguration, keysFileUrls);
if (summary.matchedKeyCount > 0) {
return finalize({type: 'exposed', summary, lastCheckedPeriod});
return finalize(
{
type: 'exposed',
summary,
},
lastCheckedPeriod,
);
}
} catch (error) {
console.log('>>> detectExposure', error);
console.log('>>> DetectExposure', error);
}

return finalize({lastCheckedPeriod});
return finalize({}, lastCheckedPeriod);
}
}

0 comments on commit d598211

Please sign in to comment.