307 lines
10 KiB
JavaScript
307 lines
10 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
const { Sqlite } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/Sqlite.sys.mjs"
|
|
);
|
|
const { FirefoxAdapter } = ChromeUtils.importESModule(
|
|
"resource://services-common/kinto-storage-adapter.sys.mjs"
|
|
);
|
|
|
|
// set up what we need to make storage adapters
|
|
const kintoFilename = "kinto.sqlite";
|
|
|
|
function do_get_kinto_connection() {
|
|
return FirefoxAdapter.openConnection({ path: kintoFilename });
|
|
}
|
|
|
|
function do_get_kinto_adapter(sqliteHandle) {
|
|
return new FirefoxAdapter("test", { sqliteHandle });
|
|
}
|
|
|
|
function do_get_kinto_db() {
|
|
let profile = do_get_profile();
|
|
let kintoDB = profile.clone();
|
|
kintoDB.append(kintoFilename);
|
|
return kintoDB;
|
|
}
|
|
|
|
function cleanup_kinto() {
|
|
add_test(function cleanup_kinto_files() {
|
|
let kintoDB = do_get_kinto_db();
|
|
// clean up the db
|
|
kintoDB.remove(false);
|
|
run_next_test();
|
|
});
|
|
}
|
|
|
|
function test_collection_operations() {
|
|
add_task(async function test_kinto_clear() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
await adapter.clear();
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
// test creating new records... and getting them again
|
|
add_task(async function test_kinto_create_new_get_existing() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
let record = { id: "test-id", foo: "bar" };
|
|
await adapter.execute(transaction => transaction.create(record));
|
|
let newRecord = await adapter.get("test-id");
|
|
// ensure the record is the same as when it was added
|
|
deepEqual(record, newRecord);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
// test removing records
|
|
add_task(async function test_kinto_can_remove_some_records() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
// create a second record
|
|
let record = { id: "test-id-2", foo: "baz" };
|
|
await adapter.execute(transaction => transaction.create(record));
|
|
let newRecord = await adapter.get("test-id-2");
|
|
deepEqual(record, newRecord);
|
|
// delete the record
|
|
await adapter.execute(transaction => transaction.delete(record.id));
|
|
newRecord = await adapter.get(record.id);
|
|
// ... and ensure it's no longer there
|
|
Assert.equal(newRecord, undefined);
|
|
// ensure the other record still exists
|
|
newRecord = await adapter.get("test-id");
|
|
Assert.notEqual(newRecord, undefined);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
// test getting records that don't exist
|
|
add_task(async function test_kinto_get_non_existant() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
// Kinto expects adapters to either:
|
|
let newRecord = await adapter.get("missing-test-id");
|
|
// resolve with an undefined record
|
|
Assert.equal(newRecord, undefined);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
// test updating records... and getting them again
|
|
add_task(async function test_kinto_update_get_existing() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
let originalRecord = { id: "test-id", foo: "bar" };
|
|
let updatedRecord = { id: "test-id", foo: "baz" };
|
|
await adapter.clear();
|
|
await adapter.execute(transaction => transaction.create(originalRecord));
|
|
await adapter.execute(transaction => transaction.update(updatedRecord));
|
|
// ensure the record exists
|
|
let newRecord = await adapter.get("test-id");
|
|
// ensure the record is the same as when it was added
|
|
deepEqual(updatedRecord, newRecord);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
// test listing records
|
|
add_task(async function test_kinto_list() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
let originalRecord = { id: "test-id-1", foo: "bar" };
|
|
let records = await adapter.list();
|
|
Assert.equal(records.length, 1);
|
|
await adapter.execute(transaction => transaction.create(originalRecord));
|
|
records = await adapter.list();
|
|
Assert.equal(records.length, 2);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
// test aborting transaction
|
|
add_task(async function test_kinto_aborting_transaction() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
await adapter.clear();
|
|
let record = { id: 1, foo: "bar" };
|
|
let error = null;
|
|
try {
|
|
await adapter.execute(transaction => {
|
|
transaction.create(record);
|
|
throw new Error("unexpected");
|
|
});
|
|
} catch (e) {
|
|
error = e;
|
|
}
|
|
Assert.notEqual(error, null);
|
|
let records = await adapter.list();
|
|
Assert.equal(records.length, 0);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
// test save and get last modified
|
|
add_task(async function test_kinto_last_modified() {
|
|
const initialValue = 0;
|
|
const intendedValue = 12345678;
|
|
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
let lastModified = await adapter.getLastModified();
|
|
Assert.equal(lastModified, initialValue);
|
|
let result = await adapter.saveLastModified(intendedValue);
|
|
Assert.equal(result, intendedValue);
|
|
lastModified = await adapter.getLastModified();
|
|
Assert.equal(lastModified, intendedValue);
|
|
|
|
// test saveLastModified parses values correctly
|
|
result = await adapter.saveLastModified(" " + intendedValue + " blah");
|
|
// should resolve with the parsed int
|
|
Assert.equal(result, intendedValue);
|
|
// and should have saved correctly
|
|
lastModified = await adapter.getLastModified();
|
|
Assert.equal(lastModified, intendedValue);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
// test loadDump(records)
|
|
add_task(async function test_kinto_import_records() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
let record1 = { id: 1, foo: "bar" };
|
|
let record2 = { id: 2, foo: "baz" };
|
|
let impactedRecords = await adapter.loadDump([record1, record2]);
|
|
Assert.equal(impactedRecords.length, 2);
|
|
let newRecord1 = await adapter.get("1");
|
|
// ensure the record is the same as when it was added
|
|
deepEqual(record1, newRecord1);
|
|
let newRecord2 = await adapter.get("2");
|
|
// ensure the record is the same as when it was added
|
|
deepEqual(record2, newRecord2);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
add_task(async function test_kinto_import_records_should_override_existing() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
await adapter.clear();
|
|
let records = await adapter.list();
|
|
Assert.equal(records.length, 0);
|
|
let impactedRecords = await adapter.loadDump([
|
|
{ id: 1, foo: "bar" },
|
|
{ id: 2, foo: "baz" },
|
|
]);
|
|
Assert.equal(impactedRecords.length, 2);
|
|
await adapter.loadDump([
|
|
{ id: 1, foo: "baz" },
|
|
{ id: 3, foo: "bab" },
|
|
]);
|
|
records = await adapter.list();
|
|
Assert.equal(records.length, 3);
|
|
let newRecord1 = await adapter.get("1");
|
|
deepEqual(newRecord1.foo, "baz");
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
add_task(async function test_import_updates_lastModified() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
await adapter.loadDump([
|
|
{ id: 1, foo: "bar", last_modified: 1457896541 },
|
|
{ id: 2, foo: "baz", last_modified: 1458796542 },
|
|
]);
|
|
let lastModified = await adapter.getLastModified();
|
|
Assert.equal(lastModified, 1458796542);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
add_task(async function test_import_preserves_older_lastModified() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
await adapter.saveLastModified(1458796543);
|
|
|
|
await adapter.loadDump([
|
|
{ id: 1, foo: "bar", last_modified: 1457896541 },
|
|
{ id: 2, foo: "baz", last_modified: 1458796542 },
|
|
]);
|
|
let lastModified = await adapter.getLastModified();
|
|
Assert.equal(lastModified, 1458796543);
|
|
await sqliteHandle.close();
|
|
});
|
|
|
|
add_task(async function test_save_metadata_preserves_lastModified() {
|
|
let sqliteHandle = await do_get_kinto_connection();
|
|
|
|
let adapter = do_get_kinto_adapter(sqliteHandle);
|
|
await adapter.saveLastModified(42);
|
|
|
|
await adapter.saveMetadata({ id: "col" });
|
|
|
|
let lastModified = await adapter.getLastModified();
|
|
Assert.equal(lastModified, 42);
|
|
await sqliteHandle.close();
|
|
});
|
|
}
|
|
|
|
// test kinto db setup and operations in various scenarios
|
|
// test from scratch - no current existing database
|
|
add_test(function test_db_creation() {
|
|
add_test(function test_create_from_scratch() {
|
|
// ensure the file does not exist in the profile
|
|
let kintoDB = do_get_kinto_db();
|
|
Assert.ok(!kintoDB.exists());
|
|
run_next_test();
|
|
});
|
|
|
|
test_collection_operations();
|
|
|
|
cleanup_kinto();
|
|
run_next_test();
|
|
});
|
|
|
|
// this is the closest we can get to a schema version upgrade at v1 - test an
|
|
// existing database
|
|
add_test(function test_creation_from_empty_db() {
|
|
add_test(function test_create_from_empty_db() {
|
|
// place an empty kinto db file in the profile
|
|
let profile = do_get_profile();
|
|
|
|
let emptyDB = do_get_file("test_storage_adapter/empty.sqlite");
|
|
emptyDB.copyTo(profile, kintoFilename);
|
|
|
|
run_next_test();
|
|
});
|
|
|
|
test_collection_operations();
|
|
|
|
cleanup_kinto();
|
|
run_next_test();
|
|
});
|
|
|
|
// test schema version upgrade at v2
|
|
add_test(function test_migration_from_v1_to_v2() {
|
|
add_test(function test_migrate_from_v1_to_v2() {
|
|
// place an empty kinto db file in the profile
|
|
let profile = do_get_profile();
|
|
|
|
let v1DB = do_get_file("test_storage_adapter/v1.sqlite");
|
|
v1DB.copyTo(profile, kintoFilename);
|
|
|
|
run_next_test();
|
|
});
|
|
|
|
add_test(async function schema_is_update_from_1_to_2() {
|
|
// The `v1.sqlite` has schema version 1.
|
|
let sqliteHandle = await Sqlite.openConnection({ path: kintoFilename });
|
|
Assert.equal(await sqliteHandle.getSchemaVersion(), 1);
|
|
await sqliteHandle.close();
|
|
|
|
// The `.openConnection()` migrates it to version 2.
|
|
sqliteHandle = await FirefoxAdapter.openConnection({ path: kintoFilename });
|
|
Assert.equal(await sqliteHandle.getSchemaVersion(), 2);
|
|
await sqliteHandle.close();
|
|
|
|
run_next_test();
|
|
});
|
|
|
|
test_collection_operations();
|
|
|
|
cleanup_kinto();
|
|
run_next_test();
|
|
});
|