/** * ICD Test Runner — Fixtures * Creates and tears down test users, teams, and groups for AuthZ tests. */ (function () { 'use strict'; var T = window.ICD; if (!T) return; function genPassword() { var chars = 'ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789!@#$'; var pw = ''; for (var i = 0; i < 16; i++) pw += chars.charAt(Math.floor(Math.random() * chars.length)); return pw; } T.provisionFixtures = async function () { var fixtures = T.fixtures; if (fixtures.ready) { if (typeof UI !== 'undefined') UI.toast('Fixtures already provisioned — tear down first', 'warning'); return; } if (T.user.role !== 'admin') { if (typeof UI !== 'undefined') UI.toast('Admin required to provision fixtures', 'error'); return; } var tag = 'icd-' + Date.now(); var errors = []; var userDefs = [ { username: tag + '-user', display_name: 'ICD Test User', role: 'user' }, { username: tag + '-tadmin', display_name: 'ICD Test Team Admin', role: 'user' }, { username: tag + '-admin2', display_name: 'ICD Test Admin', role: 'admin' } ]; for (var i = 0; i < userDefs.length; i++) { var def = userDefs[i]; var pw = genPassword(); try { var created = await T.apiPost('/admin/users', { username: def.username, password: pw, email: def.username + '@example.com', role: def.role }); try { await T.apiPut('/admin/users/' + created.id + '/active', { is_active: true }); } catch (e) { /* may already be active */ } var login = await T.publicPost('/auth/login', { login: def.username, password: pw }); fixtures.users.push({ username: def.username, password: pw, display_name: def.display_name, role: def.role, id: created.id, token: login.access_token || '' }); } catch (e) { errors.push('User ' + def.username + ': ' + e.message); } } try { var team = await T.apiPost('/admin/teams', { name: tag + '-team', description: 'ICD test team' }); fixtures.team = { id: team.id, name: team.name }; try { await T.apiPost('/admin/teams/' + team.id + '/members', { user_id: T.user.id, role: 'admin' }); } catch (e) { /* auto-add */ } var tadmin = fixtures.users.find(function (u) { return u.username.indexOf('-tadmin') !== -1; }); if (tadmin) await T.apiPost('/admin/teams/' + team.id + '/members', { user_id: tadmin.id, role: 'admin' }); var regUser = fixtures.users.find(function (u) { return u.username.indexOf('-user') !== -1 && u.username.indexOf('-tadmin') === -1; }); if (regUser) await T.apiPost('/admin/teams/' + team.id + '/members', { user_id: regUser.id, role: 'member' }); } catch (e) { errors.push('Team: ' + e.message); } try { var grp = await T.apiPost('/admin/groups', { name: tag + '-group', scope: 'global' }); fixtures.group = { id: grp.id, name: grp.name }; await T.apiPut('/admin/groups/' + grp.id, { permissions: ['model.use', 'kb.read'] }); var regUser2 = fixtures.users.find(function (u) { return u.username.indexOf('-user') !== -1 && u.username.indexOf('-tadmin') === -1; }); if (regUser2) await T.apiPost('/admin/groups/' + grp.id + '/members', { user_id: regUser2.id }); } catch (e) { errors.push('Group: ' + e.message); } fixtures.ready = true; if (typeof T.renderFixtures === 'function') T.renderFixtures(); if (errors.length > 0) { if (typeof UI !== 'undefined') UI.toast('Fixtures created with ' + errors.length + ' errors', 'warning'); console.warn('Fixture errors:', errors); } else { if (typeof UI !== 'undefined') UI.toast('Fixtures provisioned (' + fixtures.users.length + ' users, team, group)', 'success'); } }; T.teardownFixtures = async function () { var fixtures = T.fixtures; if (!fixtures.ready) return; if (fixtures.group) { try { await T.safeDelete('/admin/groups/' + fixtures.group.id); } catch (e) { /* ok */ } } if (fixtures.team) { try { await T.safeDelete('/admin/teams/' + fixtures.team.id); } catch (e) { /* ok */ } } for (var i = fixtures.users.length - 1; i >= 0; i--) { try { await T.safeDelete('/admin/users/' + fixtures.users[i].id); } catch (e) { /* ok */ } } T.fixtures = { ready: false, users: [], team: null, group: null }; if (typeof T.renderFixtures === 'function') T.renderFixtures(); if (typeof UI !== 'undefined') UI.toast('Test fixtures torn down', 'info'); }; T.getFixtureUser = function (suffix) { return T.fixtures.users.find(function (u) { return u.username.indexOf(suffix) !== -1; }); }; })();