mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Bug 906139 - Preserve unknown fields found in downloads.json. r=paolo
This commit is contained in:
parent
23ce61e5d5
commit
6fed774f8a
@ -92,6 +92,36 @@ function isString(aValue) {
|
||||
(typeof aValue == "object" && "charAt" in aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the unknown properties of aObject into aSerializable.
|
||||
*/
|
||||
function serializeUnknownProperties(aObject, aSerializable)
|
||||
{
|
||||
if (aObject._unknownProperties) {
|
||||
for (let property in aObject._unknownProperties) {
|
||||
aSerializable[property] = aObject._unknownProperties[property];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for any unknown properties in aSerializable and preserve those in the
|
||||
* _unknownProperties field of aObject. aFilterFn is called for each property
|
||||
* name of aObject and should return true only for unknown properties.
|
||||
*/
|
||||
function deserializeUnknownProperties(aObject, aSerializable, aFilterFn)
|
||||
{
|
||||
for (let property in aSerializable) {
|
||||
if (aFilterFn(property)) {
|
||||
if (!aObject._unknownProperties) {
|
||||
aObject._unknownProperties = { };
|
||||
}
|
||||
|
||||
aObject._unknownProperties[property] = aSerializable[property];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This determines the minimum time interval between updates to the number of
|
||||
* bytes transferred, and is a limiting factor to the sequence of readings used
|
||||
@ -838,11 +868,13 @@ Download.prototype = {
|
||||
|
||||
// These are serialized unless they are false, null, or empty strings.
|
||||
for (let property of kSerializableDownloadProperties) {
|
||||
if (property != "error" && this[property]) {
|
||||
if (property != "error" && property != "startTime" && this[property]) {
|
||||
serializable[property] = this[property];
|
||||
}
|
||||
}
|
||||
|
||||
serializeUnknownProperties(this, serializable);
|
||||
|
||||
return serializable;
|
||||
},
|
||||
|
||||
@ -933,6 +965,13 @@ Download.fromSerializable = function (aSerializable) {
|
||||
}
|
||||
}
|
||||
|
||||
deserializeUnknownProperties(download, aSerializable, property =>
|
||||
kSerializableDownloadProperties.indexOf(property) == -1 &&
|
||||
property != "startTime" &&
|
||||
property != "source" &&
|
||||
property != "target" &&
|
||||
property != "saver");
|
||||
|
||||
return download;
|
||||
};
|
||||
|
||||
@ -971,7 +1010,7 @@ DownloadSource.prototype = {
|
||||
toSerializable: function ()
|
||||
{
|
||||
// Simplify the representation if we don't have other details.
|
||||
if (!this.isPrivate && !this.referrer) {
|
||||
if (!this.isPrivate && !this.referrer && !this._unknownProperties) {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
@ -982,6 +1021,8 @@ DownloadSource.prototype = {
|
||||
if (this.referrer) {
|
||||
serializable.referrer = this.referrer;
|
||||
}
|
||||
|
||||
serializeUnknownProperties(this, serializable);
|
||||
return serializable;
|
||||
},
|
||||
};
|
||||
@ -1020,7 +1061,11 @@ DownloadSource.fromSerializable = function (aSerializable) {
|
||||
if ("referrer" in aSerializable) {
|
||||
source.referrer = aSerializable.referrer;
|
||||
}
|
||||
|
||||
deserializeUnknownProperties(source, aSerializable, property =>
|
||||
property != "url" && property != "isPrivate" && property != "referrer");
|
||||
}
|
||||
|
||||
return source;
|
||||
};
|
||||
|
||||
@ -1054,12 +1099,14 @@ DownloadTarget.prototype = {
|
||||
toSerializable: function ()
|
||||
{
|
||||
// Simplify the representation if we don't have other details.
|
||||
if (!this.partFilePath) {
|
||||
if (!this.partFilePath && !this._unknownProperties) {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
return { path: this.path,
|
||||
partFilePath: this.partFilePath };
|
||||
let serializable = { path: this.path,
|
||||
partFilePath: this.partFilePath };
|
||||
serializeUnknownProperties(this, serializable);
|
||||
return serializable;
|
||||
},
|
||||
};
|
||||
|
||||
@ -1072,6 +1119,7 @@ DownloadTarget.prototype = {
|
||||
* object with the following properties:
|
||||
* {
|
||||
* path: String containing the path of the target file.
|
||||
* partFilePath: optional string containing the part file path.
|
||||
* }
|
||||
*
|
||||
* @return The newly created DownloadTarget object.
|
||||
@ -1091,6 +1139,9 @@ DownloadTarget.fromSerializable = function (aSerializable) {
|
||||
if ("partFilePath" in aSerializable) {
|
||||
target.partFilePath = aSerializable.partFilePath;
|
||||
}
|
||||
|
||||
deserializeUnknownProperties(target, aSerializable, property =>
|
||||
property != "path" && property != "partFilePath");
|
||||
}
|
||||
return target;
|
||||
};
|
||||
@ -1598,12 +1649,14 @@ DownloadCopySaver.prototype = {
|
||||
toSerializable: function ()
|
||||
{
|
||||
// Simplify the representation if we don't have other details.
|
||||
if (!this.entityID) {
|
||||
if (!this.entityID && !this._unknownProperties) {
|
||||
return "copy";
|
||||
}
|
||||
|
||||
return { type: "copy",
|
||||
entityID: this.entityID };
|
||||
let serializable = { type: "copy",
|
||||
entityID: this.entityID };
|
||||
serializeUnknownProperties(this, serializable);
|
||||
return serializable;
|
||||
},
|
||||
};
|
||||
|
||||
@ -1621,6 +1674,10 @@ DownloadCopySaver.fromSerializable = function (aSerializable) {
|
||||
if ("entityID" in aSerializable) {
|
||||
saver.entityID = aSerializable.entityID;
|
||||
}
|
||||
|
||||
deserializeUnknownProperties(saver, aSerializable, property =>
|
||||
property != "entityID" && property != "type");
|
||||
|
||||
return saver;
|
||||
};
|
||||
|
||||
|
@ -215,3 +215,78 @@ add_task(function test_load_string_malformed()
|
||||
|
||||
do_check_eq(items.length, 0);
|
||||
});
|
||||
|
||||
/**
|
||||
* Saves downloads with unknown properties to a file and then reloads
|
||||
* them to ensure that these properties are preserved.
|
||||
*/
|
||||
add_task(function test_save_reload_unknownProperties()
|
||||
{
|
||||
let [listForSave, storeForSave] = yield promiseNewListAndStore();
|
||||
let [listForLoad, storeForLoad] = yield promiseNewListAndStore(
|
||||
storeForSave.path);
|
||||
|
||||
let download1 = yield promiseNewDownload(httpUrl("source.txt"));
|
||||
// startTime should be ignored as it is a known property, and error
|
||||
// is ignored by serialization
|
||||
download1._unknownProperties = { peanut: "butter",
|
||||
orange: "marmalade",
|
||||
startTime: 77,
|
||||
error: { message: "Passed" } };
|
||||
listForSave.add(download1);
|
||||
|
||||
let download2 = yield promiseStartLegacyDownload();
|
||||
yield download2.cancel();
|
||||
download2._unknownProperties = { number: 5, object: { test: "string" } };
|
||||
listForSave.add(download2);
|
||||
|
||||
let download3 = yield Downloads.createDownload({
|
||||
source: { url: httpUrl("empty.txt"),
|
||||
referrer: TEST_REFERRER_URL,
|
||||
source1: "download3source1",
|
||||
source2: "download3source2" },
|
||||
target: { path: getTempFile(TEST_TARGET_FILE_NAME).path,
|
||||
target1: "download3target1",
|
||||
target2: "download3target2" },
|
||||
saver : { type: "copy",
|
||||
saver1: "download3saver1",
|
||||
saver2: "download3saver2" },
|
||||
});
|
||||
listForSave.add(download3);
|
||||
|
||||
yield storeForSave.save();
|
||||
yield storeForLoad.load();
|
||||
|
||||
let itemsForSave = yield listForSave.getAll();
|
||||
let itemsForLoad = yield listForLoad.getAll();
|
||||
|
||||
do_check_eq(itemsForSave.length, itemsForLoad.length);
|
||||
|
||||
do_check_eq(Object.keys(itemsForLoad[0]._unknownProperties).length, 2);
|
||||
do_check_eq(itemsForLoad[0]._unknownProperties.peanut, "butter");
|
||||
do_check_eq(itemsForLoad[0]._unknownProperties.orange, "marmalade");
|
||||
do_check_false("startTime" in itemsForLoad[0]._unknownProperties);
|
||||
do_check_false("error" in itemsForLoad[0]._unknownProperties);
|
||||
|
||||
do_check_eq(Object.keys(itemsForLoad[1]._unknownProperties).length, 2);
|
||||
do_check_eq(itemsForLoad[1]._unknownProperties.number, 5);
|
||||
do_check_eq(itemsForLoad[1]._unknownProperties.object.test, "string");
|
||||
|
||||
do_check_eq(Object.keys(itemsForLoad[2].source._unknownProperties).length, 2);
|
||||
do_check_eq(itemsForLoad[2].source._unknownProperties.source1,
|
||||
"download3source1");
|
||||
do_check_eq(itemsForLoad[2].source._unknownProperties.source2,
|
||||
"download3source2");
|
||||
|
||||
do_check_eq(Object.keys(itemsForLoad[2].target._unknownProperties).length, 2);
|
||||
do_check_eq(itemsForLoad[2].target._unknownProperties.target1,
|
||||
"download3target1");
|
||||
do_check_eq(itemsForLoad[2].target._unknownProperties.target2,
|
||||
"download3target2");
|
||||
|
||||
do_check_eq(Object.keys(itemsForLoad[2].saver._unknownProperties).length, 2);
|
||||
do_check_eq(itemsForLoad[2].saver._unknownProperties.saver1,
|
||||
"download3saver1");
|
||||
do_check_eq(itemsForLoad[2].saver._unknownProperties.saver2,
|
||||
"download3saver2");
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user