refactor: centralize ack reaction gating
This commit is contained in:
134
src/channels/ack-reactions.test.ts
Normal file
134
src/channels/ack-reactions.test.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { shouldAckReaction } from "./ack-reactions.js";
|
||||
|
||||
describe("shouldAckReaction", () => {
|
||||
it("honors direct and group-all scopes", () => {
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: "direct",
|
||||
isDirect: true,
|
||||
isGroup: false,
|
||||
isMentionableGroup: false,
|
||||
requireMention: false,
|
||||
canDetectMention: false,
|
||||
effectiveWasMentioned: false,
|
||||
}),
|
||||
).toBe(true);
|
||||
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: "group-all",
|
||||
isDirect: false,
|
||||
isGroup: true,
|
||||
isMentionableGroup: true,
|
||||
requireMention: false,
|
||||
canDetectMention: false,
|
||||
effectiveWasMentioned: false,
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("skips when scope is off or none", () => {
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: "off",
|
||||
isDirect: true,
|
||||
isGroup: true,
|
||||
isMentionableGroup: true,
|
||||
requireMention: true,
|
||||
canDetectMention: true,
|
||||
effectiveWasMentioned: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: "none",
|
||||
isDirect: true,
|
||||
isGroup: true,
|
||||
isMentionableGroup: true,
|
||||
requireMention: true,
|
||||
canDetectMention: true,
|
||||
effectiveWasMentioned: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("defaults to group-mentions gating", () => {
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: undefined,
|
||||
isDirect: false,
|
||||
isGroup: true,
|
||||
isMentionableGroup: true,
|
||||
requireMention: true,
|
||||
canDetectMention: true,
|
||||
effectiveWasMentioned: true,
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("requires mention gating for group-mentions", () => {
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: "group-mentions",
|
||||
isDirect: false,
|
||||
isGroup: true,
|
||||
isMentionableGroup: true,
|
||||
requireMention: false,
|
||||
canDetectMention: true,
|
||||
effectiveWasMentioned: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: "group-mentions",
|
||||
isDirect: false,
|
||||
isGroup: true,
|
||||
isMentionableGroup: true,
|
||||
requireMention: true,
|
||||
canDetectMention: false,
|
||||
effectiveWasMentioned: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: "group-mentions",
|
||||
isDirect: false,
|
||||
isGroup: true,
|
||||
isMentionableGroup: false,
|
||||
requireMention: true,
|
||||
canDetectMention: true,
|
||||
effectiveWasMentioned: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: "group-mentions",
|
||||
isDirect: false,
|
||||
isGroup: true,
|
||||
isMentionableGroup: true,
|
||||
requireMention: true,
|
||||
canDetectMention: true,
|
||||
effectiveWasMentioned: true,
|
||||
}),
|
||||
).toBe(true);
|
||||
|
||||
expect(
|
||||
shouldAckReaction({
|
||||
scope: "group-mentions",
|
||||
isDirect: false,
|
||||
isGroup: true,
|
||||
isMentionableGroup: true,
|
||||
requireMention: true,
|
||||
canDetectMention: true,
|
||||
effectiveWasMentioned: false,
|
||||
shouldBypassMention: true,
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
27
src/channels/ack-reactions.ts
Normal file
27
src/channels/ack-reactions.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export type AckReactionScope = "all" | "direct" | "group-all" | "group-mentions" | "off" | "none";
|
||||
|
||||
export type AckReactionGateParams = {
|
||||
scope: AckReactionScope | undefined;
|
||||
isDirect: boolean;
|
||||
isGroup: boolean;
|
||||
isMentionableGroup: boolean;
|
||||
requireMention: boolean;
|
||||
canDetectMention: boolean;
|
||||
effectiveWasMentioned: boolean;
|
||||
shouldBypassMention?: boolean;
|
||||
};
|
||||
|
||||
export function shouldAckReaction(params: AckReactionGateParams): boolean {
|
||||
const scope = params.scope ?? "group-mentions";
|
||||
if (scope === "off" || scope === "none") return false;
|
||||
if (scope === "all") return true;
|
||||
if (scope === "direct") return params.isDirect;
|
||||
if (scope === "group-all") return params.isGroup;
|
||||
if (scope === "group-mentions") {
|
||||
if (!params.isMentionableGroup) return false;
|
||||
if (!params.requireMention) return false;
|
||||
if (!params.canDetectMention) return false;
|
||||
return params.effectiveWasMentioned || params.shouldBypassMention === true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user