Changeset 0.28.7 (#193)
This commit is contained in:
142
packages/icd-test-runner/js/crud/admin.js
Normal file
142
packages/icd-test-runner/js/crud/admin.js
Normal file
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* ICD Test Runner — CRUD: Admin
|
||||
* Admin user lifecycle (create → deactivate → login reject → activate →
|
||||
* login success → role change → password reset → vault reset → delete),
|
||||
* admin settings roundtrip, channel purge.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
var T = window.ICD;
|
||||
if (!T) return;
|
||||
if (!T.crud) T.crud = {};
|
||||
|
||||
T.crud.admin = async function (testTag) {
|
||||
|
||||
// ── Admin User Lifecycle (create → login fails → activate → login succeeds → cleanup) ──
|
||||
if (T.user.role === 'admin') {
|
||||
var testUserId = null;
|
||||
var testUsername = 'icdtest' + (Date.now() % 100000);
|
||||
var testPassword = 'IcdT3st!Pw' + (Date.now() % 10000);
|
||||
|
||||
await T.test('crud', 'admin', 'POST /admin/users (create)', async function () {
|
||||
var d = await T.apiPost('/admin/users', {
|
||||
username: testUsername,
|
||||
password: testPassword,
|
||||
email: testUsername + '@example.com',
|
||||
role: 'user'
|
||||
});
|
||||
T.assertShape(d, T.S.adminUser, 'admin-user');
|
||||
testUserId = d.id;
|
||||
T.registerCleanup(function () { if (testUserId) return T.safeDelete('/admin/users/' + testUserId); });
|
||||
});
|
||||
|
||||
if (testUserId) {
|
||||
// Users start active (CreateUser sets IsActive=true).
|
||||
// Deactivate first, then test inactive login rejection.
|
||||
await T.test('crud', 'admin', 'PUT /admin/users/:id/active (deactivate)', async function () {
|
||||
var d = await T.apiPut('/admin/users/' + testUserId + '/active', { is_active: false });
|
||||
T.assert(typeof d === 'object', 'expected object');
|
||||
});
|
||||
|
||||
await T.test('crud', 'admin', 'POST /auth/login (inactive user → reject)', async function () {
|
||||
var d = await T.publicPost('/auth/login', {
|
||||
login: testUsername,
|
||||
password: testPassword
|
||||
});
|
||||
T.assert(d._status === 401 || d._status === 403,
|
||||
'expected 401/403 for inactive user, got ' + d._status);
|
||||
});
|
||||
|
||||
await T.test('crud', 'admin', 'PUT /admin/users/:id/active (activate)', async function () {
|
||||
var d = await T.apiPut('/admin/users/' + testUserId + '/active', { is_active: true });
|
||||
T.assert(typeof d === 'object', 'expected object');
|
||||
});
|
||||
|
||||
var testUserToken = null;
|
||||
|
||||
await T.test('crud', 'admin', 'POST /auth/login (active user → success)', async function () {
|
||||
var d = await T.publicPost('/auth/login', {
|
||||
login: testUsername,
|
||||
password: testPassword
|
||||
});
|
||||
T.assert(d._status === 200, 'expected 200, got ' + d._status +
|
||||
(d.error ? ' (' + d.error + ')' : ''));
|
||||
T.assertHasKey(d, 'access_token', 'login');
|
||||
T.assertHasKey(d, 'refresh_token', 'login');
|
||||
T.assertHasKey(d, 'user', 'login');
|
||||
T.assert(d.user.username === testUsername, 'username mismatch');
|
||||
testUserToken = d.access_token;
|
||||
});
|
||||
|
||||
if (testUserToken) {
|
||||
await T.test('crud', 'admin', 'GET /profile (as test user)', async function () {
|
||||
var d = await T.authFetch(testUserToken, 'GET', '/profile');
|
||||
T.assertStatus(d, 200, 'profile');
|
||||
T.assert(d.username === testUsername, 'username mismatch');
|
||||
});
|
||||
|
||||
await T.test('crud', 'admin', 'POST /auth/logout (test user)', async function () {
|
||||
var d = await T.publicPost('/auth/logout', { refresh_token: '' });
|
||||
T.assert(d._status === 200 || d._status === 401 || d._status === 204,
|
||||
'expected 200/204/401, got ' + d._status);
|
||||
});
|
||||
}
|
||||
|
||||
await T.test('crud', 'admin', 'PUT /admin/users/:id/role (set admin)', async function () {
|
||||
var d = await T.apiPut('/admin/users/' + testUserId + '/role', { role: 'admin' });
|
||||
T.assert(typeof d === 'object', 'expected object');
|
||||
});
|
||||
|
||||
await T.test('crud', 'admin', 'POST /admin/users/:id/reset-password', async function () {
|
||||
var d = await T.apiPost('/admin/users/' + testUserId + '/reset-password', {
|
||||
password: 'ResetPw!' + Date.now()
|
||||
});
|
||||
T.assert(typeof d === 'object', 'expected object');
|
||||
T.assert(!d.error, 'unexpected error: ' + (d.error || ''));
|
||||
});
|
||||
|
||||
await T.test('crud', 'admin', 'POST /admin/users/:id/vault/reset', async function () {
|
||||
var d = await T.apiPost('/admin/users/' + testUserId + '/vault/reset', {});
|
||||
// May return 200 with message, or 400 if vault not configured
|
||||
T.assert(d._status === undefined || !d.error || d.error === 'vault not configured',
|
||||
'unexpected error: ' + (d.error || ''));
|
||||
});
|
||||
|
||||
await T.test('crud', 'admin', 'DELETE /admin/users/:id', async function () {
|
||||
await T.safeDelete('/admin/users/' + testUserId);
|
||||
testUserId = null;
|
||||
});
|
||||
}
|
||||
|
||||
// ── Admin Settings Roundtrip ──
|
||||
await T.test('crud', 'admin', 'PUT /admin/settings/:key (policy roundtrip)', async function () {
|
||||
// Read current value
|
||||
var before = await T.apiGet('/admin/settings/allow_registration');
|
||||
var originalVal = before.value;
|
||||
// Write a known value
|
||||
await T.apiPut('/admin/settings/allow_registration', { value: 'false' });
|
||||
var after = await T.apiGet('/admin/settings/allow_registration');
|
||||
T.assert(after.value === 'false', 'expected policy value "false"');
|
||||
// Restore
|
||||
if (originalVal !== undefined) {
|
||||
await T.apiPut('/admin/settings/allow_registration', { value: String(originalVal) });
|
||||
} else {
|
||||
await T.apiPut('/admin/settings/allow_registration', { value: 'true' });
|
||||
}
|
||||
});
|
||||
|
||||
// ── Channel Purge ──
|
||||
await T.test('crud', 'admin', 'DELETE /admin/channels/:id/purge (lifecycle)', async function () {
|
||||
// Create a throwaway channel
|
||||
var ch = await T.apiPost('/channels', { title: 'icd-purge-test', type: 'direct' });
|
||||
T.assert(ch.id, 'expected channel id');
|
||||
// Archive it
|
||||
await T.apiPut('/channels/' + ch.id, { is_archived: true });
|
||||
// Purge rejects non-archived channel attempts — ours is archived, so purge should succeed
|
||||
var del = await T.apiDelete('/admin/channels/' + ch.id + '/purge');
|
||||
T.assert(del.ok === true, 'expected { ok: true }');
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user