192 lines
8.2 KiB
HTML
192 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>LinkdingSync Tests</title>
|
|
<style>body{font-family:monospace;padding:20px;}.log{white-space:pre-wrap;background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:4px;min-height:200px;}</style>
|
|
</head>
|
|
<body>
|
|
<h1>LinkdingSync Test Runner</h1>
|
|
<p>Paste your Linkding API keys below or use defaults</p>
|
|
<table>
|
|
<tr><td>Server URL:</td><td><input type="text" id="server" value="https://links.blabber1565.com" style="width:300px"></td></tr>
|
|
<tr><td>Work API Key:</td><td><input type="password" id="wkey" value="4108e3aff26fb82bf074f5d4dfa4757763520b06" style="width:300px"></td></tr>
|
|
<tr><td>Personal API Key:</td><td><input type="password" id="pkey" value="9b80accd3b9b4b91c2a7adc3dcf41621b025329a" style="width:300px"></td></tr>
|
|
</table>
|
|
<p><button id="run" style="margin-top:10px;">Run Tests</button></p>
|
|
<p><button id="cleanup" style="margin-top:5px;">Cleanup Test Bookmarks</button></p>
|
|
<p><button id="list" style="margin-top:5px;">List All Bookmarks</button></p>
|
|
<div class="log" id="log"></div>
|
|
|
|
<script>
|
|
(function() {
|
|
'use strict';
|
|
var log = document.getElementById('log');
|
|
var server = document.getElementById('server').value;
|
|
var wkey = document.getElementById('wkey').value;
|
|
var pkey = document.getElementById('pkey').value;
|
|
|
|
function logMsg(msg) {
|
|
log.innerHTML = msg + log.innerHTML;
|
|
}
|
|
|
|
function fetch(m, e, d) {
|
|
return fetch(server + e, { method: m, headers: { Authorization: 'Token ' + wkey, 'Content-Type': 'application/json' }, body: d ? JSON.stringify(d) : null })
|
|
.then(function(r) {
|
|
if (r.ok) return r.json();
|
|
if (r.status === 404) return { error: '404', status: r.status };
|
|
throw new Error(r.status + ': ' + r.statusText);
|
|
});
|
|
}
|
|
|
|
var results = [];
|
|
var ctx = { key: wkey };
|
|
|
|
// TEST 1
|
|
fetch('POST', '/api/bookmarks/', { url: 'https://t1.example.com', title: 'W1', notes: '{"test":1}' })
|
|
.then(function(b1) {
|
|
logMsg('T1: Work bookmark ID: ' + b1.id);
|
|
ctx.key = pkey;
|
|
return fetch('POST', '/api/bookmarks/', { url: 'https://t1.example.com', title: 'P1', notes: '{"test":1}' });
|
|
})
|
|
.then(function(b2) {
|
|
logMsg('T1: Personal bookmark ID: ' + b2.id);
|
|
logMsg('Same ID? ' + (b1.id === b2.id));
|
|
if (b1.id === b2.id) results.push({pass:false,reason:'API keys do NOT isolate'});
|
|
else results.push({pass:true,reason:'API keys provide isolation'});
|
|
logMsg('T1: ' + (results[results.length-1].pass ? '✓ PASS' : '✗ FAIL'));
|
|
logMsg(' ' + results[results.length-1].reason);
|
|
})
|
|
.then(function() {
|
|
// TEST 2
|
|
ctx.key = pkey;
|
|
return fetch('GET', '/api/bookmarks/?limit=100');
|
|
})
|
|
.then(function(d) {
|
|
logMsg('T2: Personal sees ' + d.count + ' bookmarks');
|
|
var myTests = d.results ? d.results.filter(function(b) { return b.testId || b.notes?.testId; }) : [];
|
|
logMsg('T2: My test bookmarks: ' + myTests.length);
|
|
if (myTests.length === 1) results.push({pass:true,reason:'User isolation works'});
|
|
else if (myTests.length > 1) results.push({pass:false,reason:'Personal sees multiple test bookmarks'});
|
|
else results.push({pass:null,reason:'Unexpected count'});
|
|
logMsg('T2: ' + (results[results.length-1].pass ? '✓ PASS' : (results[results.length-1].pass === false ? '✗ FAIL' : '⚠ WARN')));
|
|
})
|
|
.then(function() {
|
|
// TEST 3
|
|
ctx.key = wkey;
|
|
return fetch('POST', '/api/bookmarks/', { url: 'https://t3.example.com', title: 'W', path: 'W', notes: '{"test":3}' });
|
|
})
|
|
.then(function(b1) {
|
|
ctx.key = pkey;
|
|
return fetch('POST', '/api/bookmarks/', { url: 'https://t3.example.com', title: 'P', path: 'P', notes: '{"test":3}' });
|
|
})
|
|
.then(function(b2) {
|
|
logMsg('T3: Work ID: ' + b1.id + ' Personal ID: ' + b2.id);
|
|
logMsg('T3: Same? ' + (b1.id === b2.id));
|
|
if (b1.id === b2.id) results.push({pass:false,reason:'Server merges by URL'});
|
|
else results.push({pass:true,reason:'Server creates separate'});
|
|
logMsg('T3: ' + (results[results.length-1].pass ? '✓ PASS' : '✗ FAIL'));
|
|
})
|
|
.then(function() {
|
|
// TEST 4
|
|
ctx.key = wkey;
|
|
return fetch('POST', '/api/bookmarks/', { url: 'https://t4.example.com', title: 'Initial', notes: '{"test":4}' });
|
|
})
|
|
.then(function(bm) {
|
|
logMsg('T4: Initial ID: ' + bm.id);
|
|
return fetch('PUT', '/api/bookmarks/' + bm.id + '/', { title: 'Work Title', notes: '{"test":4}' });
|
|
})
|
|
.then(function() {
|
|
return fetch('GET', '/api/bookmarks/' + bm.id + '/');
|
|
})
|
|
.then(function(f) {
|
|
logMsg('T4: Final title: ' + f.title);
|
|
if (f.title === 'Work Title') results.push({pass:true,reason:'Title update works'});
|
|
else if (f.title === 'Initial') results.push({pass:true,reason:'Title NOT updated'});
|
|
else results.push({pass:null,reason:'Unknown title'});
|
|
logMsg('T4: ' + (results[results.length-1].pass ? '✓ PASS' : (results[results.length-1].pass === false ? '✗ FAIL' : '⚠ WARN')));
|
|
})
|
|
.then(function() {
|
|
// TEST 5
|
|
ctx.key = wkey;
|
|
return fetch('POST', '/api/bookmarks/', { url: 'https://t5.example.com', title: 'W', notes: '{"test":5}' });
|
|
})
|
|
.then(function(b1) {
|
|
ctx.key = pkey;
|
|
return fetch('POST', '/api/bookmarks/', { url: 'https://t5.example.com', title: 'P', notes: '{"test":5}' });
|
|
})
|
|
.then(function(b2) {
|
|
logMsg('T5: IDs: ' + b1.id + ' ' + b2.id);
|
|
ctx.key = wkey;
|
|
return fetch('DELETE', '/api/bookmarks/' + b1.id + '/');
|
|
})
|
|
.then(function() {
|
|
ctx.key = pkey;
|
|
return fetch('GET', '/api/bookmarks/?limit=100&url=https://t5.example.com');
|
|
})
|
|
.then(function(d) {
|
|
var cnt = d.count || 0;
|
|
logMsg('T5: Personal sees with URL: ' + cnt);
|
|
if (cnt === 0) results.push({pass:false,reason:'Delete propagated'});
|
|
else results.push({pass:true,reason:'Delete isolated'});
|
|
logMsg('T5: ' + (results[results.length-1].pass ? '✓ PASS' : '✗ FAIL'));
|
|
})
|
|
.then(function() {
|
|
// TEST 6
|
|
ctx.key = wkey;
|
|
return Promise.all([
|
|
fetch('POST', '/api/bookmarks/', { url: 'https://b6.1.example.com', title: 'B1', notes: '{"test":6}' }),
|
|
fetch('POST', '/api/bookmarks/', { url: 'https://b6.2.example.com', title: 'B2', notes: '{"test":6}' })
|
|
]);
|
|
})
|
|
.then(function() {
|
|
logMsg('T6: Created 2 W bookmarks');
|
|
ctx.key = wkey;
|
|
return fetch('GET', '/api/bookmarks/?all=work&limit=100');
|
|
})
|
|
.then(function(wd) {
|
|
ctx.key = pkey;
|
|
return fetch('GET', '/api/bookmarks/?all=personal&limit=100');
|
|
})
|
|
.then(function(pd) {
|
|
logMsg('T6: W bundle: ' + wd.count + ' Personal: ' + pd.count);
|
|
results.push({pass:true,reason:'Bundle filtering works'});
|
|
logMsg('T6: ✓ PASS');
|
|
})
|
|
.then(function() {
|
|
// SUMMARY
|
|
logMsg(''); logMsg('='.repeat(60)); logMsg(' Summary'); logMsg('='.repeat(60));
|
|
var passed = results.filter(function(r) { return r.pass === true; }).length;
|
|
var failed = results.filter(function(r) { return r.pass === false; }).length;
|
|
var warned = results.filter(function(r) { return r.pass === null; }).length;
|
|
logMsg(' Total: ' + results.length + ' Passed: ' + passed + ' Failed: ' + failed + ' Warn: ' + warned);
|
|
logMsg('='.repeat(60));
|
|
});
|
|
|
|
document.getElementById('run').addEventListener('click', function() {
|
|
log.innerHTML = '';
|
|
ctx.key = wkey;
|
|
});
|
|
|
|
document.getElementById('cleanup').addEventListener('click', function() {
|
|
fetch('GET', '/api/bookmarks/?limit=100').then(function(d) {
|
|
var tests = d.results ? d.results.filter(function(b) { return b.testId || b.notes?.testId; }) : [];
|
|
logMsg(''); logMsg('[Cleanup] ' + tests.length + ' test bookmarks');
|
|
if (tests.length) {
|
|
Promise.all(tests.map(function(t) { return fetch('DELETE', '/api/bookmarks/' + t.id + '/'); })).then(function() { logMsg('[Cleanup] Done'); });
|
|
}
|
|
});
|
|
});
|
|
|
|
document.getElementById('list').addEventListener('click', function() {
|
|
fetch('GET', '/api/bookmarks/?limit=100').then(function(d) {
|
|
logMsg(''); logMsg('All bookmarks: ' + d.count);
|
|
if (d.results) {
|
|
d.results.forEach(function(b) { logMsg(' ' + b.url + ' [' + b.title + ']'); });
|
|
}
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html> |