196 lines
6.0 KiB
JavaScript
196 lines
6.0 KiB
JavaScript
/*
|
|
* Test Module: Conflict Resolution
|
|
* Tests scenarios 3 and 4
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const utils = require('../utils.js').LinkdingSyncTests;
|
|
|
|
const SCENARIO_NAME = 'Conflict Resolution Tests';
|
|
|
|
// Test 3: Conflict Resolution - Different Paths
|
|
async function test3_ConflictResolution() {
|
|
console.log('\n=== Test 3: Conflict Resolution - Different Paths ===');
|
|
console.log('Purpose: How server handles same URL in different paths with different API keys');
|
|
|
|
try {
|
|
// Create with work API key
|
|
utils.SessionManager.setContext(
|
|
CONFIG.serverUrl,
|
|
CONFIG.workApiKey,
|
|
CONFIG.workUser,
|
|
CONFIG.workBundle
|
|
);
|
|
|
|
const workUrl = 'https://conflict-resolution.example.com';
|
|
const workBookmark = await utils.Helpers.createBookmark(workUrl, {
|
|
title: 'Conflict Resolution Test',
|
|
path: 'Work/Development',
|
|
notes: 'Work Development Notes'
|
|
});
|
|
|
|
console.log(` Work bookmark ID: ${workBookmark.id}`);
|
|
|
|
// Create same URL with personal API key
|
|
utils.SessionManager.setContext(
|
|
CONFIG.serverUrl,
|
|
CONFIG.personalApiKey,
|
|
CONFIG.personalUser,
|
|
CONFIG.personalBundle
|
|
);
|
|
|
|
const personalBookmark = await utils.Helpers.createBookmark(workUrl, {
|
|
title: 'Conflict Resolution Test',
|
|
path: 'Personal/Notes',
|
|
notes: 'Personal Notes'
|
|
});
|
|
|
|
console.log(` Personal bookmark ID: ${personalBookmark.id}`);
|
|
|
|
// Compare
|
|
console.log(`\nComparing bookmark IDs: work=${workBookmark.id}, personal=${personalBookmark.id}`);
|
|
|
|
if (workBookmark.id === personalBookmark.id) {
|
|
utils.Formatters.consoleResult('Test 3', 'FAIL', 'Same bookmark ID');
|
|
console.log(' → Server merges bookmarks by URL');
|
|
console.log(' → Need path merge strategy');
|
|
|
|
const state = await utils.Helpers.fetchBookmark(workBookmark.id);
|
|
const parsed = utils.Helpers.parseNotes(state.notes);
|
|
console.log(` → Current path: ${parsed.path}`);
|
|
console.log(` → Current notes: ${parsed.userNotes}`);
|
|
|
|
return { pass: false, sameId: true, path: parsed.path };
|
|
|
|
} else {
|
|
utils.Formatters.consoleResult('Test 3', 'PASS', 'Different bookmark IDs');
|
|
console.log(' → Server creates separate bookmarks per API key');
|
|
console.log(' → Can use different API keys for isolation');
|
|
|
|
return { pass: true, sameId: false, workId: workBookmark.id, personalId: personalBookmark.id };
|
|
}
|
|
|
|
} catch (error) {
|
|
utils.Formatters.consoleResult('Test 3', 'FAIL', error.message);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Test 4: Title/Description Conflict
|
|
async function test4_TitleDescriptionConflict() {
|
|
console.log('\n=== Test 4: Title/Description Conflict ===');
|
|
console.log('Purpose: How server resolves conflicts for title/description fields');
|
|
|
|
try {
|
|
utils.SessionManager.setContext(
|
|
CONFIG.serverUrl,
|
|
CONFIG.workApiKey,
|
|
CONFIG.workUser,
|
|
CONFIG.workBundle
|
|
);
|
|
|
|
const testUrl = 'https://title-conflict.example.com';
|
|
|
|
// Create initial
|
|
const bookmark = await utils.Helpers.createBookmark(testUrl, {
|
|
title: 'Initial Title',
|
|
description: 'Initial Description',
|
|
path: 'Initial'
|
|
});
|
|
|
|
// Update via work
|
|
await utils.Helpers.updateBookmark(bookmark.id, {
|
|
title: 'Work Title',
|
|
description: 'Work Description',
|
|
notes: JSON.stringify({
|
|
path: 'Work/Dev',
|
|
userNotes: 'Work notes',
|
|
autoTags: [{name: 'Work'}]
|
|
})
|
|
});
|
|
|
|
console.log(' Updated via Work: Work Title');
|
|
|
|
// Update via personal
|
|
utils.SessionManager.setContext(
|
|
CONFIG.serverUrl,
|
|
CONFIG.personalApiKey,
|
|
CONFIG.personalUser,
|
|
CONFIG.personalBundle
|
|
);
|
|
|
|
await utils.Helpers.updateBookmark(bookmark.id, {
|
|
title: 'Personal Title',
|
|
description: 'Personal Description',
|
|
notes: JSON.stringify({
|
|
path: 'Personal/Notes',
|
|
userNotes: 'Personal notes',
|
|
autoTags: [{name: 'Personal'}]
|
|
})
|
|
});
|
|
|
|
console.log(' Updated via Personal: Personal Title');
|
|
|
|
// Fetch final state
|
|
const final = await utils.Helpers.fetchBookmark(bookmark.id);
|
|
const parsed = utils.Helpers.parseNotes(final.notes);
|
|
|
|
console.log('\nFinal state:');
|
|
console.log(` Title: ${final.title}`);
|
|
console.log(` Description: ${final.description}`);
|
|
console.log(` Path: ${parsed.path}`);
|
|
console.log(` User notes: ${parsed.userNotes}`);
|
|
|
|
if (final.title === 'Personal Title') {
|
|
utils.Formatters.consoleResult('Test 4', 'PASS', 'Last-write-wins (Personal took precedence)');
|
|
return { pass: true, strategy: 'last-write-wins', winner: 'personal' };
|
|
|
|
} else if (final.title === 'Work Title') {
|
|
utils.Formatters.consoleResult('Test 4', 'PASS', 'Last-write-wins (Work took precedence)');
|
|
return { pass: true, strategy: 'last-write-wins', winner: 'work' };
|
|
|
|
} else if (final.title.includes('Work') && final.title.includes('Personal')) {
|
|
utils.Formatters.consoleResult('Test 4', 'PASS', 'Merged title');
|
|
return { pass: true, strategy: 'merge', winner: 'merged' };
|
|
|
|
} else {
|
|
utils.Formatters.consoleResult('Test 4', 'WARN', 'Unexpected title value');
|
|
return { pass: null, strategy: 'unknown', winner: final.title };
|
|
}
|
|
|
|
} catch (error) {
|
|
utils.Formatters.consoleResult('Test 4', 'FAIL', error.message);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Run all tests
|
|
async function runConflictTests() {
|
|
console.log('\n' + '='.repeat(60));
|
|
console.log(' ' + SCENARIO_NAME);
|
|
console.log('='.repeat(60));
|
|
|
|
const results = [];
|
|
|
|
try {
|
|
results[0] = await test3_ConflictResolution();
|
|
results[1] = await test4_TitleDescriptionConflict();
|
|
} catch (error) {
|
|
console.error('Test suite error:', error.message);
|
|
utils.Helpers.resetBookmarks();
|
|
}
|
|
|
|
console.log('\n' + '='.repeat(60));
|
|
console.log(' Conflict Resolution Tests Complete');
|
|
console.log('='.repeat(60));
|
|
|
|
return results;
|
|
}
|
|
|
|
// Export
|
|
window.LinkdingSyncTests.TestConflicts = {
|
|
run: runConflictTests,
|
|
test3: test3_ConflictResolution,
|
|
test4: test4_TitleDescriptionConflict
|
|
}; |