refactor: cut cyclomatic complexity of five hot spots and pin their behavior with tests
Risk labels, menu callback parsing, settings callbacks, table cell width and markdown link targets now use tables and small helpers (CC <= 10).
This commit is contained in:
1 parent
bf4a2021e8
commit
6a6e75fe32
8 files changed
+648
-294
No files matched your search
@@ -261,3 +261,109 @@ test("Settings runtime opens menus and applies stale-message fallback toggles",
|
||||
"answer:Time injection: hidden",
|
||||
]);
|
||||
});
|
||||
|
||||
function createSettingsCallbackHarness() {
|
||||
const calls: string[] = [];
|
||||
const deps = {
|
||||
isProactivePushEnabled: () => false,
|
||||
getVoiceReplyMode: () => "manual" as const,
|
||||
isVoiceReplyModeConfigured: () => true,
|
||||
getTimeInjectionMode: () => "hidden" as const,
|
||||
areDraftPreviewsEnabled: () => false,
|
||||
getAssistantRenderingMode: () => "rich" as const,
|
||||
setProactivePushEnabled: async (enabled: boolean) => {
|
||||
calls.push(`proactive:${enabled}`);
|
||||
},
|
||||
setDraftPreviewsEnabled: async (enabled: boolean) => {
|
||||
calls.push(`draft-previews:${enabled}`);
|
||||
},
|
||||
setAssistantRenderingMode: async (mode: "rich" | "html") => {
|
||||
calls.push(`rendering:${mode}`);
|
||||
},
|
||||
setVoiceReplyMode: async (
|
||||
mode: "manual" | "mirror" | "always" | undefined,
|
||||
) => {
|
||||
calls.push(`voice:${mode ?? "hidden"}`);
|
||||
},
|
||||
setTimeInjectionMode: async (mode: "hidden" | "always" | "interval") => {
|
||||
calls.push(`time:${mode}`);
|
||||
},
|
||||
updateSettingsMessage: async (text: string) => {
|
||||
calls.push(`update:${text.split("\n")[0]}`);
|
||||
},
|
||||
answerCallbackQuery: async (_id: string, text?: string) => {
|
||||
calls.push(`answer:${text ?? ""}`);
|
||||
},
|
||||
};
|
||||
return { calls, deps };
|
||||
}
|
||||
|
||||
test("Settings callback action opens each page, including legacy aliases", async () => {
|
||||
const pages: Array<[string, string]> = [
|
||||
["settings:list", "update:<b>⚙️ Settings:</b>"],
|
||||
["settings:open:proactive", "update:<b>📌 Proactive push:</b> <code>off</code>"],
|
||||
["settings:open:draft-previews", "update:<b>📝 Draft previews:</b> <code>off</code>"],
|
||||
["settings:open:rich-drafts", "update:<b>📝 Draft previews:</b> <code>off</code>"],
|
||||
["settings:open:assistant-rendering", "update:<b>🧾 Assistant rendering:</b> <code>rich</code>"],
|
||||
["settings:open:voice-reply", "update:<b>👄 Voice reply mode:</b> <code>manual</code>"],
|
||||
["settings:open:time-injection", "update:<b>🕒 Time injection mode:</b> <code>hidden</code>"],
|
||||
["settings:open:time", "update:<b>🕒 Time injection mode:</b> <code>hidden</code>"],
|
||||
];
|
||||
for (const [data, update] of pages) {
|
||||
const { calls, deps } = createSettingsCallbackHarness();
|
||||
assert.equal(
|
||||
await handleTelegramSettingsMenuCallbackAction("q", data, deps),
|
||||
true,
|
||||
data,
|
||||
);
|
||||
assert.deepEqual(calls, [update, "answer:"], data);
|
||||
}
|
||||
});
|
||||
|
||||
test("Settings callback action applies each mode and the inverse branch of each toggle", async () => {
|
||||
const cases: Array<[string, string[]]> = [
|
||||
["settings:set:voice-reply:mirror", ["voice:mirror", "update:<b>👄 Voice reply mode:</b> <code>manual</code>", "answer:Voice reply mode: mirror"]],
|
||||
["settings:set:voice-reply:always", ["voice:always", "update:<b>👄 Voice reply mode:</b> <code>manual</code>", "answer:Voice reply mode: always"]],
|
||||
["settings:set:time-injection:interval", ["time:interval", "update:<b>🕒 Time injection mode:</b> <code>hidden</code>", "answer:Time injection: interval"]],
|
||||
["settings:set:time-injection:off", ["time:hidden", "update:<b>🕒 Time injection mode:</b> <code>hidden</code>", "answer:Time injection: hidden"]],
|
||||
["settings:set:time:always", ["time:always", "update:<b>🕒 Time injection mode:</b> <code>hidden</code>", "answer:Time injection: always"]],
|
||||
["settings:set:draft-previews:off", ["draft-previews:false", "update:<b>📝 Draft previews:</b> <code>off</code>", "answer:Draft previews disabled"]],
|
||||
["settings:set:rich-drafts:on", ["draft-previews:true", "update:<b>📝 Draft previews:</b> <code>off</code>", "answer:Draft previews enabled"]],
|
||||
["settings:set:assistant-rendering:rich", ["rendering:rich", "update:<b>🧾 Assistant rendering:</b> <code>rich</code>", "answer:Rendering: rich"]],
|
||||
["settings:set:proactive:off", ["proactive:false", "update:<b>📌 Proactive push:</b> <code>off</code>", "answer:Proactive push disabled"]],
|
||||
];
|
||||
for (const [data, expected] of cases) {
|
||||
const { calls, deps } = createSettingsCallbackHarness();
|
||||
assert.equal(
|
||||
await handleTelegramSettingsMenuCallbackAction("q", data, deps),
|
||||
true,
|
||||
data,
|
||||
);
|
||||
assert.deepEqual(calls, expected, data);
|
||||
}
|
||||
});
|
||||
|
||||
test("Settings callback action only acknowledges invalid or unknown settings values", async () => {
|
||||
for (const data of [
|
||||
"settings:set:voice-reply:bogus",
|
||||
"settings:set:time:bogus",
|
||||
"settings:set:assistant-rendering:bogus",
|
||||
"settings:set:draft-previews:maybe",
|
||||
"settings:set:proactive:maybe",
|
||||
"settings:unknown",
|
||||
]) {
|
||||
const { calls, deps } = createSettingsCallbackHarness();
|
||||
assert.equal(
|
||||
await handleTelegramSettingsMenuCallbackAction("q", data, deps),
|
||||
true,
|
||||
data,
|
||||
);
|
||||
assert.deepEqual(calls, ["answer:"], data);
|
||||
}
|
||||
const { calls, deps } = createSettingsCallbackHarness();
|
||||
assert.equal(
|
||||
await handleTelegramSettingsMenuCallbackAction("q", undefined, deps),
|
||||
false,
|
||||
);
|
||||
assert.deepEqual(calls, []);
|
||||
});
|
||||
Reference in new issue
Block a user