Bug 1376618 - Load initial blocklist data as synced r=mgoodwin
MozReview-Commit-ID: FZ5XDv4FCEo
--- a/services/common/blocklist-clients.js
+++ b/services/common/blocklist-clients.js
@@ -219,17 +219,17 @@ class BlocklistClient {
// If there is no data currently in the collection, attempt to import
// initial data from the application defaults.
// This allows to avoid synchronizing the whole collection content on
// cold start.
if (!collectionLastModified && loadDump) {
try {
const initialData = await this.loadDumpFile();
- await collection.db.loadDump(initialData.data);
+ await collection.loadDump(initialData.data);
collectionLastModified = await collection.db.getLastModified();
} catch (e) {
// Report but go-on.
Cu.reportError(e);
}
}
// If the data is up to date, there's no need to sync. We still need
@@ -237,17 +237,19 @@ class BlocklistClient {
if (lastModified <= collectionLastModified) {
this.updateLastCheck(serverTime);
reportStatus = UptakeTelemetry.STATUS.UP_TO_DATE;
return;
}
// Fetch changes from server.
try {
- const {ok} = await collection.sync({remote});
+ // Server changes have priority during synchronization.
+ const strategy = Kinto.syncStrategy.SERVER_WINS;
+ const {ok} = await collection.sync({remote, strategy});
if (!ok) {
// Some synchronization conflicts occured.
reportStatus = UptakeTelemetry.STATUS.CONFLICT_ERROR;
throw new Error("Sync failed");
}
} catch (e) {
if (e.message == INVALID_SIGNATURE) {
// Signature verification failed during synchronzation.
--- a/services/common/tests/unit/test_blocklist_clients.js
+++ b/services/common/tests/unit/test_blocklist_clients.js
@@ -109,32 +109,63 @@ function run_test() {
run_next_test();
do_register_cleanup(function() {
server.stop(() => { });
});
}
+add_task(async function test_initial_dump_is_loaded_as_synced_when_collection_is_empty() {
+ for (let {client} of gBlocklistClients) {
+ // Test an empty db populates, but don't reach server (specified timestamp <= dump).
+ await client.maybeSync(1, Date.now());
+
+ // Open the collection, verify the loaded data has status to synced:
+ const sqliteHandle = await FirefoxAdapter.openConnection({path: kintoFilename});
+ const collection = kintoCollection(client.collectionName, sqliteHandle);
+ const list = await collection.list();
+ equal(list.data[0]._status, "synced");
+ await sqliteHandle.close();
+ }
+});
+add_task(clear_state);
+
add_task(async function test_records_obtained_from_server_are_stored_in_db() {
for (let {client} of gBlocklistClients) {
// Test an empty db populates
await client.maybeSync(2000, Date.now(), {loadDump: false});
// Open the collection, verify it's been populated:
// Our test data has a single record; it should be in the local collection
const sqliteHandle = await FirefoxAdapter.openConnection({path: kintoFilename});
let collection = kintoCollection(client.collectionName, sqliteHandle);
let list = await collection.list();
equal(list.data.length, 1);
await sqliteHandle.close();
}
});
add_task(clear_state);
+add_task(async function test_records_changes_are_overwritten_by_server_changes() {
+ const {client} = gBlocklistClients[0];
+
+ // Create some local conflicting data, and make sure it syncs without error.
+ const sqliteHandle = await FirefoxAdapter.openConnection({path: kintoFilename});
+ const collection = kintoCollection(client.collectionName, sqliteHandle);
+ await collection.create({
+ "versionRange": [],
+ "id": "9d500963-d80e-3a91-6e74-66f3811b99cc"
+ }, { useRecordId: true });
+ await sqliteHandle.close();
+
+ await client.maybeSync(2000, Date.now(), {loadDump: false});
+});
+add_task(clear_state);
+
add_task(async function test_list_is_written_to_file_in_profile() {
for (let {client, testData} of gBlocklistClients) {
const filePath = OS.Path.join(OS.Constants.Path.profileDir, client.filename);
const profFile = new FileUtils.File(filePath);
strictEqual(profFile.exists(), false);
await client.maybeSync(2000, Date.now(), {loadDump: false});