mirror of
https://github.com/stablyai/agent-slack.git
synced 2026-09-19 01:06:54 +08:00
94ecafe496
Merged replacement for #93 after maintainer pushes to the contributor fork were rejected with 403. Included fixes from review: - Keep inline-only edits text-only. - Preserve channel/usergroup/broadcast tokens in rich-text conversion. - Preserve http(s) and mailto manual links. - Keep non-URL angle-bracket tokens literal. - Sync README and bundled agent-slack skill docs. Validation: - bun test - bun run typecheck - bun run format:check - bun run lint - CI Build, Lint, Test passed - Independent xhigh Codex review: no blocking findings
65 lines
2.5 KiB
TypeScript
65 lines
2.5 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { formatOutboundSlackText } from "../src/slack/format-outbound.ts";
|
|
|
|
describe("formatOutboundSlackText", () => {
|
|
test("promotes bare user IDs to Slack mention tokens", () => {
|
|
expect(formatOutboundSlackText("@U05BRPTKL6A heads up")).toBe("<@U05BRPTKL6A> heads up");
|
|
expect(formatOutboundSlackText("cc @W123456A and @BABCDEFG")).toBe(
|
|
"cc <@W123456A> and <@BABCDEFG>",
|
|
);
|
|
});
|
|
|
|
test("leaves already-formatted mention tokens alone", () => {
|
|
expect(formatOutboundSlackText("hi <@U123456A>!")).toBe("hi <@U123456A>!");
|
|
expect(formatOutboundSlackText("hi <@U123456A|nick>!")).toBe("hi <@U123456A|nick>!");
|
|
});
|
|
|
|
test("leaves already-formatted usergroup mention tokens alone", () => {
|
|
expect(formatOutboundSlackText("ping <!subteam^S12345678|@team>")).toBe(
|
|
"ping <!subteam^S12345678|@team>",
|
|
);
|
|
expect(formatOutboundSlackText("ping <!subteam^S12345678>")).toBe("ping <!subteam^S12345678>");
|
|
});
|
|
|
|
test("promotes broadcast mentions", () => {
|
|
expect(formatOutboundSlackText("@here ping")).toBe("<!here> ping");
|
|
expect(formatOutboundSlackText("cc @channel and @everyone")).toBe(
|
|
"cc <!channel> and <!everyone>",
|
|
);
|
|
});
|
|
|
|
test("escapes bare < > & in literal text", () => {
|
|
expect(formatOutboundSlackText("a < b && c > d")).toBe("a < b && c > d");
|
|
});
|
|
|
|
test("does not escape inside already-formatted Slack tokens", () => {
|
|
expect(formatOutboundSlackText("see <https://example.com|link>")).toBe(
|
|
"see <https://example.com|link>",
|
|
);
|
|
expect(formatOutboundSlackText("mail <mailto:bob@example.com|Bob>")).toBe(
|
|
"mail <mailto:bob@example.com|Bob>",
|
|
);
|
|
expect(formatOutboundSlackText("see <https://a.test/?x=1&y=2>")).toBe(
|
|
"see <https://a.test/?x=1&y=2>",
|
|
);
|
|
});
|
|
|
|
test("does not promote email-like or mid-word @", () => {
|
|
expect(formatOutboundSlackText("mail me at user@Udomain.com")).toBe(
|
|
"mail me at user@Udomain.com",
|
|
);
|
|
});
|
|
|
|
test("handles empty input", () => {
|
|
expect(formatOutboundSlackText("")).toBe("");
|
|
});
|
|
|
|
test("real-world CI dump stays readable with mention + URL", () => {
|
|
const input =
|
|
'@U05BRPTKL6A heads up: CI "Install dependencies" is failing: https://github.com/x/y/actions/runs/1 & it needs <fix>';
|
|
expect(formatOutboundSlackText(input)).toBe(
|
|
'<@U05BRPTKL6A> heads up: CI "Install dependencies" is failing: https://github.com/x/y/actions/runs/1 & it needs <fix>',
|
|
);
|
|
});
|
|
});
|