Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

const PREF_SETTINGS_SERVER = "services.settings.server";
let server;
let client;
async function clear_state() {
await client.db.clear();
}
function setJSONResponse(response, changeset) {
response.setStatusLine(null, 200, "OK");
response.setHeader("Content-Type", "application/json; charset=UTF-8");
response.setHeader("Date", new Date().toUTCString());
response.write(JSON.stringify(changeset));
}
add_setup(() => {
Services.prefs.setStringPref("services.settings.loglevel", "debug");
// Set up an HTTP Server
server = new HttpServer();
server.start(-1);
Services.prefs.setStringPref(
PREF_SETTINGS_SERVER,
`http://localhost:${server.identity.primaryPort}/v1`
);
client = RemoteSettings("some-cid");
const bodies = {
// First successful sync at timestamp=333
"/v1/buckets/main/collections/some-cid/changeset?_expected=333": {
timestamp: 333,
metadata: {
signature: { signature: "abc", x5u: "data:text/plain;base64,pem" },
},
changes: [
{ id: "rid2", last_modified: 22 },
{ id: "rid1", last_modified: 11 },
],
},
// Client fetches with _expected=222&_since=333
"/v1/buckets/main/collections/some-cid/changeset?_expected=222&_since=%22333%22":
{
timestamp: 222,
metadata: {
signature: { signature: "ghi", x5u: "data:text/plain;base64,pem" },
},
changes: [{ id: "rid1", last_modified: 11 }],
},
// Client refetches full collection with _expected=222 after signature fails.
"/v1/buckets/main/collections/some-cid/changeset?_expected=222": {
timestamp: 222,
metadata: {
signature: { signature: "ghi", x5u: "data:text/plain;base64,pem" },
},
changes: [{ id: "rid1", last_modified: 11 }],
},
};
const handler = (request, response) => {
const body = bodies[`${request.path}?${request.queryString}`];
if (!body) {
const err = new Error(
`Unexpected request ${request.path}?${request.queryString}`
);
console.error(err);
throw err;
}
setJSONResponse(response, body);
};
Object.keys(bodies).map(path =>
server.registerPathHandler(path.split("?")[0], handler)
);
// In this test suite, the only valid data is the one at timestamp=222 or timestamp=333, but not a mix of the two.
let backup = client._verifier;
client._verifier = {
asyncVerifyContentSignature: serialized => {
return (
serialized ==
'{"data":[{"id":"rid2","last_modified":22}],"last_modified":"444"}' ||
serialized ==
'{"data":[{"id":"rid1","last_modified":11},{"id":"rid2","last_modified":22}],"last_modified":"333"}' ||
serialized ==
'{"data":[{"id":"rid1","last_modified":11}],"last_modified":"222"}'
);
},
};
registerCleanupFunction(() => {
client._verifier = backup;
server.stop(() => {});
Services.prefs.clearUserPref(PREF_SETTINGS_SERVER);
Services.prefs.clearUserPref("services.settings.loglevel");
});
});
add_task(clear_state);
add_task(async function test_ignores_if_local_signature_is_valid() {
await client.maybeSync(333);
Assert.deepEqual(
[
await client.db.getLastModified(),
(await client.get()).map(({ id }) => id),
],
[333, ["rid1", "rid2"]]
);
await client.maybeSync(222);
// The client should detect that timestamp is older,
// but it ignores it because local data is good.
Assert.deepEqual(
[
await client.db.getLastModified(),
(await client.get()).map(({ id }) => id),
],
[333, ["rid1", "rid2"]]
);
});
add_task(clear_state);
add_task(async function test_uses_old_data_if_local_signature_is_invalid() {
// Import some data in the local DB. Signature will be bad.
await client.db.importChanges({}, 333, [{ id: "myid", last_modified: 1234 }]);
Assert.deepEqual(
[
await client.db.getLastModified(),
(await client.get()).map(({ id }) => id),
],
[333, ["myid"]]
);
await client.maybeSync(222);
// The client should detect that timestamp is older,
// but will replace local data with this old data.
Assert.deepEqual(
[
await client.db.getLastModified(),
(await client.get()).map(({ id }) => id),
],
[222, ["rid1"]]
);
});
add_task(clear_state);