Add reviewed duplicate account consolidation and prevent duplicate imports
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const { chromium } = require(process.env.PLAYWRIGHT_PACKAGE || 'playwright');
|
||||
const base = process.env.REVIEW_BASE || 'http://localhost:3114';
|
||||
(async () => {
|
||||
const browser = await chromium.launch();
|
||||
try {
|
||||
const context = await browser.newContext();
|
||||
await context.addCookies([{ name: 'magent_logged_in', value: '1', url: base }]);
|
||||
const rows = [36, 1880].map(id => ({ user: { id, username: 'DeaTH_TaXi', role: 'user', auth_provider: 'jellyfin', jellyseerr_user_id: 13 },
|
||||
jellyfin: { id: 'a'.repeat(32), name: 'DeaTH_TaXi' }, candidate_jellyfin_id: 'a'.repeat(32), seerr: [{ id: 13, name: 'DeaTH_TaXi' }],
|
||||
jellystat: { state: 'matched', id: 'a'.repeat(32) }, issues: ['Multiple Magent rows share this username after case and whitespace normalization.'], state: 'conflict' }));
|
||||
let blocked = false, confirmed = false, checks = 0; const writes = [];
|
||||
await context.route('**/api/**', async route => {
|
||||
const request = route.request(), path = new URL(request.url()).pathname;
|
||||
if (path === '/api/auth/me') return route.fulfill({ json: { username: 'Admin', role: 'admin' } });
|
||||
if (path === '/api/admin/identities') { checks++; return route.fulfill({ json: { rows: confirmed ? [] : rows, counts: { magent: 2, conflict: 2 }, services: { jellyfin: 'available', seerr: 'available', jellystat: 'available' }, jellyfin_users: [{ id: 'a'.repeat(32), name: 'DeaTH_TaXi' }], upstream: [] } }); }
|
||||
if (path.endsWith('/duplicates/check')) {
|
||||
const keep = request.postDataJSON().keep_id || 36;
|
||||
return route.fulfill({ json: { accounts: rows.map(row => ({ ...row.user, email: 'viewer@example.test', profile_id: null, last_login_at: null })), keep_id: keep, recommended_id: 36, revision: String(keep), can_confirm: !blocked, issues: blocked ? ['Another account owns this identity.'] : [],
|
||||
proposed: { id: keep, username: 'DeaTH_TaXi', email: 'viewer@example.test', jellyfin_user_id: 'a'.repeat(32), seerr_user_id: 13, features: { stats: true, requests: true, new_requests: true, issues: false, invites: false }, auto_search_enabled: false } } });
|
||||
}
|
||||
if (path.endsWith('/duplicates/confirm')) { writes.push(request.postDataJSON()); confirmed = true; return route.fulfill({ json: { consolidated: 1, kept_user_id: 1880 } }); }
|
||||
return route.fulfill({ json: {} });
|
||||
});
|
||||
const page = await context.newPage(), errors = [];
|
||||
page.on('pageerror', error => errors.push(error.message));
|
||||
for (const width of [1440, 390]) {
|
||||
await page.setViewportSize({ width, height: 1000 });
|
||||
await page.goto(base + '/users?view=identities&user=DeaTH_TaXi');
|
||||
await page.getByRole('button', { name: 'Check all user IDs', exact: true }).click();
|
||||
const trigger = page.getByRole('button', { name: 'Repair duplicate accounts', exact: true }).first();
|
||||
await trigger.click(); const dialog = page.getByRole('dialog');
|
||||
await dialog.getByLabel('Magent account to keep').waitFor();
|
||||
assert.equal(await dialog.getByLabel('Magent account to keep').inputValue(), '36');
|
||||
assert(await dialog.getByRole('button', { name: 'Confirm duplicate repair' }).isDisabled());
|
||||
assert(await dialog.evaluate(el => el.scrollWidth <= el.clientWidth), 'No horizontal overflow');
|
||||
await page.keyboard.press('Escape'); await dialog.waitFor({ state: 'hidden' });
|
||||
assert(await trigger.evaluate(el => el === document.activeElement));
|
||||
}
|
||||
blocked = true;
|
||||
await page.getByRole('button', { name: 'Repair duplicate accounts', exact: true }).first().click();
|
||||
let dialog = page.getByRole('dialog');
|
||||
await dialog.getByText('Another account owns this identity.', { exact: true }).waitFor();
|
||||
assert(await dialog.getByRole('checkbox').isDisabled());
|
||||
await dialog.getByRole('button', { name: 'Close', exact: true }).click();
|
||||
blocked = false;
|
||||
await page.getByRole('button', { name: 'Repair duplicate accounts', exact: true }).first().click(); dialog = page.getByRole('dialog');
|
||||
await dialog.getByLabel('Magent account to keep').selectOption('1880');
|
||||
await dialog.getByText('Magent 1880 · Keep', { exact: true }).waitFor();
|
||||
await dialog.getByRole('checkbox').check();
|
||||
const previousChecks = checks;
|
||||
await dialog.getByRole('button', { name: 'Confirm duplicate repair' }).click();
|
||||
await dialog.waitFor({ state: 'hidden' });
|
||||
await page.getByRole('button', { name: 'Run check again', exact: true }).waitFor();
|
||||
assert.deepEqual(writes, [{ user_id: 36, keep_id: 1880, revision: '1880' }]);
|
||||
assert(checks > previousChecks, 'Identity report refreshed');
|
||||
assert.deepEqual(errors, []);
|
||||
console.log('Passed: desktop/mobile duplicate review, recommended account, changed selection, explicit confirmation, conflict blocking, focus restoration and report refresh. All APIs intercepted.');
|
||||
} finally { await browser.close(); }
|
||||
})().catch(error => { console.error(error); process.exitCode = 1; });
|
||||
Reference in New Issue
Block a user