1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-13 22:12:50 +02:00
This commit is contained in:
Laurent Cozic
2017-06-19 20:26:27 +01:00
parent cb7067ddf4
commit c6ed94b446
9 changed files with 120 additions and 132 deletions

View File

@@ -31,7 +31,7 @@ async function localItemsSameAsRemote(locals, expect) {
expect(remote.updated_time).toBe(dbItem.updated_time);
let remoteContent = await fileApi().get(path);
remoteContent = dbItem.type_ == BaseModel.ITEM_TYPE_NOTE ? Note.unserialize(remoteContent) : Folder.unserialize(remoteContent);
remoteContent = dbItem.type_ == BaseModel.MODEL_TYPE_NOTE ? Note.unserialize(remoteContent) : Folder.unserialize(remoteContent);
expect(remoteContent.title).toBe(dbItem.title);
}
} catch (error) {
@@ -48,139 +48,139 @@ describe('Synchronizer', function() {
done();
});
// it('should create remote items', async (done) => {
// let folder = await Folder.save({ title: "folder1" });
// await Note.save({ title: "un", parent_id: folder.id });
it('should create remote items', async (done) => {
let folder = await Folder.save({ title: "folder1" });
await Note.save({ title: "un", parent_id: folder.id });
// let all = await Folder.all(true);
let all = await Folder.all(true);
// await synchronizer().start();
await synchronizer().start();
// await localItemsSameAsRemote(all, expect);
await localItemsSameAsRemote(all, expect);
// done();
// });
done();
});
// it('should update remote item', async (done) => {
// let folder = await Folder.save({ title: "folder1" });
// let note = await Note.save({ title: "un", parent_id: folder.id });
// await synchronizer().start();
it('should update remote item', async (done) => {
let folder = await Folder.save({ title: "folder1" });
let note = await Note.save({ title: "un", parent_id: folder.id });
await synchronizer().start();
// await sleep(0.1);
await sleep(0.1);
// await Note.save({ title: "un UPDATE", id: note.id });
await Note.save({ title: "un UPDATE", id: note.id });
// let all = await Folder.all(true);
// await synchronizer().start();
let all = await Folder.all(true);
await synchronizer().start();
// await localItemsSameAsRemote(all, expect);
await localItemsSameAsRemote(all, expect);
// done();
// });
done();
});
// it('should create local items', async (done) => {
// let folder = await Folder.save({ title: "folder1" });
// await Note.save({ title: "un", parent_id: folder.id });
// await synchronizer().start();
it('should create local items', async (done) => {
let folder = await Folder.save({ title: "folder1" });
await Note.save({ title: "un", parent_id: folder.id });
await synchronizer().start();
// switchClient(2);
switchClient(2);
// await synchronizer().start();
await synchronizer().start();
// let all = await Folder.all(true);
// await localItemsSameAsRemote(all, expect);
let all = await Folder.all(true);
await localItemsSameAsRemote(all, expect);
// done();
// });
done();
});
// it('should update local items', async (done) => {
// let folder1 = await Folder.save({ title: "folder1" });
// let note1 = await Note.save({ title: "un", parent_id: folder1.id });
// await synchronizer().start();
it('should update local items', async (done) => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: "un", parent_id: folder1.id });
await synchronizer().start();
// switchClient(2);
switchClient(2);
// await synchronizer().start();
await synchronizer().start();
// await sleep(0.1);
await sleep(0.1);
// let note2 = await Note.load(note1.id);
// note2.title = "Updated on client 2";
// await Note.save(note2);
let note2 = await Note.load(note1.id);
note2.title = "Updated on client 2";
await Note.save(note2);
// note2 = await Note.load(note2.id);
note2 = await Note.load(note2.id);
// await synchronizer().start();
await synchronizer().start();
// let files = await fileApi().list();
let files = await fileApi().list();
// switchClient(1);
switchClient(1);
// await synchronizer().start();
await synchronizer().start();
// note1 = await Note.load(note1.id);
note1 = await Note.load(note1.id);
// expect(!!note1).toBe(true);
// expect(note1.title).toBe(note2.title);
// expect(note1.body).toBe(note2.body);
expect(!!note1).toBe(true);
expect(note1.title).toBe(note2.title);
expect(note1.body).toBe(note2.body);
// done();
// });
done();
});
// it('should resolve note conflicts', async (done) => {
// let folder1 = await Folder.save({ title: "folder1" });
// let note1 = await Note.save({ title: "un", parent_id: folder1.id });
// await synchronizer().start();
it('should resolve note conflicts', async (done) => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: "un", parent_id: folder1.id });
await synchronizer().start();
// switchClient(2);
switchClient(2);
// await synchronizer().start();
await synchronizer().start();
// await sleep(0.1);
await sleep(0.1);
// let note2 = await Note.load(note1.id);
// note2.title = "Updated on client 2";
// await Note.save(note2);
// note2 = await Note.load(note2.id);
let note2 = await Note.load(note1.id);
note2.title = "Updated on client 2";
await Note.save(note2);
note2 = await Note.load(note2.id);
// await synchronizer().start();
await synchronizer().start();
// switchClient(1);
switchClient(1);
// await sleep(0.1);
await sleep(0.1);
// let note2conf = await Note.load(note1.id);
// note2conf.title = "Updated on client 1";
// await Note.save(note2conf);
// note2conf = await Note.load(note1.id);
let note2conf = await Note.load(note1.id);
note2conf.title = "Updated on client 1";
await Note.save(note2conf);
note2conf = await Note.load(note1.id);
// await synchronizer().start();
await synchronizer().start();
// let conflictFolder = await Folder.conflictFolder();
// let conflictedNotes = await Note.all(conflictFolder.id);
let conflictFolder = await Folder.conflictFolder();
let conflictedNotes = await Note.all(conflictFolder.id);
// expect(conflictedNotes.length).toBe(1);
expect(conflictedNotes.length).toBe(1);
// // Other than the id (since the conflicted note is a duplicate), parent_id (which is now the Conflicts folder) and sync_time,
// // the note must be the same in every way, to make sure no data has been lost.
// let conflictedNote = conflictedNotes[0];
// expect(conflictedNote.id == note2conf.id).toBe(false);
// expect(conflictedNote.parent_id == note2conf.parent_id).toBe(false);
// for (let n in conflictedNote) {
// if (!conflictedNote.hasOwnProperty(n)) continue;
// if (n == 'id' || n == 'parent_id') continue;
// expect(conflictedNote[n]).toBe(note2conf[n], 'Property: ' + n);
// }
// Other than the id (since the conflicted note is a duplicate), parent_id (which is now the Conflicts folder) and sync_time,
// the note must be the same in every way, to make sure no data has been lost.
let conflictedNote = conflictedNotes[0];
expect(conflictedNote.id == note2conf.id).toBe(false);
expect(conflictedNote.parent_id == note2conf.parent_id).toBe(false);
for (let n in conflictedNote) {
if (!conflictedNote.hasOwnProperty(n)) continue;
if (n == 'id' || n == 'parent_id') continue;
expect(conflictedNote[n]).toBe(note2conf[n], 'Property: ' + n);
}
// let noteUpdatedFromRemote = await Note.load(note1.id);
// for (let n in noteUpdatedFromRemote) {
// if (!noteUpdatedFromRemote.hasOwnProperty(n)) continue;
// if (n == 'sync_time') continue;
// expect(noteUpdatedFromRemote[n]).toBe(note2[n], 'Property: ' + n);
// }
let noteUpdatedFromRemote = await Note.load(note1.id);
for (let n in noteUpdatedFromRemote) {
if (!noteUpdatedFromRemote.hasOwnProperty(n)) continue;
if (n == 'sync_time') continue;
expect(noteUpdatedFromRemote[n]).toBe(note2[n], 'Property: ' + n);
}
// done();
// });
done();
});
it('should resolve folders conflicts', async (done) => {
let folder1 = await Folder.save({ title: "folder1" });
@@ -214,29 +214,6 @@ describe('Synchronizer', function() {
let folder1_final = await Folder.load(folder1.id);
expect(folder1_final.title).toBe(folder1_modRemote.title);
// let conflictFolder = await Folder.conflictFolder();
// let conflictedNotes = await Note.all(conflictFolder.id);
// expect(conflictedNotes.length).toBe(1);
// // Other than the id (since the conflicted note is a duplicate), parent_id (which is now the Conflicts folder) and sync_time,
// // the note must be the same in every way, to make sure no data has been lost.
// let conflictedNote = conflictedNotes[0];
// expect(conflictedNote.id == note2conf.id).toBe(false);
// expect(conflictedNote.parent_id == note2conf.parent_id).toBe(false);
// for (let n in conflictedNote) {
// if (!conflictedNote.hasOwnProperty(n)) continue;
// if (n == 'id' || n == 'parent_id') continue;
// expect(conflictedNote[n]).toBe(note2conf[n], 'Property: ' + n);
// }
// let noteUpdatedFromRemote = await Note.load(note1.id);
// for (let n in noteUpdatedFromRemote) {
// if (!noteUpdatedFromRemote.hasOwnProperty(n)) continue;
// if (n == 'sync_time') continue;
// expect(noteUpdatedFromRemote[n]).toBe(note2[n], 'Property: ' + n);
// }
done();
});

View File

@@ -67,8 +67,8 @@ class BaseModel {
static identifyItemType(item) {
if (!item) throw new Error('Cannot identify undefined item');
if ('body' in item || ('parent_id' in item && !!item.parent_id)) return BaseModel.ITEM_TYPE_NOTE;
if ('sync_time' in item) return BaseModel.ITEM_TYPE_FOLDER;
if ('body' in item || ('parent_id' in item && !!item.parent_id)) return BaseModel.MODEL_TYPE_NOTE;
if ('sync_time' in item) return BaseModel.MODEL_TYPE_FOLDER;
throw new Error('Cannot identify item: ' + JSON.stringify(item));
}
@@ -268,8 +268,9 @@ class BaseModel {
}
BaseModel.ITEM_TYPE_NOTE = 1;
BaseModel.ITEM_TYPE_FOLDER = 2;
BaseModel.MODEL_TYPE_NOTE = 1;
BaseModel.MODEL_TYPE_FOLDER = 2;
BaseModel.MODEL_TYPE_SETTING = 3;
BaseModel.tableInfo_ = null;
BaseModel.tableKeys_ = null;
BaseModel.db_ = null;

View File

@@ -22,10 +22,10 @@ class BaseItem extends BaseModel {
if (typeof item === 'object') {
if (!('type_' in item)) throw new Error('Item does not have a type_ property');
return item.type_ == BaseModel.ITEM_TYPE_NOTE ? Note : Folder;
return item.type_ == BaseModel.MODEL_TYPE_NOTE ? Note : Folder;
} else {
if (Number(item) === BaseModel.ITEM_TYPE_NOTE) return Note;
if (Number(item) === BaseModel.ITEM_TYPE_FOLDER) return Folder;
if (Number(item) === BaseModel.MODEL_TYPE_NOTE) return Note;
if (Number(item) === BaseModel.MODEL_TYPE_FOLDER) return Folder;
throw new Error('Unknown type: ' + item);
}
}
@@ -119,7 +119,7 @@ class BaseItem extends BaseModel {
if (!output.type_) throw new Error('Missing required property: type_: ' + content);
output.type_ = Number(output.type_);
if (output.type_ == BaseModel.ITEM_TYPE_NOTE) output.body = body.join("\n");
if (output.type_ == BaseModel.MODEL_TYPE_NOTE) output.body = body.join("\n");
for (let n in output) {
if (!output.hasOwnProperty(n)) continue;

View File

@@ -19,7 +19,7 @@ class Folder extends BaseItem {
}
static itemType() {
return BaseModel.ITEM_TYPE_FOLDER;
return BaseModel.MODEL_TYPE_FOLDER;
}
static trackChanges() {

View File

@@ -17,7 +17,7 @@ class Note extends BaseItem {
}
static itemType() {
return BaseModel.ITEM_TYPE_NOTE;
return BaseModel.MODEL_TYPE_NOTE;
}
static trackChanges() {

View File

@@ -8,6 +8,10 @@ class Setting extends BaseModel {
return 'settings';
}
static itemType() {
return BaseModel.MODEL_TYPE_SETTING;
}
static defaultSetting(key) {
if (!(key in this.defaults_)) throw new Error('Unknown key: ' + key);
let output = Object.assign({}, this.defaults_[key]);
@@ -26,8 +30,9 @@ class Setting extends BaseModel {
}
static load() {
this.cancelScheduleUpdate();
this.cache_ = [];
return this.db().selectAll('SELECT * FROM settings').then((rows) => {
return this.modelSelectAll('SELECT * FROM settings').then((rows) => {
this.cache_ = rows;
});
}
@@ -113,6 +118,11 @@ class Setting extends BaseModel {
}, 500);
}
static cancelScheduleUpdate() {
if (this.updateTimeoutId_) clearTimeout(this.updateTimeoutId_);
this.updateTimeoutId_ = null;
}
}
Setting.defaults_ = {

View File

@@ -54,7 +54,7 @@ class Synchronizer {
// Since, in this loop, we are only dealing with notes that require sync, if the
// remote has been modified after the sync time, it means both notes have been
// modified and so there's a conflict.
action = local.type_ == BaseModel.ITEM_TYPE_NOTE ? 'noteConflict' : 'folderConflict';
action = local.type_ == BaseModel.MODEL_TYPE_NOTE ? 'noteConflict' : 'folderConflict';
} else {
action = 'updateRemote';
}

View File

@@ -27,7 +27,7 @@ class Synchronizer {
}
loadParentAndItem(change) {
if (change.item_type == BaseModel.ITEM_TYPE_NOTE) {
if (change.item_type == BaseModel.MODEL_TYPE_NOTE) {
return Note.load(change.item_id).then((note) => {
return Folder.load(note.parent_id).then((folder) => {
return Promise.resolve({ parent: folder, item: note });
@@ -52,10 +52,10 @@ class Synchronizer {
let ItemClass = null;
let path = null;
if (c.item_type == BaseModel.ITEM_TYPE_FOLDER) {
if (c.item_type == BaseModel.MODEL_TYPE_FOLDER) {
ItemClass = Folder;
path = 'folders';
} else if (c.item_type == BaseModel.ITEM_TYPE_NOTE) {
} else if (c.item_type == BaseModel.MODEL_TYPE_NOTE) {
ItemClass = Note;
path = 'notes';
}

View File

@@ -38,7 +38,7 @@ class Synchronizer {
}
loadParentAndItem(change) {
if (change.item_type == BaseModel.ITEM_TYPE_NOTE) {
if (change.item_type == BaseModel.MODEL_TYPE_NOTE) {
return Note.load(change.item_id).then((note) => {
if (!note) return { parent:null, item: null };
@@ -107,7 +107,7 @@ class Synchronizer {
if (!dbItem) return null;
return {
type: dbItem.type_ == BaseModel.ITEM_TYPE_FOLDER ? 'folder' : 'note',
type: dbItem.type_ == BaseModel.MODEL_TYPE_FOLDER ? 'folder' : 'note',
path: Folder.systemPath(dbItem),
syncTime: dbItem.sync_time,
updated_time: dbItem.updated_time,
@@ -119,7 +119,7 @@ class Synchronizer {
if (!remoteItem) return null;
return {
type: remoteItem.content.type_ == BaseModel.ITEM_TYPE_FOLDER ? 'folder' : 'note',
type: remoteItem.content.type_ == BaseModel.MODEL_TYPE_FOLDER ? 'folder' : 'note',
path: remoteItem.path,
syncTime: 0,
updated_time: remoteItem.updated_time,