void () { final Pair<ConsentOptions, MemoryIOBackend> data = createConsentOptions("", JSON_CONSENTS_DATA); final ConsentOptions options = data.getFirst(); final MemoryIOBackend storage = data.getSecond(); { final Pair<List<Consent>, Boolean> beforeConfirm = options.getConsents(); assertTrue("Consents should require confirmation", beforeConfirm.getSecond()); assertEquals(2, beforeConfirm.getFirst().size()); checkStorage(storage, JSON_CONSENTS_DATA, "", ""); final Consent consentBeforeUpgrade = lookupConsent(CONSENT_ID_USAGE_STATS, beforeConfirm.getFirst()); assertNotNull(consentBeforeUpgrade); assertEquals(Version.fromString("1.0"), consentBeforeUpgrade.getVersion()); assertFalse(consentBeforeUpgrade.isAccepted()); assertEquals(ConsentOptions.Permission.UNDEFINED, options.isSendingUsageStatsAllowed()); // confirm options.setConsents(beforeConfirm.getFirst()); } // after-confirmation state { final Pair<List<Consent>, Boolean> afterConfirm = options.getConsents(); assertFalse("Consents should NOT require confirmation", afterConfirm.getSecond()); assertEquals(2, afterConfirm.getFirst().size()); assertEquals(JSON_CONSENTS_DATA, storage.myBundled); assertEquals("", storage.myDefaults); assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed)); assertEquals(ConsentOptions.Permission.NO, options.isSendingUsageStatsAllowed()); } // updates from server { options.applyServerUpdates(JSON_MAJOR_UPGRADE_CONSENTS_DATA); final Pair<List<Consent>, Boolean> afterUpdate = options.getConsents(); assertTrue("Consents should require confirmation", afterUpdate.getSecond()); assertEquals(2, afterUpdate.getFirst().size()); assertEquals(JSON_CONSENTS_DATA, storage.myBundled); assertFalse("The storage should contain non-empty default consents", StringUtil.isEmpty(storage.myDefaults)); assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed)); final Consent consentAfterUpgrade = lookupConsent(CONSENT_ID_USAGE_STATS, afterUpdate.getFirst()); assertNotNull(consentAfterUpgrade); assertEquals(Version.fromString("2.0"), consentAfterUpgrade.getVersion()); assertFalse(consentAfterUpgrade.isAccepted()); // although default value is now 'true', the last accepted value should be returned assertEquals(ConsentOptions.Permission.NO, options.isSendingUsageStatsAllowed()); // older confirmed value should be returned until consent is re-confirmed // second confirmation final List<Consent> toAccept = new ArrayList<>(); for (Consent consent : afterUpdate.getFirst()) { if (CONSENT_ID_USAGE_STATS.equals(consent.getId())) { toAccept.add(consent.derive(true)); } else { toAccept.add(consent); } } options.setConsents(toAccept); } { final Pair<List<Consent>, Boolean> afterSecondConfirm = options.getConsents(); assertFalse("Consents should NOT require confirmation", afterSecondConfirm.getSecond()); assertEquals(2, afterSecondConfirm.getFirst().size()); assertEquals(JSON_CONSENTS_DATA, storage.myBundled); assertFalse("The storage should contain non-empty default consents", StringUtil.isEmpty(storage.myDefaults)); assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed)); final Consent consentAfterSecondConfirm = lookupConsent(CONSENT_ID_USAGE_STATS, afterSecondConfirm.getFirst()); assertNotNull(consentAfterSecondConfirm); assertEquals(Version.fromString("2.0"), consentAfterSecondConfirm.getVersion()); assertTrue(consentAfterSecondConfirm.isAccepted()); assertEquals(ConsentOptions.Permission.YES, options.isSendingUsageStatsAllowed()); } }