feat: expand commercial ai drama platform
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const api = process.env.AI_DRAMA_API_BASE || "http://127.0.0.1:8787";
|
||||
const scope = {
|
||||
"x-organization-id": "org-studio-lab",
|
||||
"x-workspace-id": "ws-local-aidrama",
|
||||
"x-project-id": "thunder-mouth"
|
||||
};
|
||||
|
||||
async function request(path, headers = {}, options = {}) {
|
||||
const response = await fetch(`${api}${path}`, {
|
||||
...options,
|
||||
headers: { "content-type": "application/json", ...headers, ...(options.headers || {}) }
|
||||
});
|
||||
const payload = await response.json().catch(() => ({}));
|
||||
return { response, payload };
|
||||
}
|
||||
|
||||
function assertOk(result, label) {
|
||||
assert.equal(result.response.ok, true, `${label}: ${result.response.status} ${result.payload.detail || result.payload.error || ""}`);
|
||||
return result.payload;
|
||||
}
|
||||
|
||||
async function login(email) {
|
||||
const result = await request("/api/auth/login", {}, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ email, password: "Demo@123456" })
|
||||
});
|
||||
return { authorization: `Bearer ${assertOk(result, `${email} 登录`).session.token}` };
|
||||
}
|
||||
|
||||
function findEntitlement(payload, key) {
|
||||
const entitlement = payload.entitlements?.find((item) => item.key === key);
|
||||
assert.ok(entitlement, `缺少权益 ${key}`);
|
||||
return entitlement;
|
||||
}
|
||||
|
||||
function snapshot(entitlement) {
|
||||
return {
|
||||
limitValue: Number(entitlement.limitValue || 0),
|
||||
enabled: Boolean(entitlement.enabled),
|
||||
enforcement: entitlement.enforcement || "block",
|
||||
overrideReason: entitlement.overrideReason || ""
|
||||
};
|
||||
}
|
||||
|
||||
async function updateEntitlement(headers, key, body) {
|
||||
return request(`/api/organizations/org-studio-lab/entitlements/${encodeURIComponent(key)}`, headers, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
}
|
||||
|
||||
const owner = { ...(await login("producer@local.test")), ...scope };
|
||||
const writer = { ...(await login("writer@local.test")), ...scope };
|
||||
|
||||
let apiClientOriginal = null;
|
||||
let workspaceOriginal = null;
|
||||
let cloudFeatureOriginal = null;
|
||||
|
||||
try {
|
||||
const commercial = assertOk(await request("/api/organizations/org-studio-lab/commercial", owner), "读取商业权益");
|
||||
assert.ok(Array.isArray(commercial.planTemplates) && commercial.planTemplates.length >= 3, "必须返回套餐模板");
|
||||
assert.ok(Array.isArray(commercial.entitlements) && commercial.entitlements.length >= 10, "必须返回组织权益矩阵");
|
||||
assert.ok(commercial.entitlementSummary && Number.isFinite(commercial.entitlementSummary.total), "必须返回权益摘要");
|
||||
|
||||
const apiClientEntitlement = findEntitlement(commercial, "limit.api_clients");
|
||||
apiClientOriginal = snapshot(apiClientEntitlement);
|
||||
const writerDenied = await updateEntitlement(writer, "limit.api_clients", { limitValue: apiClientOriginal.limitValue + 1 });
|
||||
assert.equal(writerDenied.response.status, 403, "普通编剧不应修改商业权益");
|
||||
|
||||
const apiLimit = Math.max(1, Number(apiClientEntitlement.usedValue || 0));
|
||||
const apiLimitUpdate = assertOk(await updateEntitlement(owner, "limit.api_clients", {
|
||||
limitValue: apiLimit,
|
||||
enabled: true,
|
||||
enforcement: "block",
|
||||
overrideReason: "smoke entitlement limit"
|
||||
}), "压低 API 客户端权益");
|
||||
assert.equal(findEntitlement(apiLimitUpdate, "limit.api_clients").status, "blocked", "已用量达到额度时应显示 blocked");
|
||||
|
||||
const blockedClient = await request("/api/system/api-clients", owner, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ name: `blocked-client-${Date.now()}`, scopes: ["jobs:read"] })
|
||||
});
|
||||
assert.equal(blockedClient.response.status, 429, "API 客户端超过权益时必须被阻断");
|
||||
assert.equal(blockedClient.payload.error, "entitlement_limit_exceeded", "API 客户端权益阻断错误码不稳定");
|
||||
|
||||
const workspaceEntitlement = findEntitlement(commercial, "limit.workspaces");
|
||||
workspaceOriginal = snapshot(workspaceEntitlement);
|
||||
const workspaceLimit = Math.max(1, Number(workspaceEntitlement.usedValue || 0));
|
||||
assertOk(await updateEntitlement(owner, "limit.workspaces", {
|
||||
limitValue: workspaceLimit,
|
||||
enabled: true,
|
||||
enforcement: "block",
|
||||
overrideReason: "smoke workspace limit"
|
||||
}), "压低工作区权益");
|
||||
const blockedWorkspace = await request("/api/workspaces", owner, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ name: `Blocked Workspace ${Date.now()}` })
|
||||
});
|
||||
assert.equal(blockedWorkspace.response.status, 429, "工作区超过权益时必须被阻断");
|
||||
assert.equal(blockedWorkspace.payload.error, "entitlement_limit_exceeded", "工作区权益阻断错误码不稳定");
|
||||
|
||||
const cloudEntitlement = findEntitlement(commercial, "feature.external_cloud_connectors");
|
||||
cloudFeatureOriginal = snapshot(cloudEntitlement);
|
||||
assertOk(await updateEntitlement(owner, "feature.external_cloud_connectors", {
|
||||
limitValue: 1,
|
||||
enabled: false,
|
||||
enforcement: "block",
|
||||
overrideReason: "smoke cloud connector disabled"
|
||||
}), "关闭外部云连接器权益");
|
||||
const blockedCloudConnector = await request("/api/platform/models/register", owner, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
label: `Blocked Cloud Connector ${Date.now()}`,
|
||||
endpoint: "https://example.com/v1",
|
||||
kind: "openai-compatible",
|
||||
capability: ["chat"],
|
||||
costMode: "mixed",
|
||||
approvalRequired: true
|
||||
})
|
||||
});
|
||||
assert.equal(blockedCloudConnector.response.status, 403, "外部云连接器权益关闭时必须被阻断");
|
||||
assert.equal(blockedCloudConnector.payload.error, "entitlement_disabled", "外部连接器权益错误码不稳定");
|
||||
|
||||
console.log(`entitlement smoke passed: ${api}`);
|
||||
} finally {
|
||||
if (apiClientOriginal) await updateEntitlement(owner, "limit.api_clients", apiClientOriginal);
|
||||
if (workspaceOriginal) await updateEntitlement(owner, "limit.workspaces", workspaceOriginal);
|
||||
if (cloudFeatureOriginal) await updateEntitlement(owner, "feature.external_cloud_connectors", cloudFeatureOriginal);
|
||||
}
|
||||
Reference in New Issue
Block a user