// Fixture-only review: every API request is intercepted; no live identities are changed. const assert = require('node:assert/strict') const fs = require('node:fs') const path = require('node:path') const { chromium } = require(process.env.REVIEW_PLAYWRIGHT || 'playwright') const base = process.env.REVIEW_BASE || 'http://127.0.0.1:3116' ;(async () => { const browser = await chromium.launch({ headless: true }) try { const context = await browser.newContext() await context.addCookies([{ name: 'magent_logged_in', value: '1', url: base }]) let role = 'admin' let mode = 'ready' let scans = 0 const saves = [] const row = (id, username, state) => ({ user: { id, username, role: 'user', auth_provider: 'jellyfin', jellyseerr_user_id: null }, jellyfin: { id: 'a'.repeat(32), name: username }, candidate_jellyfin_id: 'a'.repeat(32), stored_jellyfin_id: null, seerr: [{ id: 20 + id, name: username, jellyfin_id: 'a'.repeat(32) }], jellystat: { state: state === 'unavailable' ? 'unavailable' : 'matched', id: 'a'.repeat(32), name: username }, basis: 'suggested_username', issues: state === 'conflict' ? ['Multiple Magent accounts resolve to this Jellyfin ID.'] : [], state, can_confirm: state === 'ready', confirmed_at: state === 'confirmed' ? '2026-09-08T00:00:00Z' : null, }) const fixture = { revision: 'b'.repeat(64), checked_at: '2026-09-08T01:00:00Z', server_id: 'c'.repeat(32), services: { jellyfin: 'available', seerr: 'available', jellystat: 'available' }, counts: { magent: 5, ready: 2, confirmed: 1, conflict: 1, unlinked: 0, unavailable: 1 }, rows: [row(51, 'Georgia', 'ready'), row(52, 'Another viewer', 'ready'), row(53, 'Duplicate account', 'conflict'), row(54, 'Unavailable viewer', 'unavailable'), row(55, 'Confirmed viewer', 'confirmed')], upstream: [{ platform: 'Seerr', id: '99', name: 'Former viewer', jellyfin_id: 'd'.repeat(32), detail: 'No current Jellyfin account has this ID.' }], } await context.route('**/api/**', async (route) => { const request = route.request() const url = new URL(request.url()) if (url.pathname === '/api/auth/me') return route.fulfill({ json: { username: 'Fixture admin', role } }) if (url.pathname === '/api/admin/identities') { scans++ if (mode === 'forbidden') return route.fulfill({ status: 403, json: { detail: 'Forbidden' } }) return route.fulfill({ json: fixture }) } if (url.pathname === '/api/admin/identities/confirm') { saves.push(request.postDataJSON()) if (mode === 'stale') return route.fulfill({ status: 409, json: { detail: 'The identity check has changed. Run it again before confirming accounts.' } }) return route.fulfill({ json: { confirmed: request.postDataJSON().user_ids.length, confirmed_at: '2026-09-08T02:00:00Z' } }) } if (url.pathname.includes('/events/stream')) return route.fulfill({ contentType: 'text/event-stream', body: ': fixture\n\n' }) return route.fulfill({ json: {} }) }) const page = await context.newPage() const errors = [] page.on('pageerror', (error) => errors.push(error.message)) for (const width of [1440, 980, 390, 320]) { await page.setViewportSize({ width, height: 1000 }) await page.goto(`${base}/admin/identities`) await page.getByRole('button', { name: 'Check all user IDs', exact: true }).waitFor() const before = scans assert.equal(await page.locator('.identity-account').count(), 0) await page.getByRole('button', { name: 'Check all user IDs', exact: true }).click() await page.getByRole('heading', { name: 'Georgia', exact: true }).waitFor() assert.equal(scans, before + 1) assert.equal(await page.getByRole('checkbox').count(), 2) assert(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth), `Overflow at ${width}px`) if (process.env.REVIEW_DIR) { fs.mkdirSync(process.env.REVIEW_DIR, { recursive: true }) await page.screenshot({ path: path.join(process.env.REVIEW_DIR, `identities-${width}.png`), fullPage: true }) } } await page.getByLabel('Find an account').fill('Georgia') await page.getByRole('button', { name: 'Select ready accounts shown' }).click() assert.equal(saves.length, 0) await page.getByRole('button', { name: 'Review selected links (1)', exact: true }).click() await page.getByRole('region', { name: 'Review links before saving' }).waitFor() assert.equal(await page.locator('.identity-confirm-panel li').count(), 1) assert(await page.locator('.identity-confirm-panel').evaluate((element) => document.activeElement === element)) assert(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)) await page.getByRole('button', { name: 'Confirm and save links', exact: true }).click() await page.getByText('1 account link confirmed and saved.', { exact: false }).waitFor() assert.deepEqual(saves[0], { revision: fixture.revision, user_ids: [51] }) assert.equal(await page.locator('.identity-account').count(), 0) mode = 'stale' await page.getByRole('button', { name: 'Check all user IDs', exact: true }).click() await page.getByRole('heading', { name: 'Georgia', exact: true }).waitFor() await page.getByRole('button', { name: 'Select ready accounts shown' }).click() await page.getByRole('button', { name: 'Review selected links (1)', exact: true }).click() await page.getByRole('button', { name: 'Confirm and save links', exact: true }).click() await page.getByRole('alert').filter({ hasText: 'The identity check has changed' }).waitFor() assert.equal(await page.getByRole('button', { name: 'Confirm and save links', exact: true }).count(), 0) mode = 'forbidden' await page.getByRole('button', { name: 'Check all user IDs', exact: true }).click() await page.waitForURL(base + '/') role = 'user' await page.goto(`${base}/admin/identities`) await page.waitForURL(base + '/') assert.deepEqual(errors, []) console.log('Identity UI: desktop/mobile, filtering, conflict exclusions, review, save, stale checks and access control passed.') } finally { await browser.close() } })().catch((error) => { console.error(error); process.exit(1) })