cloudcc-cli 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cloudcc-cache.json +4 -52
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_CLASS.md +15 -1
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_SCHEDULE.md +82 -8
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_TRIGGER.md +13 -0
- package/.cursor/skills/cloudcc-cli-dev/CLI_CHEATSHEET.md +234 -77
- package/.cursor/skills/cloudcc-cli-dev/CUSTOM-SETTING-API.md +37 -216
- package/.cursor/skills/cloudcc-cli-dev/INSTALL_AND_BOOTSTRAP.md +9 -6
- package/.cursor/skills/cloudcc-cli-dev/OBJECTS_AND_FIELDS.md +99 -5
- package/.cursor/skills/cloudcc-cli-dev/REQUIREMENTS_BREAKDOWN.md +15 -0
- package/.cursor/skills/cloudcc-cli-dev/SKILL.md +29 -7
- package/.cursor/skills/cloudcc-cli-dev/STATIC-RESOURCE-API.md +60 -0
- package/.cursor/skills/cloudcc-cli-dev/VUE_CUSTOM_PAGE.md +216 -0
- package/.cursor/skills/cloudcc-cli-dev/docs//350/207/252/345/256/232/344/271/211/351/241/265/351/235/242.md +228 -0
- package/README.md +11 -0
- package/bin/index.js +3 -0
- package/package.json +2 -2
- package/src/application/delete.js +59 -0
- package/src/application/get.js +31 -5
- package/src/application/index.js +1 -0
- package/src/classes/delete.js +43 -0
- package/src/classes/detail.js +14 -7
- package/src/classes/index.js +1 -0
- package/src/customPage/create.js +74 -12
- package/src/customPage/delete.js +2 -2
- package/src/customPage/get.js +1 -1
- package/src/customSetting/create.js +27 -0
- package/src/customSetting/delete.js +26 -0
- package/src/customSetting/detail.js +24 -0
- package/src/customSetting/get.js +25 -0
- package/src/customSetting/index.js +4 -0
- package/src/fields/delete.js +52 -0
- package/src/fields/index.js +1 -0
- package/src/menu/create-page.js +16 -25
- package/src/menu/create.js +9 -3
- package/src/menu/delete.js +59 -0
- package/src/menu/get.js +56 -0
- package/src/menu/index.js +2 -0
- package/src/object/delete.js +51 -0
- package/src/object/index.js +1 -0
- package/src/plugin/detail.js +14 -6
- package/src/plugin/publish1.js +3 -3
- package/src/recordType/get.js +1 -1
- package/src/scheduleJob/delete.js +26 -0
- package/src/scheduleJob/detail.js +23 -0
- package/src/scheduleJob/get.js +26 -0
- package/src/scheduleJob/index.js +10 -0
- package/src/staticResource/count.js +25 -0
- package/src/staticResource/delete.js +26 -0
- package/src/staticResource/detail.js +24 -0
- package/src/staticResource/doc.js +106 -0
- package/src/staticResource/get.js +25 -0
- package/src/staticResource/index.js +12 -0
- package/src/timer/delete.js +43 -0
- package/src/timer/index.js +1 -0
- package/src/triggers/delete.js +46 -0
- package/src/triggers/index.js +1 -0
- package/test/application.cli.test.js +49 -8
- package/test/classes.cli.test.js +9 -3
- package/test/customSetting.cli.test.js +84 -0
- package/test/fields.cli.test.js +18 -3
- package/test/menu.cli.test.js +34 -4
- package/test/object.cli.test.js +17 -1
- package/test/scheduleJob.cli.test.js +52 -0
- package/test/staticResource.cli.test.js +78 -0
- package/test/timer.cli.test.js +8 -2
- package/test/trigger.cli.test.js +8 -2
- package/build/component-cc-test-001.common.js +0 -831
- package/build/component-cc-test-001.common.js.map +0 -1
- package/build/component-cc-test-001.css +0 -1
- package/build/component-cc-test-001.umd.js +0 -874
- package/build/component-cc-test-001.umd.js.map +0 -1
- package/build/component-cc-test-001.umd.min.js +0 -8
- package/build/component-cc-test-001.umd.min.js.map +0 -1
- package/build/demo.html +0 -1
- package/classes/CCdd/CCdd.java +0 -22
- package/classes/CCdd/CCddTest.java +0 -11
- package/classes/CCdd/config.json +0 -1
- package/core.zip +0 -0
- package/plugins/cc-test-001/cc-test-001.vue +0 -32
- package/plugins/cc-test-001/components/HelloWorld.vue +0 -11
- package/plugins/cc-test-001/config.json +0 -6
- package/schedule/CCdd/CCdd.java +0 -11
- package/schedule/CCdd/config.json +0 -1
- package/target/ccopenapi-0.0.4-classes.jar +0 -0
- package/target/ccopenapi-0.0.4.jar +0 -0
- package/target/classes/CCdd/CCdd.class +0 -0
- package/target/classes/CCdd/CCddTest.class +0 -0
- package/target/classes/CCdd/config.json +0 -1
- package/target/maven-archiver/pom.properties +0 -3
- package/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +0 -20
- package/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +0 -19
- /package/{docs → .cursor/skills/cloudcc-cli-dev/docs}/CloudCC/350/207/252/345/256/232/344/271/211/347/273/204/344/273/266/344/275/277/347/224/250/350/257/264/346/230/216.md" +0 -0
- /package/{docs → .cursor/skills/cloudcc-cli-dev/docs}/cloudcc/345/256/232/346/227/266/344/275/234/344/270/232.md" +0 -0
- /package/{docs → .cursor/skills/cloudcc-cli-dev/docs}/cloudcc/345/256/232/346/227/266/347/261/273.md" +0 -0
- /package/{docs → .cursor/skills/cloudcc-cli-dev/docs}//350/207/252/345/256/232/344/271/211/347/261/273.md" +0 -0
- /package/{docs → .cursor/skills/cloudcc-cli-dev/docs}//350/247/246/345/217/221/345/231/250/347/261/273.md" +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const test = require("node:test");
|
|
2
|
+
const assert = require("node:assert/strict");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { exec } = require("node:child_process");
|
|
5
|
+
const { promisify } = require("node:util");
|
|
6
|
+
|
|
7
|
+
const execAsync = promisify(exec);
|
|
8
|
+
const repoRoot = path.resolve(__dirname, "..");
|
|
9
|
+
|
|
10
|
+
function quoteArg(value) {
|
|
11
|
+
return `'${String(value).replace(/'/g, `'\\''`)}'`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function runCc(args) {
|
|
15
|
+
const cmd = `npx --prefix "${repoRoot}" cc ${args.map(quoteArg).join(" ")}`;
|
|
16
|
+
return execAsync(cmd, { cwd: repoRoot });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
test("自定义设置管理:get -> detail(可选 create/delete)", async (t) => {
|
|
20
|
+
let firstSettingId = null;
|
|
21
|
+
let createdSettingId = null;
|
|
22
|
+
|
|
23
|
+
t.test("1) 获取自定义设置列表", async () => {
|
|
24
|
+
const { stdout } = await runCc(["get", "customSetting", repoRoot]);
|
|
25
|
+
const list = JSON.parse(stdout.trim() || "[]");
|
|
26
|
+
assert.ok(Array.isArray(list), "get customSetting 应返回数组");
|
|
27
|
+
if (list.length > 0) {
|
|
28
|
+
firstSettingId = list[0].objid || list[0].id || null;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
t.test("2) 查询详情(若存在 id)", async () => {
|
|
33
|
+
if (!firstSettingId) {
|
|
34
|
+
console.error("[customSetting-test] 无可用 settingId,跳过 detail");
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
await assert.doesNotReject(() => runCc(["detail", "customSetting", repoRoot, firstSettingId]));
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
t.test("3) 创建自定义设置(可选能力校验)", async () => {
|
|
41
|
+
const stamp = Date.now();
|
|
42
|
+
const body = encodeURI(
|
|
43
|
+
JSON.stringify({
|
|
44
|
+
label: `CliSetting_${stamp}`,
|
|
45
|
+
schemetableName: `cli_setting_${stamp}`,
|
|
46
|
+
setType: "list",
|
|
47
|
+
shareType: "public",
|
|
48
|
+
description: "cli test",
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
let out = "";
|
|
53
|
+
try {
|
|
54
|
+
const res = await runCc(["create", "customSetting", repoRoot, body]);
|
|
55
|
+
out = `${res.stdout}\n${res.stderr}`.trim();
|
|
56
|
+
assert.match(out, /Success|成功/i, "create customSetting 应输出成功信息");
|
|
57
|
+
} catch (e) {
|
|
58
|
+
const msg = `${e.stderr || e.message || ""}`;
|
|
59
|
+
if (/500|NullPointerException|Create Custom Setting Failed/i.test(msg)) {
|
|
60
|
+
console.error("[customSetting-test] 当前环境不支持该最小创建体,跳过 create/delete 强校验");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
throw e;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 回查列表,尽量拿到刚创建的 id(不同环境字段名可能有差异)
|
|
67
|
+
const { stdout: listOut } = await runCc(["get", "customSetting", repoRoot]);
|
|
68
|
+
const list = JSON.parse(listOut.trim() || "[]");
|
|
69
|
+
const hit = list.find((x) => `${x.label || ""}`.includes(`CliSetting_${stamp}`));
|
|
70
|
+
if (hit) {
|
|
71
|
+
createdSettingId = hit.objid || hit.id || null;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
t.test("4) 删除刚创建自定义设置(若拿到 id)", async () => {
|
|
76
|
+
if (!createdSettingId) {
|
|
77
|
+
console.error("[customSetting-test] 未定位到新建记录 id,跳过 delete");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const { stdout, stderr } = await runCc(["delete", "customSetting", repoRoot, createdSettingId]);
|
|
81
|
+
const out = `${stdout}\n${stderr}`.trim();
|
|
82
|
+
assert.match(out, /Success|成功/i, "delete customSetting 应输出成功信息");
|
|
83
|
+
});
|
|
84
|
+
});
|
package/test/fields.cli.test.js
CHANGED
|
@@ -16,11 +16,12 @@ async function runCc(args) {
|
|
|
16
16
|
return execAsync(cmd, { cwd: repoRoot });
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
test("字段管理流程:获取对象列表→create 字段→get
|
|
19
|
+
test("字段管理流程:获取对象列表→create 字段→get 字段列表→delete", async (t) => {
|
|
20
20
|
let objPrefix = null;
|
|
21
21
|
let objId = null;
|
|
22
22
|
let objName = null;
|
|
23
23
|
const fieldLabel = `AutoField_${Date.now()}`;
|
|
24
|
+
let fieldId = null;
|
|
24
25
|
|
|
25
26
|
t.test("1) 获取对象列表(取第一个对象的 id 和 objprefix)", async () => {
|
|
26
27
|
// 只取自定义对象,避免标准对象在部分环境下字段接口异常
|
|
@@ -62,8 +63,22 @@ test("字段管理流程:获取对象列表→create 字段→get 字段列表
|
|
|
62
63
|
if (res.stdFields) assert.ok(Array.isArray(res.stdFields), "stdFields 应为数组");
|
|
63
64
|
if (res.cusFields) assert.ok(Array.isArray(res.cusFields), "cusFields 应为数组");
|
|
64
65
|
|
|
65
|
-
//
|
|
66
|
+
// 尽量校验新字段是否已出现,并记录 id
|
|
66
67
|
const allCus = Array.isArray(res.cusFields) ? res.cusFields : [];
|
|
67
|
-
const hit = allCus.
|
|
68
|
+
const hit = allCus.find((f) => f.fieldname === fieldLabel);
|
|
69
|
+
if (hit && hit.id) {
|
|
70
|
+
fieldId = hit.id;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
t.test("4) delete 删除刚创建字段", async () => {
|
|
75
|
+
// 个别环境字段列表刷新有延迟,找不到时跳过强校验
|
|
76
|
+
if (!fieldId) {
|
|
77
|
+
console.error("[fields-test] 未在列表中定位到新字段 id,跳过 delete");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const { stdout, stderr } = await runCc(["delete", "fields", repoRoot, fieldId, objId]);
|
|
81
|
+
const out = `${stdout}\n${stderr}`.trim();
|
|
82
|
+
assert.match(out, /Success|成功/i, "delete fields 应输出成功信息");
|
|
68
83
|
});
|
|
69
84
|
});
|
package/test/menu.cli.test.js
CHANGED
|
@@ -19,8 +19,10 @@ async function runCc(args) {
|
|
|
19
19
|
test("菜单管理流程:获取对象列表→create menu object", async (t) => {
|
|
20
20
|
let objectId = null;
|
|
21
21
|
let objectName = null;
|
|
22
|
+
const tabName = `CC测试菜单Tab_${Date.now()}`;
|
|
23
|
+
let menuId = null;
|
|
22
24
|
|
|
23
|
-
t.test("1) 获取自定义对象列表(取第一个自定义对象 id 用于创建菜单)", async () => {
|
|
25
|
+
await t.test("1) 获取自定义对象列表(取第一个自定义对象 id 用于创建菜单)", async () => {
|
|
24
26
|
const { stdout } = await runCc(["get", "object", repoRoot, "custom"]);
|
|
25
27
|
const list = JSON.parse(stdout.trim());
|
|
26
28
|
assert.ok(Array.isArray(list), "get object custom 应返回数组");
|
|
@@ -32,10 +34,38 @@ test("菜单管理流程:获取对象列表→create menu object", async (t) =
|
|
|
32
34
|
console.error(`\n[menu-test] 目标自定义对象: ${objectName || "Unknown"} (id=${objectId})`);
|
|
33
35
|
});
|
|
34
36
|
|
|
35
|
-
t.test("2) 创建对象类型菜单(create menu object)", async () => {
|
|
37
|
+
await t.test("2) 创建对象类型菜单(create menu object)", async () => {
|
|
36
38
|
assert.ok(objectId, "需要 objectId");
|
|
37
|
-
await
|
|
38
|
-
|
|
39
|
+
const { stdout, stderr } = await runCc(["create", "menu", "object", repoRoot, objectId, tabName]);
|
|
40
|
+
const out = `${stdout}\n${stderr}`.trim();
|
|
41
|
+
assert.match(out, /Success|成功/i, "create menu object 应输出成功信息");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
await t.test("3) 查询菜单列表(get menu)并匹配刚创建菜单", async () => {
|
|
45
|
+
const { stdout } = await runCc(["get", "menu", repoRoot]);
|
|
46
|
+
const list = JSON.parse(stdout.trim());
|
|
47
|
+
assert.ok(Array.isArray(list), "get menu 应返回数组");
|
|
48
|
+
const hit = list.find((item) =>
|
|
49
|
+
item.tabName === tabName ||
|
|
50
|
+
item.tabLabel === tabName ||
|
|
51
|
+
item.label === tabName ||
|
|
52
|
+
item.name === tabName
|
|
39
53
|
);
|
|
54
|
+
if (!hit) {
|
|
55
|
+
console.error("[menu-test] 未在菜单列表定位到刚创建菜单,跳过删除步骤");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
menuId = hit.id;
|
|
59
|
+
assert.ok(menuId, "命中菜单应包含 id");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await t.test("4) 删除菜单(delete menu)", async () => {
|
|
63
|
+
if (!menuId) {
|
|
64
|
+
console.error("[menu-test] 无 menuId,跳过 delete menu");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const { stdout, stderr } = await runCc(["delete", "menu", repoRoot, menuId]);
|
|
68
|
+
const out = `${stdout}\n${stderr}`.trim();
|
|
69
|
+
assert.match(out, /Success|成功/i, "delete menu 应输出成功信息");
|
|
40
70
|
});
|
|
41
71
|
});
|
package/test/object.cli.test.js
CHANGED
|
@@ -16,10 +16,11 @@ async function runCc(args) {
|
|
|
16
16
|
return execAsync(cmd, { cwd: repoRoot });
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
test("对象管理流程:get 对象列表→create 对象→get
|
|
19
|
+
test("对象管理流程:get 对象列表→create 对象→get 列表校验→delete", async (t) => {
|
|
20
20
|
const objectLabel = `TestObj${Date.now()}`;
|
|
21
21
|
const labelNeedle = "testobj";
|
|
22
22
|
let createdSlugHit = false;
|
|
23
|
+
let createdObjId = null;
|
|
23
24
|
|
|
24
25
|
t.test("1) create 创建自定义对象", async () => {
|
|
25
26
|
await assert.doesNotReject(() => runCc(["create", "object", repoRoot, objectLabel]));
|
|
@@ -46,6 +47,14 @@ test("对象管理流程:get 对象列表→create 对象→get 列表校验",
|
|
|
46
47
|
return s.includes(labelNeedle) || l.includes(labelNeedle);
|
|
47
48
|
});
|
|
48
49
|
assert.ok(createdSlugHit, "custom 列表应包含刚创建的自定义对象(按 testobj 关键字匹配)");
|
|
50
|
+
|
|
51
|
+
const created = list.find((o) => {
|
|
52
|
+
const l = `${o.label || o.objname || ""}`.toLowerCase();
|
|
53
|
+
return l === objectLabel.toLowerCase();
|
|
54
|
+
});
|
|
55
|
+
if (created && created.id) {
|
|
56
|
+
createdObjId = created.id;
|
|
57
|
+
}
|
|
49
58
|
});
|
|
50
59
|
|
|
51
60
|
t.test("4) get 获取全部对象列表(both / 默认)并校验包含新对象", async () => {
|
|
@@ -61,4 +70,11 @@ test("对象管理流程:get 对象列表→create 对象→get 列表校验",
|
|
|
61
70
|
});
|
|
62
71
|
assert.ok(found || createdSlugHit, "both 列表应包含刚创建的自定义对象");
|
|
63
72
|
});
|
|
73
|
+
|
|
74
|
+
t.test("5) delete 删除刚创建对象", async () => {
|
|
75
|
+
assert.ok(createdObjId, "delete object 前应有 createdObjId");
|
|
76
|
+
const { stdout, stderr } = await runCc(["delete", "object", repoRoot, createdObjId]);
|
|
77
|
+
const out = `${stdout}\n${stderr}`.trim();
|
|
78
|
+
assert.match(out, /Success|成功/i, "delete object 应输出成功信息");
|
|
79
|
+
});
|
|
64
80
|
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const test = require("node:test");
|
|
2
|
+
const assert = require("node:assert/strict");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { exec } = require("node:child_process");
|
|
5
|
+
const { promisify } = require("node:util");
|
|
6
|
+
|
|
7
|
+
const execAsync = promisify(exec);
|
|
8
|
+
const repoRoot = path.resolve(__dirname, "..");
|
|
9
|
+
|
|
10
|
+
function quoteArg(value) {
|
|
11
|
+
return `'${String(value).replace(/'/g, `'\\''`)}'`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function runCc(args) {
|
|
15
|
+
const cmd = `npx --prefix "${repoRoot}" cc ${args.map(quoteArg).join(" ")}`;
|
|
16
|
+
return execAsync(cmd, { cwd: repoRoot });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
test("定时作业管理:get -> detail(可选 delete)", async (t) => {
|
|
20
|
+
let firstJobId = null;
|
|
21
|
+
|
|
22
|
+
t.test("1) 获取定时作业列表", async () => {
|
|
23
|
+
const { stdout } = await runCc(["get", "scheduleJob", repoRoot]);
|
|
24
|
+
const list = JSON.parse(stdout.trim() || "[]");
|
|
25
|
+
assert.ok(Array.isArray(list), "get scheduleJob 应返回数组");
|
|
26
|
+
if (list.length > 0 && list[0].id) {
|
|
27
|
+
firstJobId = list[0].id;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
t.test("2) 获取定时作业详情(若存在 id)", async () => {
|
|
32
|
+
if (!firstJobId) {
|
|
33
|
+
console.error("[scheduleJob-test] 无可用 jobId,跳过 detail");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
await assert.doesNotReject(() => runCc(["detail", "scheduleJob", firstJobId, repoRoot]));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
t.test("3) 删除定时作业(仅在 ENABLE_DESTRUCTIVE_TESTS=1 时执行)", async () => {
|
|
40
|
+
if (process.env.ENABLE_DESTRUCTIVE_TESTS !== "1") {
|
|
41
|
+
console.error("[scheduleJob-test] 默认跳过 delete(设置 ENABLE_DESTRUCTIVE_TESTS=1 可启用)");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!firstJobId) {
|
|
45
|
+
console.error("[scheduleJob-test] 无可用 jobId,跳过 delete");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const { stdout, stderr } = await runCc(["delete", "scheduleJob", firstJobId, repoRoot]);
|
|
49
|
+
const out = `${stdout}\n${stderr}`.trim();
|
|
50
|
+
assert.match(out, /Success|成功/i, "delete scheduleJob 应输出成功信息");
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const test = require("node:test");
|
|
2
|
+
const assert = require("node:assert/strict");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { exec } = require("node:child_process");
|
|
5
|
+
const { promisify } = require("node:util");
|
|
6
|
+
|
|
7
|
+
const execAsync = promisify(exec);
|
|
8
|
+
const repoRoot = path.resolve(__dirname, "..");
|
|
9
|
+
|
|
10
|
+
function quoteArg(value) {
|
|
11
|
+
return `'${String(value).replace(/'/g, `'\\''`)}'`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function runCc(args) {
|
|
15
|
+
const cmd = `npx --prefix "${repoRoot}" cc ${args.map(quoteArg).join(" ")}`;
|
|
16
|
+
return execAsync(cmd, { cwd: repoRoot });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
test("静态资源管理:get -> detail -> count(可选 delete)", async (t) => {
|
|
20
|
+
let firstResourceId = null;
|
|
21
|
+
|
|
22
|
+
t.test("1) 获取静态资源列表", async () => {
|
|
23
|
+
try {
|
|
24
|
+
const { stdout } = await runCc(["get", "staticResource", repoRoot]);
|
|
25
|
+
const list = JSON.parse(stdout.trim() || "[]");
|
|
26
|
+
assert.ok(Array.isArray(list), "get staticResource 应返回数组");
|
|
27
|
+
if (list.length > 0) {
|
|
28
|
+
firstResourceId = list[0].id || list[0].objid || null;
|
|
29
|
+
}
|
|
30
|
+
} catch (e) {
|
|
31
|
+
const msg = `${e.stderr || e.message || ""}`;
|
|
32
|
+
if (/404|Get Static Resource Failed/i.test(msg)) {
|
|
33
|
+
console.error("[staticResource-test] 当前环境未开放 staticResource 接口,跳过相关强校验");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
throw e;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
t.test("2) 查询静态资源详情(若存在 id)", async () => {
|
|
41
|
+
if (!firstResourceId) {
|
|
42
|
+
console.error("[staticResource-test] 无可用 resourceId,跳过 detail");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
await assert.doesNotReject(() =>
|
|
46
|
+
runCc(["detail", "staticResource", repoRoot, firstResourceId])
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
t.test("3) 统计静态资源容量(count)", async () => {
|
|
51
|
+
try {
|
|
52
|
+
const { stdout } = await runCc(["count", "staticResource", repoRoot]);
|
|
53
|
+
const data = JSON.parse(stdout.trim() || "{}");
|
|
54
|
+
assert.equal(typeof data, "object", "count staticResource 应返回对象");
|
|
55
|
+
} catch (e) {
|
|
56
|
+
const msg = `${e.stderr || e.message || ""}`;
|
|
57
|
+
if (/404|Count Static Resource Failed/i.test(msg)) {
|
|
58
|
+
console.error("[staticResource-test] 当前环境未开放 staticResource count 接口,跳过 count 强校验");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
throw e;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
t.test("4) 删除静态资源(仅在 ENABLE_DESTRUCTIVE_TESTS=1 时执行)", async () => {
|
|
66
|
+
if (process.env.ENABLE_DESTRUCTIVE_TESTS !== "1") {
|
|
67
|
+
console.error("[staticResource-test] 默认跳过 delete(设置 ENABLE_DESTRUCTIVE_TESTS=1 可启用)");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (!firstResourceId) {
|
|
71
|
+
console.error("[staticResource-test] 无可用 resourceId,跳过 delete");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const { stdout, stderr } = await runCc(["delete", "staticResource", repoRoot, firstResourceId]);
|
|
75
|
+
const out = `${stdout}\n${stderr}`.trim();
|
|
76
|
+
assert.match(out, /Success|成功/i, "delete staticResource 应输出成功信息");
|
|
77
|
+
});
|
|
78
|
+
});
|
package/test/timer.cli.test.js
CHANGED
|
@@ -18,7 +18,7 @@ async function runCc(args) {
|
|
|
18
18
|
return execAsync(cmd, { cwd: repoRoot });
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
test("
|
|
21
|
+
test("定时任务管理流程:创建→发布→拉取→线上详情→列表→批量拉取→delete→清空 schedule 文件夹", async (t) => {
|
|
22
22
|
const timerName = `CCTimer${Date.now()}`;
|
|
23
23
|
const timerDir = path.join(scheduleRoot, timerName);
|
|
24
24
|
const configPath = path.join(timerDir, "config.json");
|
|
@@ -96,7 +96,13 @@ test("定时任务管理流程:创建→发布→拉取→线上详情→列
|
|
|
96
96
|
assert.ok(afterCount >= beforeCount, "pullList 之后 schedule 目录应存在/可用");
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
t.test("7)
|
|
99
|
+
t.test("7) 删除当前创建定时类(delete timer)", async () => {
|
|
100
|
+
const { stdout, stderr } = await runCc(["delete", "timer", timerName, repoRoot]);
|
|
101
|
+
const out = `${stdout}\n${stderr}`.trim();
|
|
102
|
+
assert.match(out, /Success|成功/i, "delete timer 应输出成功信息");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
t.test("8) 清空 schedule 文件夹", async () => {
|
|
100
106
|
if (fs.existsSync(scheduleRoot)) {
|
|
101
107
|
fs.rmSync(scheduleRoot, { recursive: true, force: true });
|
|
102
108
|
}
|
package/test/trigger.cli.test.js
CHANGED
|
@@ -18,7 +18,7 @@ async function runCc(args) {
|
|
|
18
18
|
return execAsync(cmd, { cwd: repoRoot });
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
test("触发器管理流程:获取对象→创建→doc
|
|
21
|
+
test("触发器管理流程:获取对象→创建→doc→发布→拉取→线上详情→列表→批量拉取→delete→清空 triggers 文件夹", async (t) => {
|
|
22
22
|
let schemetableName = "Account";
|
|
23
23
|
let targetObjectId = null;
|
|
24
24
|
let apiname = null;
|
|
@@ -135,7 +135,13 @@ test("触发器管理流程:获取对象→创建→doc→发布→拉取→
|
|
|
135
135
|
assert.ok(afterCount >= beforeCount, "pullList 之后 triggers 目录应存在/可用");
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
-
t.test("9)
|
|
138
|
+
t.test("9) 删除当前创建触发器(delete triggers)", async () => {
|
|
139
|
+
const { stdout, stderr } = await runCc(["delete", "triggers", namePath, repoRoot]);
|
|
140
|
+
const out = `${stdout}\n${stderr}`.trim();
|
|
141
|
+
assert.match(out, /Success|成功/i, "delete triggers 应输出成功信息");
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
t.test("10) 清空 triggers 文件夹", async () => {
|
|
139
145
|
if (fs.existsSync(triggersRoot)) {
|
|
140
146
|
fs.rmSync(triggersRoot, { recursive: true, force: true });
|
|
141
147
|
}
|