services/datareporting/tests/xpcshell/test_policy.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 * http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 "use strict";
michael@0 5
michael@0 6 const {utils: Cu} = Components;
michael@0 7
michael@0 8 Cu.import("resource://gre/modules/Preferences.jsm");
michael@0 9 Cu.import("resource://gre/modules/services/datareporting/policy.jsm");
michael@0 10 Cu.import("resource://testing-common/services/datareporting/mocks.jsm");
michael@0 11 Cu.import("resource://gre/modules/UpdateChannel.jsm");
michael@0 12
michael@0 13 function getPolicy(name,
michael@0 14 aCurrentPolicyVersion = 1,
michael@0 15 aMinimumPolicyVersion = 1,
michael@0 16 aBranchMinimumVersionOverride) {
michael@0 17 let branch = "testing.datareporting." + name;
michael@0 18
michael@0 19 // The version prefs should not be removed on reset, so set them in the
michael@0 20 // default branch.
michael@0 21 let defaultPolicyPrefs = new Preferences({ branch: branch + ".policy."
michael@0 22 , defaultBranch: true });
michael@0 23 defaultPolicyPrefs.set("currentPolicyVersion", aCurrentPolicyVersion);
michael@0 24 defaultPolicyPrefs.set("minimumPolicyVersion", aMinimumPolicyVersion);
michael@0 25 let branchOverridePrefName = "minimumPolicyVersion.channel-" + UpdateChannel.get(false);
michael@0 26 if (aBranchMinimumVersionOverride !== undefined)
michael@0 27 defaultPolicyPrefs.set(branchOverridePrefName, aBranchMinimumVersionOverride);
michael@0 28 else
michael@0 29 defaultPolicyPrefs.reset(branchOverridePrefName);
michael@0 30
michael@0 31 let policyPrefs = new Preferences(branch + ".policy.");
michael@0 32 let healthReportPrefs = new Preferences(branch + ".healthreport.");
michael@0 33
michael@0 34 let listener = new MockPolicyListener();
michael@0 35 let policy = new DataReportingPolicy(policyPrefs, healthReportPrefs, listener);
michael@0 36
michael@0 37 return [policy, policyPrefs, healthReportPrefs, listener];
michael@0 38 }
michael@0 39
michael@0 40 function defineNow(policy, now) {
michael@0 41 print("Adjusting fake system clock to " + now);
michael@0 42 Object.defineProperty(policy, "now", {
michael@0 43 value: function customNow() {
michael@0 44 return now;
michael@0 45 },
michael@0 46 writable: true,
michael@0 47 });
michael@0 48 }
michael@0 49
michael@0 50 function run_test() {
michael@0 51 run_next_test();
michael@0 52 }
michael@0 53
michael@0 54 add_test(function test_constructor() {
michael@0 55 let policyPrefs = new Preferences("foo.bar.policy.");
michael@0 56 let hrPrefs = new Preferences("foo.bar.healthreport.");
michael@0 57 let listener = {
michael@0 58 onRequestDataUpload: function() {},
michael@0 59 onRequestRemoteDelete: function() {},
michael@0 60 onNotifyDataPolicy: function() {},
michael@0 61 };
michael@0 62
michael@0 63 let policy = new DataReportingPolicy(policyPrefs, hrPrefs, listener);
michael@0 64 do_check_true(Date.now() - policy.firstRunDate.getTime() < 1000);
michael@0 65
michael@0 66 let tomorrow = Date.now() + 24 * 60 * 60 * 1000;
michael@0 67 do_check_true(tomorrow - policy.nextDataSubmissionDate.getTime() < 1000);
michael@0 68
michael@0 69 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED);
michael@0 70
michael@0 71 run_next_test();
michael@0 72 });
michael@0 73
michael@0 74 add_test(function test_prefs() {
michael@0 75 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("prefs");
michael@0 76
michael@0 77 let now = new Date();
michael@0 78 let nowT = now.getTime();
michael@0 79
michael@0 80 policy.firstRunDate = now;
michael@0 81 do_check_eq(policyPrefs.get("firstRunTime"), nowT);
michael@0 82 do_check_eq(policy.firstRunDate.getTime(), nowT);
michael@0 83
michael@0 84 policy.dataSubmissionPolicyNotifiedDate= now;
michael@0 85 do_check_eq(policyPrefs.get("dataSubmissionPolicyNotifiedTime"), nowT);
michael@0 86 do_check_eq(policy.dataSubmissionPolicyNotifiedDate.getTime(), nowT);
michael@0 87
michael@0 88 policy.dataSubmissionPolicyResponseDate = now;
michael@0 89 do_check_eq(policyPrefs.get("dataSubmissionPolicyResponseTime"), nowT);
michael@0 90 do_check_eq(policy.dataSubmissionPolicyResponseDate.getTime(), nowT);
michael@0 91
michael@0 92 policy.dataSubmissionPolicyResponseType = "type-1";
michael@0 93 do_check_eq(policyPrefs.get("dataSubmissionPolicyResponseType"), "type-1");
michael@0 94 do_check_eq(policy.dataSubmissionPolicyResponseType, "type-1");
michael@0 95
michael@0 96 policy.dataSubmissionEnabled = false;
michael@0 97 do_check_false(policyPrefs.get("dataSubmissionEnabled", true));
michael@0 98 do_check_false(policy.dataSubmissionEnabled);
michael@0 99
michael@0 100 policy.dataSubmissionPolicyAccepted = false;
michael@0 101 do_check_false(policyPrefs.get("dataSubmissionPolicyAccepted", true));
michael@0 102 do_check_false(policy.dataSubmissionPolicyAccepted);
michael@0 103
michael@0 104 do_check_false(policy.dataSubmissionPolicyBypassAcceptance);
michael@0 105 policyPrefs.set("dataSubmissionPolicyBypassAcceptance", true);
michael@0 106 do_check_true(policy.dataSubmissionPolicyBypassAcceptance);
michael@0 107
michael@0 108 policy.lastDataSubmissionRequestedDate = now;
michael@0 109 do_check_eq(hrPrefs.get("lastDataSubmissionRequestedTime"), nowT);
michael@0 110 do_check_eq(policy.lastDataSubmissionRequestedDate.getTime(), nowT);
michael@0 111
michael@0 112 policy.lastDataSubmissionSuccessfulDate = now;
michael@0 113 do_check_eq(hrPrefs.get("lastDataSubmissionSuccessfulTime"), nowT);
michael@0 114 do_check_eq(policy.lastDataSubmissionSuccessfulDate.getTime(), nowT);
michael@0 115
michael@0 116 policy.lastDataSubmissionFailureDate = now;
michael@0 117 do_check_eq(hrPrefs.get("lastDataSubmissionFailureTime"), nowT);
michael@0 118 do_check_eq(policy.lastDataSubmissionFailureDate.getTime(), nowT);
michael@0 119
michael@0 120 policy.nextDataSubmissionDate = now;
michael@0 121 do_check_eq(hrPrefs.get("nextDataSubmissionTime"), nowT);
michael@0 122 do_check_eq(policy.nextDataSubmissionDate.getTime(), nowT);
michael@0 123
michael@0 124 policy.currentDaySubmissionFailureCount = 2;
michael@0 125 do_check_eq(hrPrefs.get("currentDaySubmissionFailureCount", 0), 2);
michael@0 126 do_check_eq(policy.currentDaySubmissionFailureCount, 2);
michael@0 127
michael@0 128 policy.pendingDeleteRemoteData = true;
michael@0 129 do_check_true(hrPrefs.get("pendingDeleteRemoteData"));
michael@0 130 do_check_true(policy.pendingDeleteRemoteData);
michael@0 131
michael@0 132 policy.healthReportUploadEnabled = false;
michael@0 133 do_check_false(hrPrefs.get("uploadEnabled"));
michael@0 134 do_check_false(policy.healthReportUploadEnabled);
michael@0 135
michael@0 136 do_check_false(policy.healthReportUploadLocked);
michael@0 137 hrPrefs.lock("uploadEnabled");
michael@0 138 do_check_true(policy.healthReportUploadLocked);
michael@0 139 hrPrefs.unlock("uploadEnabled");
michael@0 140 do_check_false(policy.healthReportUploadLocked);
michael@0 141
michael@0 142 run_next_test();
michael@0 143 });
michael@0 144
michael@0 145 add_test(function test_notify_state_prefs() {
michael@0 146 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notify_state_prefs");
michael@0 147
michael@0 148 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED);
michael@0 149
michael@0 150 policy._dataSubmissionPolicyNotifiedDate = new Date();
michael@0 151 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT);
michael@0 152
michael@0 153 policy.dataSubmissionPolicyResponseDate = new Date();
michael@0 154 policy._dataSubmissionPolicyNotifiedDate = null;
michael@0 155 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_COMPLETE);
michael@0 156
michael@0 157 run_next_test();
michael@0 158 });
michael@0 159
michael@0 160 add_task(function test_initial_submission_notification() {
michael@0 161 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("initial_submission_notification");
michael@0 162
michael@0 163 do_check_eq(listener.notifyUserCount, 0);
michael@0 164
michael@0 165 // Fresh instances should not do anything initially.
michael@0 166 policy.checkStateAndTrigger();
michael@0 167 do_check_eq(listener.notifyUserCount, 0);
michael@0 168
michael@0 169 // We still shouldn't notify up to the millisecond before the barrier.
michael@0 170 defineNow(policy, new Date(policy.firstRunDate.getTime() +
michael@0 171 policy.SUBMISSION_NOTIFY_INTERVAL_MSEC - 1));
michael@0 172 policy.checkStateAndTrigger();
michael@0 173 do_check_eq(listener.notifyUserCount, 0);
michael@0 174 do_check_null(policy._dataSubmissionPolicyNotifiedDate);
michael@0 175 do_check_eq(policy.dataSubmissionPolicyNotifiedDate.getTime(), 0);
michael@0 176
michael@0 177 // We have crossed the threshold. We should see notification.
michael@0 178 defineNow(policy, new Date(policy.firstRunDate.getTime() +
michael@0 179 policy.SUBMISSION_NOTIFY_INTERVAL_MSEC));
michael@0 180 policy.checkStateAndTrigger();
michael@0 181 do_check_eq(listener.notifyUserCount, 1);
michael@0 182 yield listener.lastNotifyRequest.onUserNotifyComplete();
michael@0 183 do_check_true(policy._dataSubmissionPolicyNotifiedDate instanceof Date);
michael@0 184 do_check_true(policy.dataSubmissionPolicyNotifiedDate.getTime() > 0);
michael@0 185 do_check_eq(policy.dataSubmissionPolicyNotifiedDate.getTime(),
michael@0 186 policy._dataSubmissionPolicyNotifiedDate.getTime());
michael@0 187 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT);
michael@0 188 });
michael@0 189
michael@0 190 add_test(function test_bypass_acceptance() {
michael@0 191 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("bypass_acceptance");
michael@0 192
michael@0 193 policyPrefs.set("dataSubmissionPolicyBypassAcceptance", true);
michael@0 194 do_check_false(policy.dataSubmissionPolicyAccepted);
michael@0 195 do_check_true(policy.dataSubmissionPolicyBypassAcceptance);
michael@0 196 defineNow(policy, new Date(policy.nextDataSubmissionDate.getTime()));
michael@0 197 policy.checkStateAndTrigger();
michael@0 198 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 199
michael@0 200 run_next_test();
michael@0 201 });
michael@0 202
michael@0 203 add_task(function test_notification_implicit_acceptance() {
michael@0 204 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notification_implicit_acceptance");
michael@0 205
michael@0 206 let now = new Date(policy.nextDataSubmissionDate.getTime() -
michael@0 207 policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1);
michael@0 208 defineNow(policy, now);
michael@0 209 policy.checkStateAndTrigger();
michael@0 210 do_check_eq(listener.notifyUserCount, 1);
michael@0 211 yield listener.lastNotifyRequest.onUserNotifyComplete();
michael@0 212 do_check_eq(policy.dataSubmissionPolicyResponseType, "none-recorded");
michael@0 213
michael@0 214 do_check_true(5000 < policy.IMPLICIT_ACCEPTANCE_INTERVAL_MSEC);
michael@0 215 defineNow(policy, new Date(now.getTime() + 5000));
michael@0 216 policy.checkStateAndTrigger();
michael@0 217 do_check_eq(listener.notifyUserCount, 1);
michael@0 218 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT);
michael@0 219 do_check_eq(policy.dataSubmissionPolicyResponseDate.getTime(), 0);
michael@0 220 do_check_eq(policy.dataSubmissionPolicyResponseType, "none-recorded");
michael@0 221
michael@0 222 defineNow(policy, new Date(now.getTime() + policy.IMPLICIT_ACCEPTANCE_INTERVAL_MSEC + 1));
michael@0 223 policy.checkStateAndTrigger();
michael@0 224 do_check_eq(listener.notifyUserCount, 1);
michael@0 225 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_COMPLETE);
michael@0 226 do_check_eq(policy.dataSubmissionPolicyResponseDate.getTime(), policy.now().getTime());
michael@0 227 do_check_eq(policy.dataSubmissionPolicyResponseType, "accepted-implicit-time-elapsed");
michael@0 228 });
michael@0 229
michael@0 230 add_task(function test_notification_rejected() {
michael@0 231 // User notification failed. We should not record it as being presented.
michael@0 232 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notification_failed");
michael@0 233
michael@0 234 let now = new Date(policy.nextDataSubmissionDate.getTime() -
michael@0 235 policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1);
michael@0 236 defineNow(policy, now);
michael@0 237 policy.checkStateAndTrigger();
michael@0 238 do_check_eq(listener.notifyUserCount, 1);
michael@0 239 yield listener.lastNotifyRequest.onUserNotifyFailed(new Error("testing failed."));
michael@0 240 do_check_null(policy._dataSubmissionPolicyNotifiedDate);
michael@0 241 do_check_eq(policy.dataSubmissionPolicyNotifiedDate.getTime(), 0);
michael@0 242 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED);
michael@0 243 });
michael@0 244
michael@0 245 add_task(function test_notification_accepted() {
michael@0 246 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notification_accepted");
michael@0 247
michael@0 248 let now = new Date(policy.nextDataSubmissionDate.getTime() -
michael@0 249 policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1);
michael@0 250 defineNow(policy, now);
michael@0 251 policy.checkStateAndTrigger();
michael@0 252 yield listener.lastNotifyRequest.onUserNotifyComplete();
michael@0 253 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT);
michael@0 254 do_check_false(policy.dataSubmissionPolicyAccepted);
michael@0 255 listener.lastNotifyRequest.onUserNotifyComplete();
michael@0 256 listener.lastNotifyRequest.onUserAccept("foo-bar");
michael@0 257 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_COMPLETE);
michael@0 258 do_check_eq(policy.dataSubmissionPolicyResponseType, "accepted-foo-bar");
michael@0 259 do_check_true(policy.dataSubmissionPolicyAccepted);
michael@0 260 do_check_eq(policy.dataSubmissionPolicyResponseDate.getTime(), now.getTime());
michael@0 261 });
michael@0 262
michael@0 263 add_task(function test_notification_rejected() {
michael@0 264 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notification_rejected");
michael@0 265
michael@0 266 let now = new Date(policy.nextDataSubmissionDate.getTime() -
michael@0 267 policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1);
michael@0 268 defineNow(policy, now);
michael@0 269 policy.checkStateAndTrigger();
michael@0 270 yield listener.lastNotifyRequest.onUserNotifyComplete();
michael@0 271 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT);
michael@0 272 do_check_false(policy.dataSubmissionPolicyAccepted);
michael@0 273 listener.lastNotifyRequest.onUserReject();
michael@0 274 do_check_eq(policy.notifyState, policy.STATE_NOTIFY_COMPLETE);
michael@0 275 do_check_eq(policy.dataSubmissionPolicyResponseType, "rejected-no-reason");
michael@0 276 do_check_false(policy.dataSubmissionPolicyAccepted);
michael@0 277
michael@0 278 // No requests for submission should occur if user has rejected.
michael@0 279 defineNow(policy, new Date(policy.nextDataSubmissionDate.getTime() + 10000));
michael@0 280 policy.checkStateAndTrigger();
michael@0 281 do_check_eq(listener.requestDataUploadCount, 0);
michael@0 282 });
michael@0 283
michael@0 284 add_test(function test_submission_kill_switch() {
michael@0 285 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_kill_switch");
michael@0 286
michael@0 287 policy.firstRunDate = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000);
michael@0 288 policy.nextDataSubmissionDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
michael@0 289 policy.recordUserAcceptance("accept-old-ack");
michael@0 290 do_check_true(policyPrefs.has("dataSubmissionPolicyAcceptedVersion"));
michael@0 291 policy.checkStateAndTrigger();
michael@0 292 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 293
michael@0 294 defineNow(policy,
michael@0 295 new Date(Date.now() + policy.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC + 100));
michael@0 296 policy.dataSubmissionEnabled = false;
michael@0 297 policy.checkStateAndTrigger();
michael@0 298 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 299
michael@0 300 run_next_test();
michael@0 301 });
michael@0 302
michael@0 303 add_test(function test_upload_kill_switch() {
michael@0 304 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("upload_kill_switch");
michael@0 305
michael@0 306 defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
michael@0 307 policy.recordUserAcceptance();
michael@0 308 defineNow(policy, policy.nextDataSubmissionDate);
michael@0 309
michael@0 310 // So that we don't trigger deletions, which cause uploads to be delayed.
michael@0 311 hrPrefs.ignore("uploadEnabled", policy.uploadEnabledObserver);
michael@0 312
michael@0 313 policy.healthReportUploadEnabled = false;
michael@0 314 policy.checkStateAndTrigger();
michael@0 315 do_check_eq(listener.requestDataUploadCount, 0);
michael@0 316 policy.healthReportUploadEnabled = true;
michael@0 317 policy.checkStateAndTrigger();
michael@0 318 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 319
michael@0 320 run_next_test();
michael@0 321 });
michael@0 322
michael@0 323 add_test(function test_data_submission_no_data() {
michael@0 324 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("data_submission_no_data");
michael@0 325
michael@0 326 policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
michael@0 327 policy.dataSubmissionPolicyAccepted = true;
michael@0 328 let now = new Date(policy.nextDataSubmissionDate.getTime() + 1);
michael@0 329 defineNow(policy, now);
michael@0 330 do_check_eq(listener.requestDataUploadCount, 0);
michael@0 331 policy.checkStateAndTrigger();
michael@0 332 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 333 listener.lastDataRequest.onNoDataAvailable();
michael@0 334
michael@0 335 // The next trigger should try again.
michael@0 336 defineNow(policy, new Date(now.getTime() + 155 * 60 * 1000));
michael@0 337 policy.checkStateAndTrigger();
michael@0 338 do_check_eq(listener.requestDataUploadCount, 2);
michael@0 339
michael@0 340 run_next_test();
michael@0 341 });
michael@0 342
michael@0 343 add_task(function test_data_submission_submit_failure_hard() {
michael@0 344 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("data_submission_submit_failure_hard");
michael@0 345
michael@0 346 policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
michael@0 347 policy.dataSubmissionPolicyAccepted = true;
michael@0 348 let nextDataSubmissionDate = policy.nextDataSubmissionDate;
michael@0 349 let now = new Date(policy.nextDataSubmissionDate.getTime() + 1);
michael@0 350 defineNow(policy, now);
michael@0 351
michael@0 352 policy.checkStateAndTrigger();
michael@0 353 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 354 yield listener.lastDataRequest.onSubmissionFailureHard();
michael@0 355 do_check_eq(listener.lastDataRequest.state,
michael@0 356 listener.lastDataRequest.SUBMISSION_FAILURE_HARD);
michael@0 357
michael@0 358 let expected = new Date(now.getTime() + 24 * 60 * 60 * 1000);
michael@0 359 do_check_eq(policy.nextDataSubmissionDate.getTime(), expected.getTime());
michael@0 360
michael@0 361 defineNow(policy, new Date(now.getTime() + 10));
michael@0 362 policy.checkStateAndTrigger();
michael@0 363 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 364 });
michael@0 365
michael@0 366 add_task(function test_data_submission_submit_try_again() {
michael@0 367 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("data_submission_failure_soft");
michael@0 368
michael@0 369 policy.recordUserAcceptance();
michael@0 370 let nextDataSubmissionDate = policy.nextDataSubmissionDate;
michael@0 371 let now = new Date(policy.nextDataSubmissionDate.getTime());
michael@0 372 defineNow(policy, now);
michael@0 373 policy.checkStateAndTrigger();
michael@0 374 yield listener.lastDataRequest.onSubmissionFailureSoft();
michael@0 375 do_check_eq(policy.nextDataSubmissionDate.getTime(),
michael@0 376 nextDataSubmissionDate.getTime() + 15 * 60 * 1000);
michael@0 377 });
michael@0 378
michael@0 379 add_task(function test_submission_daily_scheduling() {
michael@0 380 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_daily_scheduling");
michael@0 381
michael@0 382 policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
michael@0 383 policy.dataSubmissionPolicyAccepted = true;
michael@0 384 let nextDataSubmissionDate = policy.nextDataSubmissionDate;
michael@0 385
michael@0 386 // Skip ahead to next submission date. We should get a submission request.
michael@0 387 let now = new Date(policy.nextDataSubmissionDate.getTime());
michael@0 388 defineNow(policy, now);
michael@0 389 policy.checkStateAndTrigger();
michael@0 390 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 391 do_check_eq(policy.lastDataSubmissionRequestedDate.getTime(), now.getTime());
michael@0 392
michael@0 393 let finishedDate = new Date(now.getTime() + 250);
michael@0 394 defineNow(policy, new Date(finishedDate.getTime() + 50));
michael@0 395 yield listener.lastDataRequest.onSubmissionSuccess(finishedDate);
michael@0 396 do_check_eq(policy.lastDataSubmissionSuccessfulDate.getTime(), finishedDate.getTime());
michael@0 397
michael@0 398 // Next scheduled submission should be exactly 1 day after the reported
michael@0 399 // submission success.
michael@0 400
michael@0 401 let nextScheduled = new Date(finishedDate.getTime() + 24 * 60 * 60 * 1000);
michael@0 402 do_check_eq(policy.nextDataSubmissionDate.getTime(), nextScheduled.getTime());
michael@0 403
michael@0 404 // Fast forward some arbitrary time. We shouldn't do any work yet.
michael@0 405 defineNow(policy, new Date(now.getTime() + 40000));
michael@0 406 policy.checkStateAndTrigger();
michael@0 407 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 408
michael@0 409 defineNow(policy, nextScheduled);
michael@0 410 policy.checkStateAndTrigger();
michael@0 411 do_check_eq(listener.requestDataUploadCount, 2);
michael@0 412 yield listener.lastDataRequest.onSubmissionSuccess(new Date(nextScheduled.getTime() + 200));
michael@0 413 do_check_eq(policy.nextDataSubmissionDate.getTime(),
michael@0 414 new Date(nextScheduled.getTime() + 24 * 60 * 60 * 1000 + 200).getTime());
michael@0 415 });
michael@0 416
michael@0 417 add_test(function test_submission_far_future_scheduling() {
michael@0 418 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_far_future_scheduling");
michael@0 419
michael@0 420 let now = new Date(Date.now() - 24 * 60 * 60 * 1000);
michael@0 421 defineNow(policy, now);
michael@0 422 policy.recordUserAcceptance();
michael@0 423 now = new Date();
michael@0 424 defineNow(policy, now);
michael@0 425
michael@0 426 let nextDate = policy._futureDate(3 * 24 * 60 * 60 * 1000 - 1);
michael@0 427 policy.nextDataSubmissionDate = nextDate;
michael@0 428 policy.checkStateAndTrigger();
michael@0 429 do_check_eq(listener.requestDataUploadCount, 0);
michael@0 430 do_check_eq(policy.nextDataSubmissionDate.getTime(), nextDate.getTime());
michael@0 431
michael@0 432 policy.nextDataSubmissionDate = new Date(nextDate.getTime() + 1);
michael@0 433 policy.checkStateAndTrigger();
michael@0 434 do_check_eq(listener.requestDataUploadCount, 0);
michael@0 435 do_check_eq(policy.nextDataSubmissionDate.getTime(),
michael@0 436 policy._futureDate(24 * 60 * 60 * 1000).getTime());
michael@0 437
michael@0 438 run_next_test();
michael@0 439 });
michael@0 440
michael@0 441 add_task(function test_submission_backoff() {
michael@0 442 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_backoff");
michael@0 443
michael@0 444 do_check_eq(policy.FAILURE_BACKOFF_INTERVALS.length, 2);
michael@0 445
michael@0 446 policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
michael@0 447 policy.dataSubmissionPolicyAccepted = true;
michael@0 448
michael@0 449 let now = new Date(policy.nextDataSubmissionDate.getTime());
michael@0 450 defineNow(policy, now);
michael@0 451 policy.checkStateAndTrigger();
michael@0 452 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 453 do_check_eq(policy.currentDaySubmissionFailureCount, 0);
michael@0 454
michael@0 455 now = new Date(now.getTime() + 5000);
michael@0 456 defineNow(policy, now);
michael@0 457
michael@0 458 // On first soft failure we should back off by scheduled interval.
michael@0 459 yield listener.lastDataRequest.onSubmissionFailureSoft();
michael@0 460 do_check_eq(policy.currentDaySubmissionFailureCount, 1);
michael@0 461 do_check_eq(policy.nextDataSubmissionDate.getTime(),
michael@0 462 new Date(now.getTime() + policy.FAILURE_BACKOFF_INTERVALS[0]).getTime());
michael@0 463 do_check_eq(policy.lastDataSubmissionFailureDate.getTime(), now.getTime());
michael@0 464
michael@0 465 // Should not request submission until scheduled.
michael@0 466 now = new Date(policy.nextDataSubmissionDate.getTime() - 1);
michael@0 467 defineNow(policy, now);
michael@0 468 policy.checkStateAndTrigger();
michael@0 469 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 470
michael@0 471 // 2nd request for submission.
michael@0 472 now = new Date(policy.nextDataSubmissionDate.getTime());
michael@0 473 defineNow(policy, now);
michael@0 474 policy.checkStateAndTrigger();
michael@0 475 do_check_eq(listener.requestDataUploadCount, 2);
michael@0 476
michael@0 477 now = new Date(now.getTime() + 5000);
michael@0 478 defineNow(policy, now);
michael@0 479
michael@0 480 // On second failure we should back off by more.
michael@0 481 yield listener.lastDataRequest.onSubmissionFailureSoft();
michael@0 482 do_check_eq(policy.currentDaySubmissionFailureCount, 2);
michael@0 483 do_check_eq(policy.nextDataSubmissionDate.getTime(),
michael@0 484 new Date(now.getTime() + policy.FAILURE_BACKOFF_INTERVALS[1]).getTime());
michael@0 485
michael@0 486 now = new Date(policy.nextDataSubmissionDate.getTime());
michael@0 487 defineNow(policy, now);
michael@0 488 policy.checkStateAndTrigger();
michael@0 489 do_check_eq(listener.requestDataUploadCount, 3);
michael@0 490
michael@0 491 now = new Date(now.getTime() + 5000);
michael@0 492 defineNow(policy, now);
michael@0 493
michael@0 494 // On 3rd failure we should back off by a whole day.
michael@0 495 yield listener.lastDataRequest.onSubmissionFailureSoft();
michael@0 496 do_check_eq(policy.currentDaySubmissionFailureCount, 0);
michael@0 497 do_check_eq(policy.nextDataSubmissionDate.getTime(),
michael@0 498 new Date(now.getTime() + 24 * 60 * 60 * 1000).getTime());
michael@0 499 });
michael@0 500
michael@0 501 // Ensure that only one submission request can be active at a time.
michael@0 502 add_test(function test_submission_expiring() {
michael@0 503 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_expiring");
michael@0 504
michael@0 505 policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
michael@0 506 policy.dataSubmissionPolicyAccepted = true;
michael@0 507 let nextDataSubmission = policy.nextDataSubmissionDate;
michael@0 508 let now = new Date(policy.nextDataSubmissionDate.getTime());
michael@0 509 defineNow(policy, now);
michael@0 510 policy.checkStateAndTrigger();
michael@0 511 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 512 defineNow(policy, new Date(now.getTime() + 500));
michael@0 513 policy.checkStateAndTrigger();
michael@0 514 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 515
michael@0 516 defineNow(policy, new Date(policy.now().getTime() +
michael@0 517 policy.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC));
michael@0 518
michael@0 519 policy.checkStateAndTrigger();
michael@0 520 do_check_eq(listener.requestDataUploadCount, 2);
michael@0 521
michael@0 522 run_next_test();
michael@0 523 });
michael@0 524
michael@0 525 add_task(function test_delete_remote_data() {
michael@0 526 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("delete_remote_data");
michael@0 527
michael@0 528 do_check_false(policy.pendingDeleteRemoteData);
michael@0 529 let nextSubmissionDate = policy.nextDataSubmissionDate;
michael@0 530
michael@0 531 let now = new Date();
michael@0 532 defineNow(policy, now);
michael@0 533
michael@0 534 policy.deleteRemoteData();
michael@0 535 do_check_true(policy.pendingDeleteRemoteData);
michael@0 536 do_check_neq(nextSubmissionDate.getTime(),
michael@0 537 policy.nextDataSubmissionDate.getTime());
michael@0 538 do_check_eq(now.getTime(), policy.nextDataSubmissionDate.getTime());
michael@0 539
michael@0 540 do_check_eq(listener.requestRemoteDeleteCount, 1);
michael@0 541 do_check_true(listener.lastRemoteDeleteRequest.isDelete);
michael@0 542 defineNow(policy, policy._futureDate(1000));
michael@0 543
michael@0 544 yield listener.lastRemoteDeleteRequest.onSubmissionSuccess(policy.now());
michael@0 545 do_check_false(policy.pendingDeleteRemoteData);
michael@0 546 });
michael@0 547
michael@0 548 // Ensure that deletion requests take priority over regular data submission.
michael@0 549 add_test(function test_delete_remote_data_priority() {
michael@0 550 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("delete_remote_data_priority");
michael@0 551
michael@0 552 let now = new Date();
michael@0 553 defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
michael@0 554 policy.recordUserAcceptance();
michael@0 555 defineNow(policy, new Date(now.getTime() + 3 * 24 * 60 * 60 * 1000));
michael@0 556
michael@0 557 policy.checkStateAndTrigger();
michael@0 558 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 559 policy._inProgressSubmissionRequest = null;
michael@0 560
michael@0 561 policy.deleteRemoteData();
michael@0 562 policy.checkStateAndTrigger();
michael@0 563
michael@0 564 do_check_eq(listener.requestRemoteDeleteCount, 1);
michael@0 565 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 566
michael@0 567 run_next_test();
michael@0 568 });
michael@0 569
michael@0 570 add_test(function test_delete_remote_data_backoff() {
michael@0 571 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("delete_remote_data_backoff");
michael@0 572
michael@0 573 let now = new Date();
michael@0 574 defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
michael@0 575 policy.recordUserAcceptance();
michael@0 576 defineNow(policy, now);
michael@0 577 policy.nextDataSubmissionDate = now;
michael@0 578 policy.deleteRemoteData();
michael@0 579
michael@0 580 policy.checkStateAndTrigger();
michael@0 581 do_check_eq(listener.requestRemoteDeleteCount, 1);
michael@0 582 defineNow(policy, policy._futureDate(1000));
michael@0 583 policy.checkStateAndTrigger();
michael@0 584 do_check_eq(listener.requestDataUploadCount, 0);
michael@0 585 do_check_eq(listener.requestRemoteDeleteCount, 1);
michael@0 586
michael@0 587 defineNow(policy, policy._futureDate(500));
michael@0 588 listener.lastRemoteDeleteRequest.onSubmissionFailureSoft();
michael@0 589 defineNow(policy, policy._futureDate(50));
michael@0 590
michael@0 591 policy.checkStateAndTrigger();
michael@0 592 do_check_eq(listener.requestRemoteDeleteCount, 1);
michael@0 593
michael@0 594 defineNow(policy, policy._futureDate(policy.FAILURE_BACKOFF_INTERVALS[0] - 50));
michael@0 595 policy.checkStateAndTrigger();
michael@0 596 do_check_eq(listener.requestRemoteDeleteCount, 2);
michael@0 597
michael@0 598 run_next_test();
michael@0 599 });
michael@0 600
michael@0 601 // If we request delete while an upload is in progress, delete should be
michael@0 602 // scheduled immediately after upload.
michael@0 603 add_task(function test_delete_remote_data_in_progress_upload() {
michael@0 604 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("delete_remote_data_in_progress_upload");
michael@0 605
michael@0 606 let now = new Date();
michael@0 607 defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
michael@0 608 policy.recordUserAcceptance();
michael@0 609 defineNow(policy, policy.nextDataSubmissionDate);
michael@0 610
michael@0 611 policy.checkStateAndTrigger();
michael@0 612 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 613 defineNow(policy, policy._futureDate(50 * 1000));
michael@0 614
michael@0 615 // If we request a delete during a pending request, nothing should be done.
michael@0 616 policy.deleteRemoteData();
michael@0 617 policy.checkStateAndTrigger();
michael@0 618 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 619 do_check_eq(listener.requestRemoteDeleteCount, 0);
michael@0 620
michael@0 621 // Now wait a little bit and finish the request.
michael@0 622 defineNow(policy, policy._futureDate(10 * 1000));
michael@0 623 yield listener.lastDataRequest.onSubmissionSuccess(policy._futureDate(1000));
michael@0 624 defineNow(policy, policy._futureDate(5000));
michael@0 625
michael@0 626 policy.checkStateAndTrigger();
michael@0 627 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 628 do_check_eq(listener.requestRemoteDeleteCount, 1);
michael@0 629 });
michael@0 630
michael@0 631 add_test(function test_polling() {
michael@0 632 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("polling");
michael@0 633 let intended = 500;
michael@0 634 let acceptable = 250; // Because nsITimer doesn't guarantee times.
michael@0 635
michael@0 636 // Ensure checkStateAndTrigger is called at a regular interval.
michael@0 637 let then = Date.now();
michael@0 638 print("Starting run: " + then);
michael@0 639 Object.defineProperty(policy, "POLL_INTERVAL_MSEC", {
michael@0 640 value: intended,
michael@0 641 });
michael@0 642 let count = 0;
michael@0 643
michael@0 644 Object.defineProperty(policy, "checkStateAndTrigger", {
michael@0 645 value: function fakeCheckStateAndTrigger() {
michael@0 646 let now = Date.now();
michael@0 647 let after = now - then;
michael@0 648 count++;
michael@0 649
michael@0 650 print("Polled at " + now + " after " + after + "ms, intended " + intended);
michael@0 651 do_check_true(after >= acceptable);
michael@0 652 DataReportingPolicy.prototype.checkStateAndTrigger.call(policy);
michael@0 653
michael@0 654 if (count >= 2) {
michael@0 655 policy.stopPolling();
michael@0 656
michael@0 657 do_check_eq(listener.notifyUserCount, 0);
michael@0 658 do_check_eq(listener.requestDataUploadCount, 0);
michael@0 659
michael@0 660 run_next_test();
michael@0 661 }
michael@0 662
michael@0 663 // "Specified timer period will be at least the time between when
michael@0 664 // processing for last firing the callback completes and when the next
michael@0 665 // firing occurs."
michael@0 666 //
michael@0 667 // That means we should set 'then' at the *end* of our handler, not
michael@0 668 // earlier.
michael@0 669 then = Date.now();
michael@0 670 }
michael@0 671 });
michael@0 672 policy.startPolling();
michael@0 673 });
michael@0 674
michael@0 675 // Ensure that implicit acceptance of policy is resolved through polling.
michael@0 676 //
michael@0 677 // This is probably covered by other tests. But, it's best to have explicit
michael@0 678 // coverage from a higher-level.
michael@0 679 add_test(function test_polling_implicit_acceptance() {
michael@0 680 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("polling_implicit_acceptance");
michael@0 681
michael@0 682 // Redefine intervals with shorter, test-friendly values.
michael@0 683 Object.defineProperty(policy, "POLL_INTERVAL_MSEC", {
michael@0 684 value: 250,
michael@0 685 });
michael@0 686
michael@0 687 Object.defineProperty(policy, "IMPLICIT_ACCEPTANCE_INTERVAL_MSEC", {
michael@0 688 value: 700,
michael@0 689 });
michael@0 690
michael@0 691 let count = 0;
michael@0 692
michael@0 693 // Track JS elapsed time, so we can decide if we've waited for enough ticks.
michael@0 694 let start;
michael@0 695 Object.defineProperty(policy, "checkStateAndTrigger", {
michael@0 696 value: function CheckStateAndTriggerProxy() {
michael@0 697 count++;
michael@0 698 let now = Date.now();
michael@0 699 let delta = now - start;
michael@0 700 print("checkStateAndTrigger count: " + count + ", now " + now +
michael@0 701 ", delta " + delta);
michael@0 702
michael@0 703 // Account for some slack.
michael@0 704 DataReportingPolicy.prototype.checkStateAndTrigger.call(policy);
michael@0 705
michael@0 706 // What should happen on different invocations:
michael@0 707 //
michael@0 708 // 1) We are inside the prompt interval so user gets prompted.
michael@0 709 // 2) still ~300ms away from implicit acceptance
michael@0 710 // 3) still ~50ms away from implicit acceptance
michael@0 711 // 4) Implicit acceptance recorded. Data submission requested.
michael@0 712 // 5) Request still pending. No new submission requested.
michael@0 713 //
michael@0 714 // Note that, due to the inaccuracy of timers, 4 might not happen until 5
michael@0 715 // firings have occurred. Yay. So we watch times, not just counts.
michael@0 716
michael@0 717 do_check_eq(listener.notifyUserCount, 1);
michael@0 718
michael@0 719 if (count == 1) {
michael@0 720 listener.lastNotifyRequest.onUserNotifyComplete();
michael@0 721 }
michael@0 722
michael@0 723 if (delta <= (policy.IMPLICIT_ACCEPTANCE_INTERVAL_MSEC + policy.POLL_INTERVAL_MSEC)) {
michael@0 724 do_check_false(policy.dataSubmissionPolicyAccepted);
michael@0 725 do_check_eq(listener.requestDataUploadCount, 0);
michael@0 726 } else if (count > 3) {
michael@0 727 do_check_true(policy.dataSubmissionPolicyAccepted);
michael@0 728 do_check_eq(policy.dataSubmissionPolicyResponseType,
michael@0 729 "accepted-implicit-time-elapsed");
michael@0 730 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 731 }
michael@0 732
michael@0 733 if ((count > 4) && policy.dataSubmissionPolicyAccepted) {
michael@0 734 do_check_eq(listener.requestDataUploadCount, 1);
michael@0 735 policy.stopPolling();
michael@0 736 run_next_test();
michael@0 737 }
michael@0 738 }
michael@0 739 });
michael@0 740
michael@0 741 policy.firstRunDate = new Date(Date.now() - 4 * 24 * 60 * 60 * 1000);
michael@0 742 policy.nextDataSubmissionDate = new Date(Date.now());
michael@0 743 start = Date.now();
michael@0 744 policy.startPolling();
michael@0 745 });
michael@0 746
michael@0 747 add_task(function test_record_health_report_upload_enabled() {
michael@0 748 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("record_health_report_upload_enabled");
michael@0 749
michael@0 750 // Preconditions.
michael@0 751 do_check_false(policy.pendingDeleteRemoteData);
michael@0 752 do_check_true(policy.healthReportUploadEnabled);
michael@0 753 do_check_eq(listener.requestRemoteDeleteCount, 0);
michael@0 754
michael@0 755 // User intent to disable should immediately result in a pending
michael@0 756 // delete request.
michael@0 757 policy.recordHealthReportUploadEnabled(false, "testing 1 2 3");
michael@0 758 do_check_false(policy.healthReportUploadEnabled);
michael@0 759 do_check_true(policy.pendingDeleteRemoteData);
michael@0 760 do_check_eq(listener.requestRemoteDeleteCount, 1);
michael@0 761
michael@0 762 // Fulfilling it should make it go away.
michael@0 763 yield listener.lastRemoteDeleteRequest.onNoDataAvailable();
michael@0 764 do_check_false(policy.pendingDeleteRemoteData);
michael@0 765
michael@0 766 // User intent to enable should get us back to default state.
michael@0 767 policy.recordHealthReportUploadEnabled(true, "testing 1 2 3");
michael@0 768 do_check_false(policy.pendingDeleteRemoteData);
michael@0 769 do_check_true(policy.healthReportUploadEnabled);
michael@0 770 });
michael@0 771
michael@0 772 add_test(function test_pref_change_initiates_deletion() {
michael@0 773 let [policy, policyPrefs, hrPrefs, listener] = getPolicy("record_health_report_upload_enabled");
michael@0 774
michael@0 775 // Preconditions.
michael@0 776 do_check_false(policy.pendingDeleteRemoteData);
michael@0 777 do_check_true(policy.healthReportUploadEnabled);
michael@0 778 do_check_eq(listener.requestRemoteDeleteCount, 0);
michael@0 779
michael@0 780 // User intent to disable should indirectly result in a pending
michael@0 781 // delete request, because the policy is watching for the pref
michael@0 782 // to change.
michael@0 783 Object.defineProperty(policy, "deleteRemoteData", {
michael@0 784 value: function deleteRemoteDataProxy() {
michael@0 785 do_check_false(policy.healthReportUploadEnabled);
michael@0 786 do_check_false(policy.pendingDeleteRemoteData); // Just called.
michael@0 787
michael@0 788 run_next_test();
michael@0 789 },
michael@0 790 });
michael@0 791
michael@0 792 hrPrefs.set("uploadEnabled", false);
michael@0 793 });
michael@0 794
michael@0 795 add_task(function* test_policy_version() {
michael@0 796 let policy, policyPrefs, hrPrefs, listener, now, firstRunTime;
michael@0 797 function createPolicy(shouldBeAccepted = false,
michael@0 798 currentPolicyVersion = 1, minimumPolicyVersion = 1,
michael@0 799 branchMinimumVersionOverride) {
michael@0 800 [policy, policyPrefs, hrPrefs, listener] =
michael@0 801 getPolicy("policy_version_test", currentPolicyVersion,
michael@0 802 minimumPolicyVersion, branchMinimumVersionOverride);
michael@0 803 let firstRun = now === undefined;
michael@0 804 if (firstRun) {
michael@0 805 firstRunTime = policy.firstRunDate.getTime();
michael@0 806 do_check_true(firstRunTime > 0);
michael@0 807 now = new Date(policy.firstRunDate.getTime() +
michael@0 808 policy.SUBMISSION_NOTIFY_INTERVAL_MSEC);
michael@0 809 }
michael@0 810 else {
michael@0 811 // The first-run time should not be reset even after policy-version
michael@0 812 // upgrades.
michael@0 813 do_check_eq(policy.firstRunDate.getTime(), firstRunTime);
michael@0 814 }
michael@0 815 defineNow(policy, now);
michael@0 816 do_check_eq(policy.dataSubmissionPolicyAccepted, shouldBeAccepted);
michael@0 817 }
michael@0 818
michael@0 819 function* triggerPolicyCheckAndEnsureNotified(notified = true, accept = true) {
michael@0 820 policy.checkStateAndTrigger();
michael@0 821 do_check_eq(listener.notifyUserCount, Number(notified));
michael@0 822 if (notified) {
michael@0 823 yield listener.lastNotifyRequest.onUserNotifyComplete();
michael@0 824 if (accept) {
michael@0 825 listener.lastNotifyRequest.onUserAccept("because,");
michael@0 826 do_check_true(policy.dataSubmissionPolicyAccepted);
michael@0 827 do_check_eq(policyPrefs.get("dataSubmissionPolicyAcceptedVersion"),
michael@0 828 policyPrefs.get("currentPolicyVersion"));
michael@0 829 }
michael@0 830 else {
michael@0 831 do_check_false(policyPrefs.has("dataSubmissionPolicyAcceptedVersion"));
michael@0 832 }
michael@0 833 }
michael@0 834 }
michael@0 835
michael@0 836 createPolicy();
michael@0 837 yield triggerPolicyCheckAndEnsureNotified();
michael@0 838
michael@0 839 // We shouldn't be notified again if the current version is still valid;
michael@0 840 createPolicy(true);
michael@0 841 yield triggerPolicyCheckAndEnsureNotified(false);
michael@0 842
michael@0 843 // Just increasing the current version isn't enough. The minimum
michael@0 844 // version must be changed.
michael@0 845 let currentPolicyVersion = policyPrefs.get("currentPolicyVersion");
michael@0 846 let minimumPolicyVersion = policyPrefs.get("minimumPolicyVersion");
michael@0 847 createPolicy(true, ++currentPolicyVersion, minimumPolicyVersion);
michael@0 848 yield triggerPolicyCheckAndEnsureNotified(false);
michael@0 849 do_check_true(policy.dataSubmissionPolicyAccepted);
michael@0 850 do_check_eq(policyPrefs.get("dataSubmissionPolicyAcceptedVersion"),
michael@0 851 minimumPolicyVersion);
michael@0 852
michael@0 853 // Increase the minimum policy version and check if we're notified.
michael@0 854 createPolicy(false, currentPolicyVersion, ++minimumPolicyVersion);
michael@0 855 do_check_false(policyPrefs.has("dataSubmissionPolicyAcceptedVersion"));
michael@0 856 yield triggerPolicyCheckAndEnsureNotified();
michael@0 857
michael@0 858 // Test increasing the minimum version just on the current channel.
michael@0 859 createPolicy(true, currentPolicyVersion, minimumPolicyVersion);
michael@0 860 yield triggerPolicyCheckAndEnsureNotified(false);
michael@0 861 createPolicy(false, ++currentPolicyVersion, minimumPolicyVersion, minimumPolicyVersion + 1);
michael@0 862 yield triggerPolicyCheckAndEnsureNotified(true);
michael@0 863 });

mercurial