mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 23:05:42 +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);
|
(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
|
* 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
|
* 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.
|
// These are serialized unless they are false, null, or empty strings.
|
||||||
for (let property of kSerializableDownloadProperties) {
|
for (let property of kSerializableDownloadProperties) {
|
||||||
if (property != "error" && this[property]) {
|
if (property != "error" && property != "startTime" && this[property]) {
|
||||||
serializable[property] = this[property];
|
serializable[property] = this[property];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serializeUnknownProperties(this, serializable);
|
||||||
|
|
||||||
return 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;
|
return download;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -971,7 +1010,7 @@ DownloadSource.prototype = {
|
|||||||
toSerializable: function ()
|
toSerializable: function ()
|
||||||
{
|
{
|
||||||
// Simplify the representation if we don't have other details.
|
// 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;
|
return this.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -982,6 +1021,8 @@ DownloadSource.prototype = {
|
|||||||
if (this.referrer) {
|
if (this.referrer) {
|
||||||
serializable.referrer = this.referrer;
|
serializable.referrer = this.referrer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serializeUnknownProperties(this, serializable);
|
||||||
return serializable;
|
return serializable;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -1020,7 +1061,11 @@ DownloadSource.fromSerializable = function (aSerializable) {
|
|||||||
if ("referrer" in aSerializable) {
|
if ("referrer" in aSerializable) {
|
||||||
source.referrer = aSerializable.referrer;
|
source.referrer = aSerializable.referrer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deserializeUnknownProperties(source, aSerializable, property =>
|
||||||
|
property != "url" && property != "isPrivate" && property != "referrer");
|
||||||
}
|
}
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1054,12 +1099,14 @@ DownloadTarget.prototype = {
|
|||||||
toSerializable: function ()
|
toSerializable: function ()
|
||||||
{
|
{
|
||||||
// Simplify the representation if we don't have other details.
|
// Simplify the representation if we don't have other details.
|
||||||
if (!this.partFilePath) {
|
if (!this.partFilePath && !this._unknownProperties) {
|
||||||
return this.path;
|
return this.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { path: this.path,
|
let serializable = { path: this.path,
|
||||||
partFilePath: this.partFilePath };
|
partFilePath: this.partFilePath };
|
||||||
|
serializeUnknownProperties(this, serializable);
|
||||||
|
return serializable;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1072,6 +1119,7 @@ DownloadTarget.prototype = {
|
|||||||
* object with the following properties:
|
* object with the following properties:
|
||||||
* {
|
* {
|
||||||
* path: String containing the path of the target file.
|
* path: String containing the path of the target file.
|
||||||
|
* partFilePath: optional string containing the part file path.
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @return The newly created DownloadTarget object.
|
* @return The newly created DownloadTarget object.
|
||||||
@ -1091,6 +1139,9 @@ DownloadTarget.fromSerializable = function (aSerializable) {
|
|||||||
if ("partFilePath" in aSerializable) {
|
if ("partFilePath" in aSerializable) {
|
||||||
target.partFilePath = aSerializable.partFilePath;
|
target.partFilePath = aSerializable.partFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deserializeUnknownProperties(target, aSerializable, property =>
|
||||||
|
property != "path" && property != "partFilePath");
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
};
|
};
|
||||||
@ -1598,12 +1649,14 @@ DownloadCopySaver.prototype = {
|
|||||||
toSerializable: function ()
|
toSerializable: function ()
|
||||||
{
|
{
|
||||||
// Simplify the representation if we don't have other details.
|
// Simplify the representation if we don't have other details.
|
||||||
if (!this.entityID) {
|
if (!this.entityID && !this._unknownProperties) {
|
||||||
return "copy";
|
return "copy";
|
||||||
}
|
}
|
||||||
|
|
||||||
return { type: "copy",
|
let serializable = { type: "copy",
|
||||||
entityID: this.entityID };
|
entityID: this.entityID };
|
||||||
|
serializeUnknownProperties(this, serializable);
|
||||||
|
return serializable;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1621,6 +1674,10 @@ DownloadCopySaver.fromSerializable = function (aSerializable) {
|
|||||||
if ("entityID" in aSerializable) {
|
if ("entityID" in aSerializable) {
|
||||||
saver.entityID = aSerializable.entityID;
|
saver.entityID = aSerializable.entityID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deserializeUnknownProperties(saver, aSerializable, property =>
|
||||||
|
property != "entityID" && property != "type");
|
||||||
|
|
||||||
return saver;
|
return saver;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -215,3 +215,78 @@ add_task(function test_load_string_malformed()
|
|||||||
|
|
||||||
do_check_eq(items.length, 0);
|
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