mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 810132 - Add remote deletion requests to policy; r=rnewman
This commit is contained in:
parent
21080df09a
commit
80740451d8
@ -15,20 +15,29 @@ this.MockPolicyListener = function MockPolicyListener() {
|
||||
this._log = Log4Moz.repository.getLogger("HealthReport.Testing.MockPolicyListener");
|
||||
this._log.level = Log4Moz.Level["Debug"];
|
||||
|
||||
this.requestDataSubmissionCount = 0;
|
||||
this.requestDataUploadCount = 0;
|
||||
this.lastDataRequest = null;
|
||||
|
||||
this.requestRemoteDeleteCount = 0;
|
||||
this.lastRemoteDeleteRequest = null;
|
||||
|
||||
this.notifyUserCount = 0;
|
||||
this.lastNotifyRequest = null;
|
||||
}
|
||||
|
||||
MockPolicyListener.prototype = {
|
||||
onRequestDataSubmission: function onRequestDataSubmission(request) {
|
||||
this._log.info("onRequestDataSubmission invoked.");
|
||||
this.requestDataSubmissionCount++;
|
||||
onRequestDataUpload: function onRequestDataUpload(request) {
|
||||
this._log.info("onRequestDataUpload invoked.");
|
||||
this.requestDataUploadCount++;
|
||||
this.lastDataRequest = request;
|
||||
},
|
||||
|
||||
onRequestRemoteDelete: function onRequestRemoteDelete(request) {
|
||||
this._log.info("onRequestRemoteDelete invoked.");
|
||||
this.requestRemoteDeleteCount++;
|
||||
this.lastRemoteDeleteRequest = request;
|
||||
},
|
||||
|
||||
onNotifyDataPolicy: function onNotifyDataPolicy(request) {
|
||||
this._log.info("onNotifyUser invoked.");
|
||||
this.notifyUserCount++;
|
||||
|
@ -107,7 +107,9 @@ Object.freeze(NotifyPolicyRequest.prototype);
|
||||
/**
|
||||
* Represents a request to submit data.
|
||||
*
|
||||
* Instances of this are created when the policy requests data submission.
|
||||
* Instances of this are created when the policy requests data upload or
|
||||
* deletion.
|
||||
*
|
||||
* Receivers are expected to call one of the provided on* functions to signal
|
||||
* completion of the request.
|
||||
*
|
||||
@ -115,9 +117,10 @@ Object.freeze(NotifyPolicyRequest.prototype);
|
||||
* Receivers of instances of this type should not attempt to do anything with
|
||||
* the instance except call one of the on* methods.
|
||||
*/
|
||||
function DataSubmissionRequest(promise, expiresDate) {
|
||||
function DataSubmissionRequest(promise, expiresDate, isDelete) {
|
||||
this.promise = promise;
|
||||
this.expiresDate = expiresDate;
|
||||
this.isDelete = isDelete;
|
||||
|
||||
this.state = null;
|
||||
this.reason = null;
|
||||
@ -131,6 +134,10 @@ DataSubmissionRequest.prototype = {
|
||||
|
||||
/**
|
||||
* No submission was attempted because no data was available.
|
||||
*
|
||||
* In the case of upload, this means there is no data to upload (perhaps
|
||||
* it isn't available yet). In case of remote deletion, it means that there
|
||||
* is no remote data to delete.
|
||||
*/
|
||||
onNoDataAvailable: function onNoDataAvailable() {
|
||||
this.state = this.NO_DATA_AVAILABLE;
|
||||
@ -140,6 +147,9 @@ DataSubmissionRequest.prototype = {
|
||||
/**
|
||||
* Data submission has completed successfully.
|
||||
*
|
||||
* In case of upload, this means the upload completed successfully. In case
|
||||
* of deletion, the data was deleted successfully.
|
||||
*
|
||||
* @param date
|
||||
* (Date) When data submission occurred.
|
||||
*/
|
||||
@ -204,11 +214,16 @@ Object.freeze(DataSubmissionRequest.prototype);
|
||||
* The listener passed into the instance must have the following properties
|
||||
* (which are callbacks that will be invoked at certain key events):
|
||||
*
|
||||
* * onRequestDataSubmission(request) - Called when the policy is requesting
|
||||
* * onRequestDataUpload(request) - Called when the policy is requesting
|
||||
* data to be submitted. The function is passed a `DataSubmissionRequest`.
|
||||
* The listener should call one of the special resolving functions on that
|
||||
* instance (see the documentation for that type).
|
||||
*
|
||||
* * onRequestRemoteDelete(request) - Called when the policy is requesting
|
||||
* deletion of remotely stored data. The function is passed a
|
||||
* `DataSubmissionRequest`. The listener should call one of the special
|
||||
* resolving functions on that instance (just like `onRequestDataUpload`).
|
||||
*
|
||||
* * onNotifyDataPolicy(request) - Called when the policy is requesting the
|
||||
* user to be notified that data submission will occur. The function
|
||||
* receives a `NotifyPolicyRequest` instance. The callee should call one or
|
||||
@ -321,7 +336,11 @@ HealthReportPolicy.prototype = {
|
||||
STATE_NOTIFY_WAIT: "waiting",
|
||||
STATE_NOTIFY_COMPLETE: "ok",
|
||||
|
||||
REQUIRED_LISTENERS: ["onRequestDataSubmission", "onNotifyDataPolicy"],
|
||||
REQUIRED_LISTENERS: [
|
||||
"onRequestDataUpload",
|
||||
"onRequestRemoteDelete",
|
||||
"onNotifyDataPolicy",
|
||||
],
|
||||
|
||||
/**
|
||||
* The first time the health report policy came into existence.
|
||||
@ -402,8 +421,8 @@ HealthReportPolicy.prototype = {
|
||||
/**
|
||||
* Whether submission of data is allowed.
|
||||
*
|
||||
* This is the master switch for data submission. If it is off, we will
|
||||
* never submit data, even if the user has agreed to it.
|
||||
* This is the master switch for remote server communication. If it is
|
||||
* false, we never request upload or deletion.
|
||||
*/
|
||||
get dataSubmissionEnabled() {
|
||||
// Default is true because we are opt-out.
|
||||
@ -414,6 +433,22 @@ HealthReportPolicy.prototype = {
|
||||
this._prefs.set("dataSubmissionEnabled", !!value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether upload of data is allowed.
|
||||
*
|
||||
* This is a kill switch for upload. It is meant to reflect a system or
|
||||
* deployment policy decision. User intent should be reflected in the
|
||||
* "dataSubmissionPolicy" prefs.
|
||||
*/
|
||||
get dataUploadEnabled() {
|
||||
// Default is true because we are opt-out.
|
||||
return this._prefs.get("dataUploadEnabled", true);
|
||||
},
|
||||
|
||||
set dataUploadEnabled(value) {
|
||||
this._prefs.set("dataUploadEnabled", !!value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether the user has accepted that data submission can occur.
|
||||
*
|
||||
@ -541,6 +576,21 @@ HealthReportPolicy.prototype = {
|
||||
this._prefs.set("currentDaySubmissionFailureCount", value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether a request to delete remote data is awaiting completion.
|
||||
*
|
||||
* If this is true, the policy will request that remote data be deleted.
|
||||
* Furthermore, no new data will be uploaded (if it's even allowed) until
|
||||
* the remote deletion is fulfilled.
|
||||
*/
|
||||
get pendingDeleteRemoteData() {
|
||||
return !!this._prefs.get("pendingDeleteRemoteData", false);
|
||||
},
|
||||
|
||||
set pendingDeleteRemoteData(value) {
|
||||
this._prefs.set("pendingDeleteRemoteData", !!value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Record user acceptance of data submission policy.
|
||||
*
|
||||
@ -578,6 +628,25 @@ HealthReportPolicy.prototype = {
|
||||
this.dataSubmissionPolicyAccepted = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Request that remote data be deleted.
|
||||
*
|
||||
* This will record an intent that previously uploaded data is to be deleted.
|
||||
* The policy will eventually issue a request to the listener for data
|
||||
* deletion. It will keep asking for deletion until the listener acknowledges
|
||||
* that data has been deleted.
|
||||
*/
|
||||
deleteRemoteData: function deleteRemoteData(reason="no-reason") {
|
||||
this._log.info("Remote data deletion requested: " + reason);
|
||||
|
||||
this.pendingDeleteRemoteData = true;
|
||||
|
||||
// We want delete deletion to occur as soon as possible. Move up any
|
||||
// pending scheduled data submission and try to trigger.
|
||||
this.nextDataSubmissionDate = this.now();
|
||||
this.checkStateAndTrigger();
|
||||
},
|
||||
|
||||
/**
|
||||
* Start background polling for activity.
|
||||
*
|
||||
@ -654,7 +723,29 @@ HealthReportPolicy.prototype = {
|
||||
// should be pretty safe.
|
||||
this._moveScheduleForward24h();
|
||||
|
||||
// Fall through and prompt for user notification, if necessary.
|
||||
// Fall through since we may have other actions.
|
||||
}
|
||||
|
||||
// Tend to any in progress work.
|
||||
if (this._processInProgressSubmission()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Requests to delete remote data take priority above everything else.
|
||||
if (this.pendingDeleteRemoteData) {
|
||||
if (nowT < nextSubmissionDate.getTime()) {
|
||||
this._log.debug("Deletion request is scheduled for the future: " +
|
||||
nextSubmissionDate);
|
||||
return;
|
||||
}
|
||||
|
||||
this._dispatchSubmissionRequest("onRequestRemoteDelete", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.dataUploadEnabled) {
|
||||
this._log.debug("Data upload is disabled. Doing nothing.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If the user hasn't responded to the data policy, don't do anything.
|
||||
@ -677,53 +768,7 @@ HealthReportPolicy.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._inProgressSubmissionRequest) {
|
||||
if (this._inProgressSubmissionRequest.expiresDate.getTime() > nowT) {
|
||||
this._log.info("Waiting on in-progress submission request to finish.");
|
||||
return;
|
||||
}
|
||||
|
||||
this._log.warn("Old submission request has expired from no activity.");
|
||||
this._inProgressSubmissionRequest.promise.reject(new Error("Request has expired."));
|
||||
this._inProgressSubmissionRequest = null;
|
||||
if (!this._handleSubmissionFailure()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We're past our scheduled next data submission date, so let's do it!
|
||||
this.lastDataSubmissionRequestedDate = now;
|
||||
let deferred = Promise.defer();
|
||||
let requestExpiresDate =
|
||||
this._futureDate(this.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC);
|
||||
this._inProgressSubmissionRequest = new DataSubmissionRequest(deferred,
|
||||
requestExpiresDate);
|
||||
|
||||
let onSuccess = function onSuccess(result) {
|
||||
this._inProgressSubmissionRequest = null;
|
||||
this._handleSubmissionResult(result);
|
||||
}.bind(this);
|
||||
|
||||
let onError = function onError(error) {
|
||||
this._log.error("Error when handling data submission result: " +
|
||||
CommonUtils.exceptionStr(result));
|
||||
this._inProgressSubmissionRequest = null;
|
||||
this._handleSubmissionFailure();
|
||||
}.bind(this);
|
||||
|
||||
deferred.promise.then(onSuccess, onError);
|
||||
|
||||
this._log.info("Requesting data submission. Will expire at " +
|
||||
requestExpiresDate);
|
||||
try {
|
||||
this._listener.onRequestDataSubmission(this._inProgressSubmissionRequest);
|
||||
} catch (ex) {
|
||||
this._log.warn("Exception when calling onRequestDataSubmission: " +
|
||||
CommonUtils.exceptionStr(ex));
|
||||
this._inProgressSubmissionRequest = null;
|
||||
this._handleSubmissionFailure();
|
||||
return;
|
||||
}
|
||||
this._dispatchSubmissionRequest("onRequestDataUpload", false);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -797,26 +842,109 @@ HealthReportPolicy.prototype = {
|
||||
return true;
|
||||
},
|
||||
|
||||
_processInProgressSubmission: function _processInProgressSubmission() {
|
||||
if (!this._inProgressSubmissionRequest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let now = this.now().getTime();
|
||||
if (this._inProgressSubmissionRequest.expiresDate.getTime() > now) {
|
||||
this._log.info("Waiting on in-progress submission request to finish.");
|
||||
return true;
|
||||
}
|
||||
|
||||
this._log.warn("Old submission request has expired from no activity.");
|
||||
this._inProgressSubmissionRequest.promise.reject(new Error("Request has expired."));
|
||||
this._inProgressSubmissionRequest = null;
|
||||
this._handleSubmissionFailure();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_dispatchSubmissionRequest: function _dispatchSubmissionRequest(handler, isDelete) {
|
||||
let now = this.now();
|
||||
|
||||
// We're past our scheduled next data submission date, so let's do it!
|
||||
this.lastDataSubmissionRequestedDate = now;
|
||||
let deferred = Promise.defer();
|
||||
let requestExpiresDate =
|
||||
this._futureDate(this.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC);
|
||||
this._inProgressSubmissionRequest = new DataSubmissionRequest(deferred,
|
||||
requestExpiresDate,
|
||||
isDelete);
|
||||
|
||||
let onSuccess = function onSuccess(result) {
|
||||
this._inProgressSubmissionRequest = null;
|
||||
this._handleSubmissionResult(result);
|
||||
}.bind(this);
|
||||
|
||||
let onError = function onError(error) {
|
||||
this._log.error("Error when handling data submission result: " +
|
||||
CommonUtils.exceptionStr(result));
|
||||
this._inProgressSubmissionRequest = null;
|
||||
this._handleSubmissionFailure();
|
||||
}.bind(this);
|
||||
|
||||
deferred.promise.then(onSuccess, onError);
|
||||
|
||||
this._log.info("Requesting data submission. Will expire at " +
|
||||
requestExpiresDate);
|
||||
try {
|
||||
this._listener[handler](this._inProgressSubmissionRequest);
|
||||
} catch (ex) {
|
||||
this._log.warn("Exception when calling " + handler + ": " +
|
||||
CommonUtils.exceptionStr(ex));
|
||||
this._inProgressSubmissionRequest = null;
|
||||
this._handleSubmissionFailure();
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
_handleSubmissionResult: function _handleSubmissionResult(request) {
|
||||
let state = request.state;
|
||||
let reason = request.reason || "no reason";
|
||||
this._log.info("Got submission request result: " + state);
|
||||
|
||||
if (state == request.SUBMISSION_SUCCESS) {
|
||||
this._log.info("Successful data submission reported.");
|
||||
if (request.isDelete) {
|
||||
this.pendingDeleteRemoteData = false;
|
||||
this._log.info("Successful data delete reported.");
|
||||
} else {
|
||||
this._log.info("Successful data upload reported.");
|
||||
}
|
||||
|
||||
this.lastDataSubmissionSuccessfulDate = request.submissionDate;
|
||||
this.nextDataSubmissionDate =
|
||||
|
||||
let nextSubmissionDate =
|
||||
new Date(request.submissionDate.getTime() + MILLISECONDS_PER_DAY);
|
||||
|
||||
// Schedule pending deletes immediately. This has potential to overload
|
||||
// the server. However, the frequency of delete requests across all
|
||||
// clients should be low, so this shouldn't pose a problem.
|
||||
if (this.pendingDeleteRemoteData) {
|
||||
nextSubmissionDate = this.now();
|
||||
}
|
||||
|
||||
this.nextDataSubmissionDate = nextSubmissionDate;
|
||||
this.currentDaySubmissionFailureCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == request.NO_DATA_AVAILABLE) {
|
||||
if (request.isDelete) {
|
||||
this._log.info("Remote data delete requested but no remote data was stored.");
|
||||
this.pendingDeleteRemoteData = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this._log.info("No data was available to submit. May try later.");
|
||||
this._handleSubmissionFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't special case request.isDelete for these failures because it
|
||||
// likely means there was a server error.
|
||||
|
||||
if (state == request.SUBMISSION_FAILURE_SOFT) {
|
||||
this._log.warn("Soft error submitting data: " + reason);
|
||||
this.lastDataSubmissionFailureDate = this.now();
|
||||
@ -862,3 +990,4 @@ HealthReportPolicy.prototype = {
|
||||
};
|
||||
|
||||
Object.freeze(HealthReportPolicy.prototype);
|
||||
|
||||
|
@ -34,7 +34,8 @@ function run_test() {
|
||||
add_test(function test_constructor() {
|
||||
let prefs = new Preferences("foo.bar");
|
||||
let listener = {
|
||||
onRequestDataSubmission: function() {},
|
||||
onRequestDataUpload: function() {},
|
||||
onRequestRemoteDelete: function() {},
|
||||
onNotifyDataPolicy: function() {},
|
||||
};
|
||||
|
||||
@ -99,6 +100,10 @@ add_test(function test_prefs() {
|
||||
do_check_eq(prefs.get("currentDaySubmissionFailureCount", 0), 2);
|
||||
do_check_eq(policy.currentDaySubmissionFailureCount, 2);
|
||||
|
||||
policy.pendingDeleteRemoteData = true;
|
||||
do_check_true(prefs.get("pendingDeleteRemoteData"));
|
||||
do_check_true(policy.pendingDeleteRemoteData);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
@ -233,7 +238,7 @@ add_test(function test_notification_rejected() {
|
||||
// No requests for submission should occur if user has rejected.
|
||||
defineNow(policy, new Date(policy.nextDataSubmissionDate.getTime() + 10000));
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 0);
|
||||
do_check_eq(listener.requestDataUploadCount, 0);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@ -245,13 +250,30 @@ add_test(function test_submission_kill_switch() {
|
||||
policy.nextDataSubmissionDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
||||
policy.recordUserAcceptance("accept-old-ack");
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
defineNow(policy,
|
||||
new Date(Date.now() + policy.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC + 100));
|
||||
policy.dataSubmissionEnabled = false;
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_upload_kill_switch() {
|
||||
let [policy, prefs, listener] = getPolicy("upload_kill_switch");
|
||||
|
||||
defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
|
||||
policy.recordUserAcceptance();
|
||||
defineNow(policy, policy.nextDataSubmissionDate);
|
||||
|
||||
policy.dataUploadEnabled = false;
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 0);
|
||||
policy.dataUploadEnabled = true;
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@ -263,15 +285,15 @@ add_test(function test_data_submission_no_data() {
|
||||
policy.dataSubmissionPolicyAccepted = true;
|
||||
let now = new Date(policy.nextDataSubmissionDate.getTime() + 1);
|
||||
defineNow(policy, now);
|
||||
do_check_eq(listener.requestDataSubmissionCount, 0);
|
||||
do_check_eq(listener.requestDataUploadCount, 0);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
listener.lastDataRequest.onNoDataAvailable();
|
||||
|
||||
// The next trigger should try again.
|
||||
defineNow(policy, new Date(now.getTime() + 155 * 60 * 1000));
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 2);
|
||||
do_check_eq(listener.requestDataUploadCount, 2);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@ -286,7 +308,7 @@ add_test(function test_data_submission_submit_failure_hard() {
|
||||
defineNow(policy, now);
|
||||
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
listener.lastDataRequest.onSubmissionFailureHard();
|
||||
do_check_eq(listener.lastDataRequest.state,
|
||||
listener.lastDataRequest.SUBMISSION_FAILURE_HARD);
|
||||
@ -296,7 +318,7 @@ add_test(function test_data_submission_submit_failure_hard() {
|
||||
|
||||
defineNow(policy, new Date(now.getTime() + 10));
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@ -327,7 +349,7 @@ add_test(function test_submission_daily_scheduling() {
|
||||
let now = new Date(policy.nextDataSubmissionDate.getTime());
|
||||
defineNow(policy, now);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
do_check_eq(policy.lastDataSubmissionRequestedDate.getTime(), now.getTime());
|
||||
|
||||
let finishedDate = new Date(now.getTime() + 250);
|
||||
@ -344,11 +366,11 @@ add_test(function test_submission_daily_scheduling() {
|
||||
// Fast forward some arbitrary time. We shouldn't do any work yet.
|
||||
defineNow(policy, new Date(now.getTime() + 40000));
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
defineNow(policy, nextScheduled);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 2);
|
||||
do_check_eq(listener.requestDataUploadCount, 2);
|
||||
listener.lastDataRequest.onSubmissionSuccess(new Date(nextScheduled.getTime() + 200));
|
||||
do_check_eq(policy.nextDataSubmissionDate.getTime(),
|
||||
new Date(nextScheduled.getTime() + 24 * 60 * 60 * 1000 + 200).getTime());
|
||||
@ -368,12 +390,12 @@ add_test(function test_submission_far_future_scheduling() {
|
||||
let nextDate = policy._futureDate(3 * 24 * 60 * 60 * 1000 - 1);
|
||||
policy.nextDataSubmissionDate = nextDate;
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 0);
|
||||
do_check_eq(listener.requestDataUploadCount, 0);
|
||||
do_check_eq(policy.nextDataSubmissionDate.getTime(), nextDate.getTime());
|
||||
|
||||
policy.nextDataSubmissionDate = new Date(nextDate.getTime() + 1);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 0);
|
||||
do_check_eq(listener.requestDataUploadCount, 0);
|
||||
do_check_eq(policy.nextDataSubmissionDate.getTime(),
|
||||
policy._futureDate(24 * 60 * 60 * 1000).getTime());
|
||||
|
||||
@ -391,7 +413,7 @@ add_test(function test_submission_backoff() {
|
||||
let now = new Date(policy.nextDataSubmissionDate.getTime());
|
||||
defineNow(policy, now);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
do_check_eq(policy.currentDaySubmissionFailureCount, 0);
|
||||
|
||||
now = new Date(now.getTime() + 5000);
|
||||
@ -408,13 +430,13 @@ add_test(function test_submission_backoff() {
|
||||
now = new Date(policy.nextDataSubmissionDate.getTime() - 1);
|
||||
defineNow(policy, now);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
// 2nd request for submission.
|
||||
now = new Date(policy.nextDataSubmissionDate.getTime());
|
||||
defineNow(policy, now);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 2);
|
||||
do_check_eq(listener.requestDataUploadCount, 2);
|
||||
|
||||
now = new Date(now.getTime() + 5000);
|
||||
defineNow(policy, now);
|
||||
@ -428,7 +450,7 @@ add_test(function test_submission_backoff() {
|
||||
now = new Date(policy.nextDataSubmissionDate.getTime());
|
||||
defineNow(policy, now);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 3);
|
||||
do_check_eq(listener.requestDataUploadCount, 3);
|
||||
|
||||
now = new Date(now.getTime() + 5000);
|
||||
defineNow(policy, now);
|
||||
@ -452,16 +474,126 @@ add_test(function test_submission_expiring() {
|
||||
let now = new Date(policy.nextDataSubmissionDate.getTime());
|
||||
defineNow(policy, now);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
defineNow(policy, new Date(now.getTime() + 500));
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
defineNow(policy, new Date(policy.now().getTime() +
|
||||
policy.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC));
|
||||
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataSubmissionCount, 2);
|
||||
do_check_eq(listener.requestDataUploadCount, 2);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_delete_remote_data() {
|
||||
let [policy, prefs, listener] = getPolicy("delete_remote_data");
|
||||
|
||||
do_check_false(policy.pendingDeleteRemoteData);
|
||||
let nextSubmissionDate = policy.nextDataSubmissionDate;
|
||||
|
||||
let now = new Date();
|
||||
defineNow(policy, now);
|
||||
|
||||
policy.deleteRemoteData();
|
||||
do_check_true(policy.pendingDeleteRemoteData);
|
||||
do_check_neq(nextSubmissionDate.getTime(),
|
||||
policy.nextDataSubmissionDate.getTime());
|
||||
do_check_eq(now.getTime(), policy.nextDataSubmissionDate.getTime());
|
||||
|
||||
do_check_eq(listener.requestRemoteDeleteCount, 1);
|
||||
do_check_true(listener.lastRemoteDeleteRequest.isDelete);
|
||||
defineNow(policy, policy._futureDate(1000));
|
||||
|
||||
listener.lastRemoteDeleteRequest.onSubmissionSuccess(policy.now());
|
||||
do_check_false(policy.pendingDeleteRemoteData);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
// Ensure that deletion requests take priority over regular data submission.
|
||||
add_test(function test_delete_remote_data_priority() {
|
||||
let [policy, prefs, listener] = getPolicy("delete_remote_data_priority");
|
||||
|
||||
let now = new Date();
|
||||
defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
|
||||
policy.recordUserAcceptance();
|
||||
defineNow(policy, new Date(now.getTime() + 3 * 24 * 60 * 60 * 1000));
|
||||
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
policy._inProgressSubmissionRequest = null;
|
||||
|
||||
policy.deleteRemoteData();
|
||||
policy.checkStateAndTrigger();
|
||||
|
||||
do_check_eq(listener.requestRemoteDeleteCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_delete_remote_data_backoff() {
|
||||
let [policy, prefs, listener] = getPolicy("delete_remote_data_backoff");
|
||||
|
||||
let now = new Date();
|
||||
defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
|
||||
policy.recordUserAcceptance();
|
||||
defineNow(policy, now);
|
||||
policy.nextDataSubmissionDate = now;
|
||||
policy.deleteRemoteData();
|
||||
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestRemoteDeleteCount, 1);
|
||||
defineNow(policy, policy._futureDate(1000));
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 0);
|
||||
do_check_eq(listener.requestRemoteDeleteCount, 1);
|
||||
|
||||
defineNow(policy, policy._futureDate(500));
|
||||
listener.lastRemoteDeleteRequest.onSubmissionFailureSoft();
|
||||
defineNow(policy, policy._futureDate(50));
|
||||
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestRemoteDeleteCount, 1);
|
||||
|
||||
defineNow(policy, policy._futureDate(policy.FAILURE_BACKOFF_INTERVALS[0] - 50));
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestRemoteDeleteCount, 2);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
// If we request delete while an upload is in progress, delete should be
|
||||
// scheduled immediately after upload.
|
||||
add_test(function test_delete_remote_data_in_progress_upload() {
|
||||
let [policy, prefs, listener] = getPolicy("delete_remote_data_in_progress_upload");
|
||||
|
||||
let now = new Date();
|
||||
defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
|
||||
policy.recordUserAcceptance();
|
||||
defineNow(policy, policy.nextDataSubmissionDate);
|
||||
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
defineNow(policy, policy._futureDate(50 * 1000));
|
||||
|
||||
// If we request a delete during a pending request, nothing should be done.
|
||||
policy.deleteRemoteData();
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
do_check_eq(listener.requestRemoteDeleteCount, 0);
|
||||
|
||||
// Now wait a little bit and finish the request.
|
||||
defineNow(policy, policy._futureDate(10 * 1000));
|
||||
listener.lastDataRequest.onSubmissionSuccess(policy._futureDate(1000));
|
||||
defineNow(policy, policy._futureDate(5000));
|
||||
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
do_check_eq(listener.requestRemoteDeleteCount, 1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@ -489,7 +621,7 @@ add_test(function test_polling() {
|
||||
policy.stopPolling();
|
||||
|
||||
do_check_eq(listener.notifyUserCount, 0);
|
||||
do_check_eq(listener.requestDataSubmissionCount, 0);
|
||||
do_check_eq(listener.requestDataUploadCount, 0);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
@ -539,16 +671,16 @@ add_test(function test_polling_implicit_acceptance() {
|
||||
|
||||
if (count < 4) {
|
||||
do_check_false(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_eq(listener.requestDataSubmissionCount, 0);
|
||||
do_check_eq(listener.requestDataUploadCount, 0);
|
||||
} else {
|
||||
do_check_true(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_eq(policy.dataSubmissionPolicyResponseType,
|
||||
"accepted-implicit-time-elapsed");
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
}
|
||||
|
||||
if (count > 4) {
|
||||
do_check_eq(listener.requestDataSubmissionCount, 1);
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
policy.stopPolling();
|
||||
run_next_test();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user