Initial commit: LinkSyncServer and LinkSyncExtension projects with complete documentation, models, API endpoints, tests, and extension implementation
This commit is contained in:
218
Linkding Browser Extension/LinkdingSync/tests/test-deletion.js
Normal file
218
Linkding Browser Extension/LinkdingSync/tests/test-deletion.js
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Test Module: Delete Propagation
|
||||
* Tests scenario 5
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const utils = require('../utils.js').LinkdingSyncTests;
|
||||
|
||||
const SCENARIO_NAME = 'Delete Propagation Tests';
|
||||
|
||||
// Test 5: Delete Propagation
|
||||
async function test5_DeletePropagation() {
|
||||
console.log('\n=== Test 5: Delete Propagation ===');
|
||||
console.log('Purpose: Confirm if deleting affects all API keys');
|
||||
|
||||
try {
|
||||
utils.SessionManager.setContext(
|
||||
CONFIG.serverUrl,
|
||||
CONFIG.workApiKey,
|
||||
CONFIG.workUser,
|
||||
CONFIG.workBundle
|
||||
);
|
||||
|
||||
const testUrl = 'https://delete-propagation.example.com';
|
||||
|
||||
// Create via work
|
||||
const workBookmark = await utils.Helpers.createBookmark(testUrl, {
|
||||
title: 'Delete Prop Test',
|
||||
path: 'Work/Dev'
|
||||
});
|
||||
|
||||
console.log(` Work bookmark ID: ${workBookmark.id}`);
|
||||
|
||||
// Create same URL via personal
|
||||
utils.SessionManager.setContext(
|
||||
CONFIG.serverUrl,
|
||||
CONFIG.personalApiKey,
|
||||
CONFIG.personalUser,
|
||||
CONFIG.personalBundle
|
||||
);
|
||||
|
||||
const personalBookmark = await utils.Helpers.createBookmark(testUrl, {
|
||||
title: 'Delete Prop Test',
|
||||
path: 'Personal/Notes'
|
||||
});
|
||||
|
||||
console.log(` Personal bookmark ID: ${personalBookmark.id}`);
|
||||
|
||||
const sameBookmark = workBookmark.id === personalBookmark.id;
|
||||
console.log(` Same bookmark? ${sameBookmark}`);
|
||||
|
||||
// Delete via work
|
||||
await utils.SessionManager.setContext(
|
||||
CONFIG.serverUrl,
|
||||
CONFIG.workApiKey,
|
||||
CONFIG.workUser,
|
||||
CONFIG.workBundle
|
||||
);
|
||||
await utils.Helpers.deleteBookmark(workBookmark.id);
|
||||
console.log(' Deleted via Work key');
|
||||
|
||||
// Check via personal
|
||||
utils.SessionManager.setContext(
|
||||
CONFIG.serverUrl,
|
||||
CONFIG.personalApiKey,
|
||||
CONFIG.personalUser,
|
||||
CONFIG.personalBundle
|
||||
);
|
||||
|
||||
const personalList = await utils.Helpers.getAllBookmarks();
|
||||
const deleted = personalList.find(b => b.url === testUrl);
|
||||
|
||||
if (!deleted) {
|
||||
utils.Formatters.consoleResult('Test 5', 'FAIL', 'Delete propagated (same bookmark)');
|
||||
console.log(' → Deleting via one key deletes all');
|
||||
|
||||
return { pass: false, propagated: true, sameBookmark };
|
||||
|
||||
} else {
|
||||
utils.Formatters.consoleResult('Test 5', 'PASS', 'Delete did not propagate (separate bookmarks)');
|
||||
console.log(' → Each bookmark exists independently');
|
||||
console.log(' → Can delete via specific API key');
|
||||
|
||||
return { pass: true, propagated: false, sameBookmark };
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
utils.Formatters.consoleResult('Test 5', 'FAIL', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Test 6: Delete with Same User Different Keys
|
||||
async function test6_DeleteSameUserDifferentKeys() {
|
||||
console.log('\n=== Test 6: Delete - Same User, Different Keys ===');
|
||||
console.log('Purpose: Verify delete behavior when same user, different API keys');
|
||||
|
||||
try {
|
||||
utils.SessionManager.setContext(
|
||||
CONFIG.serverUrl,
|
||||
CONFIG.workApiKey,
|
||||
CONFIG.workUser,
|
||||
CONFIG.workBundle
|
||||
);
|
||||
|
||||
const testUrl = 'https://delete-same-user.example.com';
|
||||
|
||||
// Create with first key
|
||||
const bm1 = await utils.Helpers.createBookmark(testUrl, {
|
||||
title: 'Same User Delete Test - Key 1'
|
||||
});
|
||||
|
||||
console.log(` Created with Key 1: ID=${bm1.id}`);
|
||||
|
||||
// Create same URL with second key (personal)
|
||||
utils.SessionManager.setContext(
|
||||
CONFIG.serverUrl,
|
||||
CONFIG.personalApiKey,
|
||||
CONFIG.personalUser,
|
||||
CONFIG.personalBundle
|
||||
);
|
||||
|
||||
const bm2 = await utils.Helpers.createBookmark(testUrl, {
|
||||
title: 'Same User Delete Test - Key 2'
|
||||
});
|
||||
|
||||
console.log(` Created with Key 2: ID=${bm2.id}`);
|
||||
|
||||
// Check if same bookmark
|
||||
if (bm1.id === bm2.id) {
|
||||
utils.Formatters.consoleResult('Test 6', 'WARN', 'Same bookmark - delete propagates');
|
||||
console.log(' → Same user means same bookmark');
|
||||
console.log(' → Deleting via either key removes it');
|
||||
|
||||
// Delete via work
|
||||
await utils.Helpers.deleteBookmark(bm1.id);
|
||||
|
||||
// Verify gone
|
||||
utils.SessionManager.setContext(
|
||||
CONFIG.serverUrl,
|
||||
CONFIG.workApiKey,
|
||||
CONFIG.workUser,
|
||||
CONFIG.workBundle
|
||||
);
|
||||
const workList = await utils.Helpers.getAllBookmarks();
|
||||
const exists = workList.find(b => b.url === testUrl);
|
||||
|
||||
if (!exists) {
|
||||
console.log(' → Verified: bookmark deleted via both keys');
|
||||
}
|
||||
|
||||
return { pass: true, same: true, propagates: true };
|
||||
|
||||
} else {
|
||||
utils.Formatters.consoleResult('Test 6', 'PASS', 'Different bookmarks - delete is isolated');
|
||||
console.log(' → Different API keys create different bookmarks');
|
||||
console.log(' → Can delete independently');
|
||||
|
||||
// Delete via work
|
||||
await utils.Helpers.deleteBookmark(bm1.id);
|
||||
|
||||
// Verify work side gone
|
||||
const workList = await utils.Helpers.getAllBookmarks();
|
||||
const workGone = !workList.find(b => b.url === testUrl);
|
||||
|
||||
// Verify personal still exists
|
||||
utils.SessionManager.setContext(
|
||||
CONFIG.serverUrl,
|
||||
CONFIG.personalApiKey,
|
||||
CONFIG.personalUser,
|
||||
CONFIG.personalBundle
|
||||
);
|
||||
const personalList = await utils.Helpers.getAllBookmarks();
|
||||
const personalExists = personalList.find(b => b.url === testUrl);
|
||||
|
||||
if (workGone && personalExists) {
|
||||
console.log(' → Verified: work deleted, personal still exists');
|
||||
}
|
||||
|
||||
return { pass: true, same: false, propagates: false };
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
utils.Formatters.consoleResult('Test 6', 'FAIL', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Run all tests
|
||||
async function runDeletionTests() {
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log(' ' + SCENARIO_NAME);
|
||||
console.log('='.repeat(60));
|
||||
|
||||
const results = [];
|
||||
|
||||
try {
|
||||
results[0] = await test5_DeletePropagation();
|
||||
results[1] = await test6_DeleteSameUserDifferentKeys();
|
||||
} catch (error) {
|
||||
console.error('Test suite error:', error.message);
|
||||
utils.Helpers.resetBookmarks();
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log(' Deletion Tests Complete');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
// Export
|
||||
window.LinkdingSyncTests.TestDeletion = {
|
||||
run: runDeletionTests,
|
||||
test5: test5_DeletePropagation,
|
||||
test6: test6_DeleteSameUserDifferentKeys
|
||||
};
|
||||
Reference in New Issue
Block a user