feat: bootstrap commercial AI drama platform
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const api = process.env.AI_DRAMA_API_BASE || "http://127.0.0.1:8787";
|
||||
|
||||
async function request(path, options = {}) {
|
||||
const response = await fetch(`${api}${path}`, {
|
||||
...options,
|
||||
headers: { "content-type": "application/json", ...(options.headers || {}) }
|
||||
});
|
||||
const payload = await response.json().catch(() => ({}));
|
||||
return { response, payload };
|
||||
}
|
||||
|
||||
async function login(email) {
|
||||
const result = await request("/api/auth/login", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ email, password: "Demo@123456" })
|
||||
});
|
||||
assert.equal(result.response.ok, true, `${email} 登录失败`);
|
||||
return { authorization: `Bearer ${result.payload.session.token}` };
|
||||
}
|
||||
|
||||
const ownerHeaders = await login("producer@local.test");
|
||||
const writerHeaders = await login("writer@local.test");
|
||||
|
||||
try {
|
||||
const directory = await request("/api/system/users", { headers: ownerHeaders });
|
||||
assert.equal(directory.response.ok, true, "系统管理员无法读取全局用户目录");
|
||||
assert.ok(directory.payload.users.some((user) => user.id === "u-owner"), "用户目录缺少系统管理员");
|
||||
assert.ok(directory.payload.users.every((user) => Array.isArray(user.organizations)), "用户目录缺少组织归属");
|
||||
|
||||
const detail = await request("/api/system/users/u-owner", { headers: ownerHeaders });
|
||||
assert.equal(detail.response.ok, true, "系统管理员无法读取用户详情");
|
||||
assert.ok(Array.isArray(detail.payload.sessions) && Array.isArray(detail.payload.recentAudit), "用户详情缺少会话或审计");
|
||||
|
||||
const ordinaryDenied = await request("/api/system/users", { headers: writerHeaders });
|
||||
assert.equal(ordinaryDenied.response.status, 403, "普通用户不应访问全局用户目录");
|
||||
assert.equal(ordinaryDenied.payload.error, "system_admin_required", "全局用户目录权限错误码不稳定");
|
||||
|
||||
const selfSuspend = await request("/api/system/users/u-owner", {
|
||||
method: "PATCH",
|
||||
headers: ownerHeaders,
|
||||
body: JSON.stringify({ status: "suspended" })
|
||||
});
|
||||
assert.equal(selfSuspend.response.status, 400, "系统管理员不能停用自己");
|
||||
assert.equal(selfSuspend.payload.error, "cannot_suspend_self", "自停用保护错误码不稳定");
|
||||
|
||||
const suspended = await request("/api/system/users/u-writer", {
|
||||
method: "PATCH",
|
||||
headers: ownerHeaders,
|
||||
body: JSON.stringify({ status: "suspended" })
|
||||
});
|
||||
assert.equal(suspended.response.ok, true, "停用普通用户失败");
|
||||
assert.equal(suspended.payload.user.status, "suspended", "用户停用状态未落库");
|
||||
assert.ok(suspended.payload.revokedSessionCount >= 1, "停用用户必须撤销全部会话");
|
||||
|
||||
const staleSession = await request("/api/auth/session", { headers: writerHeaders });
|
||||
assert.equal(staleSession.response.status, 401, "停用后的旧会话必须失效");
|
||||
|
||||
const reactivated = await request("/api/system/users/u-writer", {
|
||||
method: "PATCH",
|
||||
headers: ownerHeaders,
|
||||
body: JSON.stringify({ status: "active" })
|
||||
});
|
||||
assert.equal(reactivated.response.ok, true, "恢复用户失败");
|
||||
assert.equal(reactivated.payload.user.status, "active", "用户恢复状态未落库");
|
||||
|
||||
const newWriterHeaders = await login("writer@local.test");
|
||||
const revoked = await request("/api/system/users/u-writer/revoke-sessions", {
|
||||
method: "POST",
|
||||
headers: ownerHeaders,
|
||||
body: "{}"
|
||||
});
|
||||
assert.equal(revoked.response.ok, true, "系统管理员强制撤销用户会话失败");
|
||||
assert.ok(revoked.payload.revokedSessionCount >= 1, "强制撤销必须返回撤销数量");
|
||||
const revokedSession = await request("/api/auth/session", { headers: newWriterHeaders });
|
||||
assert.equal(revokedSession.response.status, 401, "强制撤销后用户会话仍然有效");
|
||||
|
||||
console.log(`system users smoke passed: ${api}`);
|
||||
} finally {
|
||||
await request("/api/system/users/u-writer", {
|
||||
method: "PATCH",
|
||||
headers: ownerHeaders,
|
||||
body: JSON.stringify({ status: "active" })
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user