mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
test(ui): collapse session key/display name fixtures
This commit is contained in:
@@ -13,82 +13,72 @@ function row(overrides: Partial<SessionRow> & { key: string }): SessionRow {
|
||||
* ================================================================ */
|
||||
|
||||
describe("parseSessionKey", () => {
|
||||
it("identifies main session (bare 'main')", () => {
|
||||
expect(parseSessionKey("main")).toEqual({ prefix: "", fallbackName: "Main Session" });
|
||||
});
|
||||
|
||||
it("identifies main session (agent:main:main)", () => {
|
||||
expect(parseSessionKey("agent:main:main")).toEqual({
|
||||
prefix: "",
|
||||
fallbackName: "Main Session",
|
||||
});
|
||||
});
|
||||
|
||||
it("identifies subagent sessions", () => {
|
||||
expect(parseSessionKey("agent:main:subagent:18abfefe-1fa6-43cb-8ba8-ebdc9b43e253")).toEqual({
|
||||
prefix: "Subagent:",
|
||||
fallbackName: "Subagent:",
|
||||
});
|
||||
});
|
||||
|
||||
it("identifies cron sessions", () => {
|
||||
expect(parseSessionKey("agent:main:cron:daily-briefing-uuid")).toEqual({
|
||||
prefix: "Cron:",
|
||||
fallbackName: "Cron Job:",
|
||||
});
|
||||
});
|
||||
|
||||
it("identifies direct chat with known channel", () => {
|
||||
expect(parseSessionKey("agent:main:bluebubbles:direct:+19257864429")).toEqual({
|
||||
prefix: "",
|
||||
fallbackName: "iMessage · +19257864429",
|
||||
});
|
||||
});
|
||||
|
||||
it("identifies direct chat with telegram", () => {
|
||||
expect(parseSessionKey("agent:main:telegram:direct:user123")).toEqual({
|
||||
prefix: "",
|
||||
fallbackName: "Telegram · user123",
|
||||
});
|
||||
});
|
||||
|
||||
it("identifies group chat with known channel", () => {
|
||||
expect(parseSessionKey("agent:main:discord:group:guild-chan")).toEqual({
|
||||
prefix: "",
|
||||
fallbackName: "Discord Group",
|
||||
});
|
||||
});
|
||||
|
||||
it("capitalises unknown channels in direct/group patterns", () => {
|
||||
expect(parseSessionKey("agent:main:mychannel:direct:user1")).toEqual({
|
||||
prefix: "",
|
||||
fallbackName: "Mychannel · user1",
|
||||
});
|
||||
});
|
||||
|
||||
it("identifies channel-prefixed legacy keys", () => {
|
||||
expect(parseSessionKey("bluebubbles:g-agent-main-bluebubbles-direct-+19257864429")).toEqual({
|
||||
prefix: "",
|
||||
fallbackName: "iMessage Session",
|
||||
});
|
||||
expect(parseSessionKey("discord:123:456")).toEqual({
|
||||
prefix: "",
|
||||
fallbackName: "Discord Session",
|
||||
});
|
||||
});
|
||||
|
||||
it("handles bare channel name as key", () => {
|
||||
expect(parseSessionKey("telegram")).toEqual({
|
||||
prefix: "",
|
||||
fallbackName: "Telegram Session",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns raw key for unknown patterns", () => {
|
||||
expect(parseSessionKey("something-unknown")).toEqual({
|
||||
prefix: "",
|
||||
fallbackName: "something-unknown",
|
||||
});
|
||||
it("maps session keys to expected prefixes and fallback names", () => {
|
||||
const cases = [
|
||||
{
|
||||
name: "bare main",
|
||||
key: "main",
|
||||
expected: { prefix: "", fallbackName: "Main Session" },
|
||||
},
|
||||
{
|
||||
name: "agent main key",
|
||||
key: "agent:main:main",
|
||||
expected: { prefix: "", fallbackName: "Main Session" },
|
||||
},
|
||||
{
|
||||
name: "subagent key",
|
||||
key: "agent:main:subagent:18abfefe-1fa6-43cb-8ba8-ebdc9b43e253",
|
||||
expected: { prefix: "Subagent:", fallbackName: "Subagent:" },
|
||||
},
|
||||
{
|
||||
name: "cron key",
|
||||
key: "agent:main:cron:daily-briefing-uuid",
|
||||
expected: { prefix: "Cron:", fallbackName: "Cron Job:" },
|
||||
},
|
||||
{
|
||||
name: "direct known channel",
|
||||
key: "agent:main:bluebubbles:direct:+19257864429",
|
||||
expected: { prefix: "", fallbackName: "iMessage · +19257864429" },
|
||||
},
|
||||
{
|
||||
name: "direct telegram",
|
||||
key: "agent:main:telegram:direct:user123",
|
||||
expected: { prefix: "", fallbackName: "Telegram · user123" },
|
||||
},
|
||||
{
|
||||
name: "group known channel",
|
||||
key: "agent:main:discord:group:guild-chan",
|
||||
expected: { prefix: "", fallbackName: "Discord Group" },
|
||||
},
|
||||
{
|
||||
name: "unknown channel direct",
|
||||
key: "agent:main:mychannel:direct:user1",
|
||||
expected: { prefix: "", fallbackName: "Mychannel · user1" },
|
||||
},
|
||||
{
|
||||
name: "legacy channel-prefixed key",
|
||||
key: "bluebubbles:g-agent-main-bluebubbles-direct-+19257864429",
|
||||
expected: { prefix: "", fallbackName: "iMessage Session" },
|
||||
},
|
||||
{
|
||||
name: "legacy discord key",
|
||||
key: "discord:123:456",
|
||||
expected: { prefix: "", fallbackName: "Discord Session" },
|
||||
},
|
||||
{
|
||||
name: "bare channel key",
|
||||
key: "telegram",
|
||||
expected: { prefix: "", fallbackName: "Telegram Session" },
|
||||
},
|
||||
{
|
||||
name: "unknown pattern",
|
||||
key: "something-unknown",
|
||||
expected: { prefix: "", fallbackName: "something-unknown" },
|
||||
},
|
||||
] as const;
|
||||
for (const testCase of cases) {
|
||||
expect(parseSessionKey(testCase.key), testCase.name).toEqual(testCase.expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -97,167 +87,130 @@ describe("parseSessionKey", () => {
|
||||
* ================================================================ */
|
||||
|
||||
describe("resolveSessionDisplayName", () => {
|
||||
// ── Key-only fallbacks (no row) ──────────────────
|
||||
|
||||
it("returns 'Main Session' for agent:main:main key", () => {
|
||||
expect(resolveSessionDisplayName("agent:main:main")).toBe("Main Session");
|
||||
it("resolves key-only fallbacks", () => {
|
||||
const cases = [
|
||||
{ key: "agent:main:main", expected: "Main Session" },
|
||||
{ key: "main", expected: "Main Session" },
|
||||
{ key: "agent:main:subagent:abc-123", expected: "Subagent:" },
|
||||
{ key: "agent:main:cron:abc-123", expected: "Cron Job:" },
|
||||
{ key: "agent:main:bluebubbles:direct:+19257864429", expected: "iMessage · +19257864429" },
|
||||
{ key: "discord:123:456", expected: "Discord Session" },
|
||||
{ key: "something-custom", expected: "something-custom" },
|
||||
] as const;
|
||||
for (const testCase of cases) {
|
||||
expect(resolveSessionDisplayName(testCase.key), testCase.key).toBe(testCase.expected);
|
||||
}
|
||||
});
|
||||
|
||||
it("returns 'Main Session' for bare 'main' key", () => {
|
||||
expect(resolveSessionDisplayName("main")).toBe("Main Session");
|
||||
});
|
||||
|
||||
it("returns 'Subagent:' for subagent key without row", () => {
|
||||
expect(resolveSessionDisplayName("agent:main:subagent:abc-123")).toBe("Subagent:");
|
||||
});
|
||||
|
||||
it("returns 'Cron Job:' for cron key without row", () => {
|
||||
expect(resolveSessionDisplayName("agent:main:cron:abc-123")).toBe("Cron Job:");
|
||||
});
|
||||
|
||||
it("parses direct chat key with channel", () => {
|
||||
expect(resolveSessionDisplayName("agent:main:bluebubbles:direct:+19257864429")).toBe(
|
||||
"iMessage · +19257864429",
|
||||
);
|
||||
});
|
||||
|
||||
it("parses channel-prefixed legacy key", () => {
|
||||
expect(resolveSessionDisplayName("discord:123:456")).toBe("Discord Session");
|
||||
});
|
||||
|
||||
it("returns raw key for unknown patterns", () => {
|
||||
expect(resolveSessionDisplayName("something-custom")).toBe("something-custom");
|
||||
});
|
||||
|
||||
// ── With row data (label / displayName) ──────────
|
||||
|
||||
it("returns parsed fallback when row has no label or displayName", () => {
|
||||
expect(resolveSessionDisplayName("agent:main:main", row({ key: "agent:main:main" }))).toBe(
|
||||
"Main Session",
|
||||
);
|
||||
});
|
||||
|
||||
it("returns parsed fallback when displayName matches key", () => {
|
||||
expect(resolveSessionDisplayName("mykey", row({ key: "mykey", displayName: "mykey" }))).toBe(
|
||||
"mykey",
|
||||
);
|
||||
});
|
||||
|
||||
it("returns parsed fallback when label matches key", () => {
|
||||
expect(resolveSessionDisplayName("mykey", row({ key: "mykey", label: "mykey" }))).toBe("mykey");
|
||||
});
|
||||
|
||||
it("uses label alone when available", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"discord:123:456",
|
||||
row({ key: "discord:123:456", label: "General" }),
|
||||
),
|
||||
).toBe("General");
|
||||
});
|
||||
|
||||
it("falls back to displayName when label is absent", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"discord:123:456",
|
||||
row({ key: "discord:123:456", displayName: "My Chat" }),
|
||||
),
|
||||
).toBe("My Chat");
|
||||
});
|
||||
|
||||
it("prefers label over displayName when both are present", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"discord:123:456",
|
||||
row({ key: "discord:123:456", displayName: "My Chat", label: "General" }),
|
||||
),
|
||||
).toBe("General");
|
||||
});
|
||||
|
||||
it("ignores whitespace-only label and falls back to displayName", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"discord:123:456",
|
||||
row({ key: "discord:123:456", displayName: "My Chat", label: " " }),
|
||||
),
|
||||
).toBe("My Chat");
|
||||
});
|
||||
|
||||
it("uses parsed fallback when whitespace-only label and no displayName", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName("discord:123:456", row({ key: "discord:123:456", label: " " })),
|
||||
).toBe("Discord Session");
|
||||
});
|
||||
|
||||
it("trims label and displayName", () => {
|
||||
expect(resolveSessionDisplayName("k", row({ key: "k", label: " General " }))).toBe("General");
|
||||
expect(resolveSessionDisplayName("k", row({ key: "k", displayName: " My Chat " }))).toBe(
|
||||
"My Chat",
|
||||
);
|
||||
});
|
||||
|
||||
// ── Type prefixes applied to labels / displayNames ──
|
||||
|
||||
it("prefixes subagent label with Subagent:", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"agent:main:subagent:abc-123",
|
||||
row({ key: "agent:main:subagent:abc-123", label: "maintainer-v2" }),
|
||||
),
|
||||
).toBe("Subagent: maintainer-v2");
|
||||
});
|
||||
|
||||
it("prefixes subagent displayName with Subagent:", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"agent:main:subagent:abc-123",
|
||||
row({ key: "agent:main:subagent:abc-123", displayName: "Task Runner" }),
|
||||
),
|
||||
).toBe("Subagent: Task Runner");
|
||||
});
|
||||
|
||||
it("prefixes cron label with Cron:", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"agent:main:cron:abc-123",
|
||||
row({ key: "agent:main:cron:abc-123", label: "daily-briefing" }),
|
||||
),
|
||||
).toBe("Cron: daily-briefing");
|
||||
});
|
||||
|
||||
it("prefixes cron displayName with Cron:", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"agent:main:cron:abc-123",
|
||||
row({ key: "agent:main:cron:abc-123", displayName: "Nightly Sync" }),
|
||||
),
|
||||
).toBe("Cron: Nightly Sync");
|
||||
});
|
||||
|
||||
it("does not double-prefix cron labels that already include Cron:", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"agent:main:cron:abc-123",
|
||||
row({ key: "agent:main:cron:abc-123", label: "Cron: Nightly Sync" }),
|
||||
),
|
||||
).toBe("Cron: Nightly Sync");
|
||||
});
|
||||
|
||||
it("does not double-prefix subagent display names that already include Subagent:", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"agent:main:subagent:abc-123",
|
||||
row({ key: "agent:main:subagent:abc-123", displayName: "Subagent: Runner" }),
|
||||
),
|
||||
).toBe("Subagent: Runner");
|
||||
});
|
||||
|
||||
it("does not prefix non-typed sessions with labels", () => {
|
||||
expect(
|
||||
resolveSessionDisplayName(
|
||||
"agent:main:bluebubbles:direct:+19257864429",
|
||||
row({ key: "agent:main:bluebubbles:direct:+19257864429", label: "Tyler" }),
|
||||
),
|
||||
).toBe("Tyler");
|
||||
it("resolves row labels/display names and typed prefixes", () => {
|
||||
const cases = [
|
||||
{
|
||||
name: "row with no label/display",
|
||||
key: "agent:main:main",
|
||||
rowData: row({ key: "agent:main:main" }),
|
||||
expected: "Main Session",
|
||||
},
|
||||
{
|
||||
name: "displayName equals key",
|
||||
key: "mykey",
|
||||
rowData: row({ key: "mykey", displayName: "mykey" }),
|
||||
expected: "mykey",
|
||||
},
|
||||
{
|
||||
name: "label equals key",
|
||||
key: "mykey",
|
||||
rowData: row({ key: "mykey", label: "mykey" }),
|
||||
expected: "mykey",
|
||||
},
|
||||
{
|
||||
name: "label used",
|
||||
key: "discord:123:456",
|
||||
rowData: row({ key: "discord:123:456", label: "General" }),
|
||||
expected: "General",
|
||||
},
|
||||
{
|
||||
name: "displayName fallback",
|
||||
key: "discord:123:456",
|
||||
rowData: row({ key: "discord:123:456", displayName: "My Chat" }),
|
||||
expected: "My Chat",
|
||||
},
|
||||
{
|
||||
name: "label preferred over displayName",
|
||||
key: "discord:123:456",
|
||||
rowData: row({ key: "discord:123:456", displayName: "My Chat", label: "General" }),
|
||||
expected: "General",
|
||||
},
|
||||
{
|
||||
name: "ignore whitespace label",
|
||||
key: "discord:123:456",
|
||||
rowData: row({ key: "discord:123:456", displayName: "My Chat", label: " " }),
|
||||
expected: "My Chat",
|
||||
},
|
||||
{
|
||||
name: "fallback when whitespace label and no displayName",
|
||||
key: "discord:123:456",
|
||||
rowData: row({ key: "discord:123:456", label: " " }),
|
||||
expected: "Discord Session",
|
||||
},
|
||||
{
|
||||
name: "trim label",
|
||||
key: "k",
|
||||
rowData: row({ key: "k", label: " General " }),
|
||||
expected: "General",
|
||||
},
|
||||
{
|
||||
name: "trim displayName",
|
||||
key: "k",
|
||||
rowData: row({ key: "k", displayName: " My Chat " }),
|
||||
expected: "My Chat",
|
||||
},
|
||||
{
|
||||
name: "prefix subagent label",
|
||||
key: "agent:main:subagent:abc-123",
|
||||
rowData: row({ key: "agent:main:subagent:abc-123", label: "maintainer-v2" }),
|
||||
expected: "Subagent: maintainer-v2",
|
||||
},
|
||||
{
|
||||
name: "prefix subagent displayName",
|
||||
key: "agent:main:subagent:abc-123",
|
||||
rowData: row({ key: "agent:main:subagent:abc-123", displayName: "Task Runner" }),
|
||||
expected: "Subagent: Task Runner",
|
||||
},
|
||||
{
|
||||
name: "prefix cron label",
|
||||
key: "agent:main:cron:abc-123",
|
||||
rowData: row({ key: "agent:main:cron:abc-123", label: "daily-briefing" }),
|
||||
expected: "Cron: daily-briefing",
|
||||
},
|
||||
{
|
||||
name: "prefix cron displayName",
|
||||
key: "agent:main:cron:abc-123",
|
||||
rowData: row({ key: "agent:main:cron:abc-123", displayName: "Nightly Sync" }),
|
||||
expected: "Cron: Nightly Sync",
|
||||
},
|
||||
{
|
||||
name: "avoid double cron prefix",
|
||||
key: "agent:main:cron:abc-123",
|
||||
rowData: row({ key: "agent:main:cron:abc-123", label: "Cron: Nightly Sync" }),
|
||||
expected: "Cron: Nightly Sync",
|
||||
},
|
||||
{
|
||||
name: "avoid double subagent prefix",
|
||||
key: "agent:main:subagent:abc-123",
|
||||
rowData: row({ key: "agent:main:subagent:abc-123", displayName: "Subagent: Runner" }),
|
||||
expected: "Subagent: Runner",
|
||||
},
|
||||
{
|
||||
name: "non-typed label without prefix",
|
||||
key: "agent:main:bluebubbles:direct:+19257864429",
|
||||
rowData: row({ key: "agent:main:bluebubbles:direct:+19257864429", label: "Tyler" }),
|
||||
expected: "Tyler",
|
||||
},
|
||||
] as const;
|
||||
for (const testCase of cases) {
|
||||
expect(resolveSessionDisplayName(testCase.key, testCase.rowData), testCase.name).toBe(
|
||||
testCase.expected,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user