Files
modelstudioai__cli/packages/commands/tests/e2e/memory/memory-profile-update.e2e.test.ts
T
zeyu.fz 75a7100702 feat(memory): 完善记忆及画像相关命令支持并统一参数
- 在 CLI 文档中新增记忆 live 场景说明与变量需求
- 扩展 CLI 命令集,添加记忆画像 Profile 的增删改查功能
- 统一所有记忆相关命令加入 workspace 和 library 参数支持
- 记忆添加命令支持自定义 meta_data,完善输入校验和互斥说明
- 记忆删除、列表、获取用户画像等命令增加工作空间参数支持
- 画像模板相关命令新增分页参数及属性操作接口
- 重构知识命令共享模块,移除重复的 workspace 解析实现,统一导出
- 优化命令输出格式,文本模式下显示更多详细信息和异常提示
- 提供完整的示例参数,增强命令使用说明和提示文档
2026-09-10 14:40:39 +08:00

215 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, test } from "vite-plus/test";
import { parseStdoutJson, runCommandE2e, runCommandHelp } from "../helpers.ts";
import { MEMORY_PROFILE_UPDATE_ROUTES } from "../topic-routes.ts";
import { TEST_WORKSPACE_ARGS, type MemoryDryRunBody } from "./shared.ts";
describe("e2e: memory profile update", () => {
test("--help 展示 flags", async () => {
const { stderr, exitCode } = await runCommandHelp(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--help",
]);
expect(exitCode, stderr).toBe(0);
expect(stderr).toMatch(/--schema-id/i);
expect(stderr).toMatch(/--name/i);
expect(stderr).toMatch(/--description/i);
expect(stderr).toMatch(/--attributes-operations/i);
expect(stderr).toMatch(/--memory-library-id/i);
expect(stderr).toMatch(/--workspace-id/i);
});
test("缺 --schema-id 报 USAGE (2)", async () => {
const { exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--name",
"user_basic_v2",
]);
expect(exitCode).toBe(2);
});
test("三个可改字段全不传报 USAGE (2)", async () => {
const { stderr, exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
]);
expect(exitCode).toBe(2);
expect(stderr).toMatch(/--attributes-operations/i);
});
test("--attributes-operations 非法 JSON 报 USAGE (2)", async () => {
const { exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
"--attributes-operations",
"[oops",
...TEST_WORKSPACE_ARGS,
"--dry-run",
]);
expect(exitCode).toBe(2);
});
test("--attributes-operations 传对象而非数组报 USAGE (2)", async () => {
const { exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
"--attributes-operations",
'{"op":"add","name":"plan"}',
...TEST_WORKSPACE_ARGS,
"--dry-run",
]);
expect(exitCode).toBe(2);
});
test("op 非法取值报 USAGE (2)", async () => {
const { stderr, exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
"--attributes-operations",
'[{"op":"upsert","name":"plan"}]',
...TEST_WORKSPACE_ARGS,
"--dry-run",
]);
expect(exitCode).toBe(2);
expect(stderr).toMatch(/op/i);
});
test("op=add 缺 name 报 USAGE (2)", async () => {
const { stderr, exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
"--attributes-operations",
'[{"op":"add","description":"套餐"}]',
...TEST_WORKSPACE_ARGS,
"--dry-run",
]);
expect(exitCode).toBe(2);
expect(stderr).toMatch(/name/i);
});
test("op=delete 缺 attribute_id 报 USAGE (2)", async () => {
const { stderr, exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
"--attributes-operations",
'[{"op":"delete"}]',
...TEST_WORKSPACE_ARGS,
"--dry-run",
]);
expect(exitCode).toBe(2);
expect(stderr).toMatch(/attribute_id/i);
});
test("op=update 缺 attribute_id 报 USAGE (2)", async () => {
const { exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
"--attributes-operations",
'[{"op":"update","name":"plan"}]',
...TEST_WORKSPACE_ARGS,
"--dry-run",
]);
expect(exitCode).toBe(2);
});
test("--dry-run 断言 endpoint / PATCH / name 与 description", async () => {
const { stdout, stderr, exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
"--name",
"user_basic_v2",
"--description",
"升级后的画像",
...TEST_WORKSPACE_ARGS,
"--dry-run",
"--output",
"json",
]);
expect(exitCode, stderr).toBe(0);
const data = parseStdoutJson<MemoryDryRunBody>(stdout);
expect(data.endpoint).toMatch(/api\/v2\/apps\/memory\/profile_schemas\/schema_test$/);
expect(data.method).toBe("PATCH");
expect(data.request?.name).toBe("user_basic_v2");
expect(data.request?.description).toBe("升级后的画像");
expect(data.request?.attributes_operations).toBeUndefined();
});
test("--dry-run 断言三种 op 原样进 body(含 default_value: null)", async () => {
const { stdout, stderr, exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
"--attributes-operations",
'[{"op":"add","name":"plan","default_value":"free"},' +
'{"op":"update","attribute_id":"attr_1","default_value":null},' +
'{"op":"delete","attribute_id":"attr_2"}]',
...TEST_WORKSPACE_ARGS,
"--dry-run",
"--output",
"json",
]);
expect(exitCode, stderr).toBe(0);
const data = parseStdoutJson<MemoryDryRunBody>(stdout);
expect(data.request?.attributes_operations).toEqual([
{ op: "add", name: "plan", default_value: "free" },
{ op: "update", attribute_id: "attr_1", default_value: null },
{ op: "delete", attribute_id: "attr_2" },
]);
});
test("--dry-run 断言 memory_library_id 进 body 而不是 query string", async () => {
const { stdout, stderr, exitCode } = await runCommandE2e(MEMORY_PROFILE_UPDATE_ROUTES, [
"memory",
"profile",
"update",
"--schema-id",
"schema_test",
"--name",
"user_basic_v2",
"--memory-library-id",
"lib_test",
...TEST_WORKSPACE_ARGS,
"--dry-run",
"--output",
"json",
]);
expect(exitCode, stderr).toBe(0);
const data = parseStdoutJson<MemoryDryRunBody>(stdout);
// UpdateProfileSchema is the only profile endpoint carrying the library in the body
expect(data.request?.memory_library_id).toBe("lib_test");
expect(data.endpoint).not.toMatch(/memory_library_id/);
});
});
// The live update path is exercised inside the self-cleaning chain in
// memory-profile-delete.e2e.test.ts, which owns the schema it mutates.