mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-03 03:03:24 -04:00
refactor(test): dedupe trigger model command fixtures
This commit is contained in:
@@ -14,27 +14,42 @@ beforeAll(async () => {
|
||||
|
||||
installTriggerHandlingE2eTestHooks();
|
||||
|
||||
const DEFAULT_SESSION_KEY = "telegram:slash:111";
|
||||
|
||||
function makeTelegramModelCommand(body: string, sessionKey = DEFAULT_SESSION_KEY) {
|
||||
return {
|
||||
Body: body,
|
||||
From: "telegram:111",
|
||||
To: "telegram:111",
|
||||
ChatType: "direct" as const,
|
||||
Provider: "telegram" as const,
|
||||
Surface: "telegram" as const,
|
||||
SessionKey: sessionKey,
|
||||
CommandAuthorized: true,
|
||||
};
|
||||
}
|
||||
|
||||
function firstReplyText(reply: Awaited<ReturnType<typeof getReplyFromConfig>>) {
|
||||
return Array.isArray(reply) ? (reply[0]?.text ?? "") : (reply?.text ?? "");
|
||||
}
|
||||
|
||||
async function runModelCommand(home: string, body: string, sessionKey = DEFAULT_SESSION_KEY) {
|
||||
const cfg = makeCfg(home);
|
||||
const res = await getReplyFromConfig(makeTelegramModelCommand(body, sessionKey), {}, cfg);
|
||||
const text = firstReplyText(res);
|
||||
return {
|
||||
cfg,
|
||||
sessionKey,
|
||||
text,
|
||||
normalized: normalizeTestText(text),
|
||||
};
|
||||
}
|
||||
|
||||
describe("trigger handling", () => {
|
||||
it("shows a /model summary and points to /models", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const cfg = makeCfg(home);
|
||||
const res = await getReplyFromConfig(
|
||||
{
|
||||
Body: "/model",
|
||||
From: "telegram:111",
|
||||
To: "telegram:111",
|
||||
ChatType: "direct",
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
SessionKey: "telegram:slash:111",
|
||||
CommandAuthorized: true,
|
||||
},
|
||||
{},
|
||||
cfg,
|
||||
);
|
||||
const { normalized } = await runModelCommand(home, "/model");
|
||||
|
||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
const normalized = normalizeTestText(text ?? "");
|
||||
expect(normalized).toContain("Current: anthropic/claude-opus-4-5");
|
||||
expect(normalized).toContain("/model <provider/model> to switch");
|
||||
expect(normalized).toContain("Tap below to browse models");
|
||||
@@ -43,83 +58,36 @@ describe("trigger handling", () => {
|
||||
expect(normalized).not.toContain("image");
|
||||
});
|
||||
});
|
||||
|
||||
it("aliases /model list to /models", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const cfg = makeCfg(home);
|
||||
const res = await getReplyFromConfig(
|
||||
{
|
||||
Body: "/model list",
|
||||
From: "telegram:111",
|
||||
To: "telegram:111",
|
||||
ChatType: "direct",
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
SessionKey: "telegram:slash:111",
|
||||
CommandAuthorized: true,
|
||||
},
|
||||
{},
|
||||
cfg,
|
||||
);
|
||||
const { normalized } = await runModelCommand(home, "/model list");
|
||||
|
||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
const normalized = normalizeTestText(text ?? "");
|
||||
expect(normalized).toContain("Providers:");
|
||||
expect(normalized).toContain("Use: /models <provider>");
|
||||
expect(normalized).toContain("Switch: /model <provider/model>");
|
||||
});
|
||||
});
|
||||
|
||||
it("selects the exact provider/model pair for openrouter", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const cfg = makeCfg(home);
|
||||
const sessionKey = "telegram:slash:111";
|
||||
|
||||
const res = await getReplyFromConfig(
|
||||
{
|
||||
Body: "/model openrouter/anthropic/claude-opus-4-5",
|
||||
From: "telegram:111",
|
||||
To: "telegram:111",
|
||||
ChatType: "direct",
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
SessionKey: sessionKey,
|
||||
CommandAuthorized: true,
|
||||
},
|
||||
{},
|
||||
cfg,
|
||||
const { cfg, sessionKey, normalized } = await runModelCommand(
|
||||
home,
|
||||
"/model openrouter/anthropic/claude-opus-4-5",
|
||||
);
|
||||
|
||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
expect(normalizeTestText(text ?? "")).toContain(
|
||||
"Model set to openrouter/anthropic/claude-opus-4-5",
|
||||
);
|
||||
expect(normalized).toContain("Model set to openrouter/anthropic/claude-opus-4-5");
|
||||
|
||||
const store = loadSessionStore(cfg.session.store);
|
||||
expect(store[sessionKey]?.providerOverride).toBe("openrouter");
|
||||
expect(store[sessionKey]?.modelOverride).toBe("anthropic/claude-opus-4-5");
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects invalid /model <#> selections", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const cfg = makeCfg(home);
|
||||
const sessionKey = "telegram:slash:111";
|
||||
const { cfg, sessionKey, normalized } = await runModelCommand(home, "/model 99");
|
||||
|
||||
const res = await getReplyFromConfig(
|
||||
{
|
||||
Body: "/model 99",
|
||||
From: "telegram:111",
|
||||
To: "telegram:111",
|
||||
ChatType: "direct",
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
SessionKey: sessionKey,
|
||||
CommandAuthorized: true,
|
||||
},
|
||||
{},
|
||||
cfg,
|
||||
);
|
||||
|
||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
const normalized = normalizeTestText(text ?? "");
|
||||
expect(normalized).toContain("Numeric model selection is not supported in chat.");
|
||||
expect(normalized).toContain("Browse: /models or /models <provider>");
|
||||
expect(normalized).toContain("Switch: /model <provider/model>");
|
||||
@@ -129,59 +97,27 @@ describe("trigger handling", () => {
|
||||
expect(store[sessionKey]?.modelOverride).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("resets to the default model via /model <provider/model>", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const cfg = makeCfg(home);
|
||||
const sessionKey = "telegram:slash:111";
|
||||
|
||||
const res = await getReplyFromConfig(
|
||||
{
|
||||
Body: "/model anthropic/claude-opus-4-5",
|
||||
From: "telegram:111",
|
||||
To: "telegram:111",
|
||||
ChatType: "direct",
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
SessionKey: sessionKey,
|
||||
CommandAuthorized: true,
|
||||
},
|
||||
{},
|
||||
cfg,
|
||||
const { cfg, sessionKey, normalized } = await runModelCommand(
|
||||
home,
|
||||
"/model anthropic/claude-opus-4-5",
|
||||
);
|
||||
|
||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
expect(normalizeTestText(text ?? "")).toContain(
|
||||
"Model reset to default (anthropic/claude-opus-4-5)",
|
||||
);
|
||||
expect(normalized).toContain("Model reset to default (anthropic/claude-opus-4-5)");
|
||||
|
||||
const store = loadSessionStore(cfg.session.store);
|
||||
// When selecting the default, overrides are cleared
|
||||
expect(store[sessionKey]?.providerOverride).toBeUndefined();
|
||||
expect(store[sessionKey]?.modelOverride).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("selects a model via /model <provider/model>", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const cfg = makeCfg(home);
|
||||
const sessionKey = "telegram:slash:111";
|
||||
const { cfg, sessionKey, normalized } = await runModelCommand(home, "/model openai/gpt-5.2");
|
||||
|
||||
const res = await getReplyFromConfig(
|
||||
{
|
||||
Body: "/model openai/gpt-5.2",
|
||||
From: "telegram:111",
|
||||
To: "telegram:111",
|
||||
ChatType: "direct",
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
SessionKey: sessionKey,
|
||||
CommandAuthorized: true,
|
||||
},
|
||||
{},
|
||||
cfg,
|
||||
);
|
||||
|
||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
expect(normalizeTestText(text ?? "")).toContain("Model set to openai/gpt-5.2");
|
||||
expect(normalized).toContain("Model set to openai/gpt-5.2");
|
||||
|
||||
const store = loadSessionStore(cfg.session.store);
|
||||
expect(store[sessionKey]?.providerOverride).toBe("openai");
|
||||
|
||||
Reference in New Issue
Block a user