diff --git a/www/__mocks__/cordovaMocks.ts b/www/__mocks__/cordovaMocks.ts index c8f4b4c0f..c00377120 100644 --- a/www/__mocks__/cordovaMocks.ts +++ b/www/__mocks__/cordovaMocks.ts @@ -29,6 +29,9 @@ export const mockFile = () => { "applicationStorageDirectory" : "../path/to/app/storage/directory"}; } +//for consent document +const _storage = {}; + export const mockBEMUserCache = () => { const _cache = {}; const messages = []; @@ -92,9 +95,37 @@ export const mockBEMUserCache = () => { rs(messages.filter(m => m.key == key).map(m => m.value)); }, 100) ); + }, + getDocument: (key: string, withMetadata?: boolean) => { + return new Promise((rs, rj) => + setTimeout(() => { + rs(_storage[key]); + }, 100) + ); + }, + isEmptyDoc: (doc) => { + if (doc == undefined) { return true } + let string = doc.toString(); + if (string.length == 0) { + return true; + } else { + return false; + } } } window['cordova'] ||= {}; window['cordova'].plugins ||= {}; window['cordova'].plugins.BEMUserCache = mockBEMUserCache; } + +export const mockBEMDataCollection = () => { + const mockBEMDataCollection = { + markConsented: (consentDoc) => { + setTimeout(() => { + _storage['config/consent'] = consentDoc; + }, 100) + } + } + window['cordova'] ||= {}; + window['cordova'].plugins.BEMDataCollection = mockBEMDataCollection; +} diff --git a/www/__tests__/startprefs.test.ts b/www/__tests__/startprefs.test.ts new file mode 100644 index 000000000..1e62e7b5e --- /dev/null +++ b/www/__tests__/startprefs.test.ts @@ -0,0 +1,24 @@ +import { markConsented, isConsented, readConsentState, getConsentDocument } from '../js/splash/startprefs'; + +import { mockBEMUserCache, mockBEMDataCollection } from "../__mocks__/cordovaMocks"; +import { mockLogger } from "../__mocks__/globalMocks"; + +mockBEMUserCache(); +mockBEMDataCollection(); +mockLogger(); + +global.fetch = (url: string) => new Promise((rs, rj) => { + setTimeout(() => rs({ + json: () => new Promise((rs, rj) => { + let myJSON = { "emSensorDataCollectionProtocol": { "protocol_id": "2014-04-6267", "approval_date": "2016-07-14" } }; + setTimeout(() => rs(myJSON), 100); + }) + })); +}) as any; + +it('checks state of consent before and after marking consent', async () => { + expect(await readConsentState().then(isConsented)).toBeFalsy(); + let marked = await markConsented(); + expect(await readConsentState().then(isConsented)).toBeTruthy(); + expect(await getConsentDocument()).toEqual({"approval_date": "2016-07-14", "protocol_id": "2014-04-6267"}); +}); \ No newline at end of file diff --git a/www/i18n/en.json b/www/i18n/en.json index 9217339f7..4909e4503 100644 --- a/www/i18n/en.json +++ b/www/i18n/en.json @@ -64,9 +64,10 @@ "confirm": "Confirm", "user-data-erased": "User data erased.", "consent-not-found": "Consent for data collection not found, consent now?", + "no-consent-logout": "Consent for data collection not found, please save your opcode, log out, and log back in with the same opcode. Note that you won't get any personalized stats until you do!", "no-consent-message": "OK! Note that you won't get any personalized stats until you do!", "consent-found": "Consent found!", - "consented-to": "Consented to protocol {{protocol_id}}, {{approval_date}}", + "consented-to": "Consented to protocol last updated on {{approval_date}}", "consented-ok": "OK", "qrcode": "My OPcode", "qrcode-share-title": "You can save your OPcode to login easily in the future!" diff --git a/www/index.js b/www/index.js index 0a0c63708..78d29cf7a 100644 --- a/www/index.js +++ b/www/index.js @@ -5,7 +5,6 @@ import 'leaflet/dist/leaflet.css'; import './js/ngApp.js'; import './js/splash/referral.js'; -import './js/splash/startprefs.js'; import './js/splash/pushnotify.js'; import './js/splash/storedevicesettings.js'; import './js/splash/localnotify.js'; diff --git a/www/js/App.tsx b/www/js/App.tsx index 3c6c8bec9..b1806a5cc 100644 --- a/www/js/App.tsx +++ b/www/js/App.tsx @@ -31,8 +31,6 @@ const App = () => { const { colors } = useTheme(); const { t } = useTranslation(); - const StartPrefs = getAngularService('StartPrefs'); - const routes = useMemo(() => { const showMetrics = appConfig?.survey_info?.['trip-labels'] == 'MULTILABEL'; return showMetrics ? defaultRoutes(t) : defaultRoutes(t).filter(r => r.key != 'metrics'); diff --git a/www/js/control/ProfileSettings.jsx b/www/js/control/ProfileSettings.jsx index 7678cae6b..e2e6d04fd 100644 --- a/www/js/control/ProfileSettings.jsx +++ b/www/js/control/ProfileSettings.jsx @@ -25,6 +25,8 @@ import { AppContext } from "../App"; import { shareQR } from "../components/QrCode"; import { storageClear } from "../plugin/storage"; import { getAppVersion } from "../plugin/clientStats"; +import { getConsentDocument } from "../splash/startprefs"; +import { logDebug } from "../plugin/logger"; //any pure functions can go outside const ProfileSettings = () => { @@ -39,7 +41,6 @@ const ProfileSettings = () => { const EmailHelper = getAngularService('EmailHelper'); const NotificationScheduler = getAngularService('NotificationScheduler'); const ControlHelper = getAngularService('ControlHelper'); - const StartPrefs = getAngularService('StartPrefs'); //functions that come directly from an Angular service const editCollectionConfig = () => setEditCollectionVis(true); @@ -314,8 +315,9 @@ const ProfileSettings = () => { //in ProfileSettings in DevZone (above two functions are helpers) async function checkConsent() { - StartPrefs.getConsentDocument().then(function(resultDoc){ + getConsentDocument().then(function(resultDoc){ setConsentDoc(resultDoc); + logDebug("In profile settings, consent doc found", resultDoc); if (resultDoc == null) { setNoConsentVis(true); } else { @@ -482,17 +484,13 @@ const ProfileSettings = () => { onDismiss={()=>setNoConsentVis(false)} style={settingStyles.dialog(colors.elevation.level3)}> {t('general-settings.consent-not-found')} + + {t('general-settings.no-consent-logout')} + - @@ -503,7 +501,7 @@ const ProfileSettings = () => { setConsentVis(false)} style={settingStyles.dialog(colors.elevation.level3)}> - {t('general-settings.consented-to', {protocol_id: consentDoc.protocol_id, approval_date: consentDoc.approval_date})} + {t('general-settings.consented-to', {approval_date: consentDoc.approval_date})}