You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-23 22:36:32 +02:00
All: Fixes #13531: When creating a conflict, ensure the latest note contents are used to create the conflict (#13552)
This commit is contained in:
@@ -1644,6 +1644,7 @@ packages/lib/services/synchronizer/Synchronizer.sharing.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.tags.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.tools.test.js
|
||||
packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.js
|
||||
packages/lib/services/synchronizer/handleConflictAction.test.js
|
||||
packages/lib/services/synchronizer/migrations/1.js
|
||||
packages/lib/services/synchronizer/migrations/2.js
|
||||
packages/lib/services/synchronizer/migrations/3.js
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1617,6 +1617,7 @@ packages/lib/services/synchronizer/Synchronizer.sharing.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.tags.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.tools.test.js
|
||||
packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.js
|
||||
packages/lib/services/synchronizer/handleConflictAction.test.js
|
||||
packages/lib/services/synchronizer/migrations/1.js
|
||||
packages/lib/services/synchronizer/migrations/2.js
|
||||
packages/lib/services/synchronizer/migrations/3.js
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import BaseItem from '../../models/BaseItem';
|
||||
import Note from '../../models/Note';
|
||||
import { setupDatabaseAndSynchronizer, switchClient } from '../../testing/test-utils';
|
||||
import handleConflictAction from './utils/handleConflictAction';
|
||||
import { SyncAction } from './utils/types';
|
||||
|
||||
describe('handleConflictAction', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
});
|
||||
|
||||
test('note conflict is created', async () => {
|
||||
const local = await Note.save({ title: 'Test', body: 'body' });
|
||||
// Pass the local note with unsaved changes to verify that the note is reloaded before creating the conflict
|
||||
const changedLocal = { ...local, title: 'TestChanged' };
|
||||
const remoteContent = { ...local, title: 'TestRemote' };
|
||||
const initialSyncItem = await BaseItem.syncItem(1, local.id);
|
||||
|
||||
await handleConflictAction(
|
||||
SyncAction.NoteConflict,
|
||||
Note,
|
||||
true,
|
||||
remoteContent,
|
||||
changedLocal,
|
||||
1,
|
||||
false,
|
||||
(action) => (action),
|
||||
);
|
||||
|
||||
const createdSyncItem = await BaseItem.syncItem(1, local.id);
|
||||
const updatedLocal = await Note.load(local.id);
|
||||
const notes = await Note.all();
|
||||
const conflictNote = await Note.loadByTitle('Test');
|
||||
|
||||
expect(initialSyncItem).toBeUndefined();
|
||||
expect(createdSyncItem).toBeDefined();
|
||||
expect(updatedLocal.title).toBe('TestRemote');
|
||||
expect(notes.length).toBe(2);
|
||||
expect(conflictNote.id).not.toBe(local.id);
|
||||
});
|
||||
|
||||
test('note conflict is not created when remote and local contents match', async () => {
|
||||
const local = await Note.save({ title: 'Test', body: 'body' });
|
||||
// Pass the local note with unsaved changes to verify that the note is reloaded before checking if eligible to create a conflict
|
||||
const changedLocal = { ...local, title: 'TestChanged' };
|
||||
const remoteContent = local;
|
||||
const initialSyncItem = await BaseItem.syncItem(1, local.id);
|
||||
|
||||
await handleConflictAction(
|
||||
SyncAction.NoteConflict,
|
||||
Note,
|
||||
true,
|
||||
remoteContent,
|
||||
changedLocal,
|
||||
1,
|
||||
false,
|
||||
(action) => (action),
|
||||
);
|
||||
|
||||
const createdSyncItem = await BaseItem.syncItem(1, local.id);
|
||||
const notes = await Note.all();
|
||||
expect(initialSyncItem).toBeUndefined();
|
||||
expect(createdSyncItem).toBeDefined();
|
||||
expect(notes.length).toBe(1);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -38,6 +38,9 @@ export default async (action: SyncAction, ItemClass: typeof BaseItem, remoteExis
|
||||
});
|
||||
}
|
||||
} else if (action === SyncAction.NoteConflict) {
|
||||
// Reload the note, to ensure the latest version is used to create the conflict
|
||||
local = await Note.load(local.id);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// First find out if the conflict matters. For example, if the conflict is on the title or body
|
||||
// we want to preserve all the changes. If it's on todo_completed it doesn't really matter
|
||||
|
||||
Reference in New Issue
Block a user