























@@ -560,6 +560,76 @@ describe("DiscordVoiceManager", () => {
560560expectConnectedStatus(manager, "1002");
561561});
562562563+it("rejects joins outside configured allowed voice channels", async () => {
564+const manager = createManager({
565+voice: {
566+enabled: true,
567+mode: "stt-tts",
568+allowedChannels: [{ guildId: "g1", channelId: "1001" }],
569+},
570+});
571+572+const result = await manager.join({ guildId: "g1", channelId: "1002" });
573+574+expect(result.ok).toBe(false);
575+expect(result.message).toBe(
576+"<#1002> is not allowed by channels.discord.voice.allowedChannels.",
577+);
578+expect(joinVoiceChannelMock).not.toHaveBeenCalled();
579+});
580+581+it("allows joins inside configured allowed voice channels", async () => {
582+const manager = createManager({
583+voice: {
584+enabled: true,
585+mode: "stt-tts",
586+allowedChannels: [{ guildId: "g1", channelId: "1001" }],
587+},
588+});
589+590+const result = await manager.join({ guildId: "g1", channelId: "1001" });
591+592+expect(result.ok).toBe(true);
593+expectConnectedStatus(manager, "1001");
594+});
595+596+it("treats an empty allowed voice channel list as deny-all", async () => {
597+const manager = createManager({
598+voice: {
599+enabled: true,
600+mode: "stt-tts",
601+allowedChannels: [],
602+},
603+});
604+605+const result = await manager.join({ guildId: "g1", channelId: "1001" });
606+607+expect(result.ok).toBe(false);
608+expect(joinVoiceChannelMock).not.toHaveBeenCalled();
609+});
610+611+it("leaves and rejoins the configured target when Discord moves the bot outside allowed voice channels", async () => {
612+const manager = createManager({
613+voice: {
614+enabled: true,
615+mode: "stt-tts",
616+autoJoin: [{ guildId: "g1", channelId: "1001" }],
617+allowedChannels: [{ guildId: "g1", channelId: "1001" }],
618+},
619+});
620+manager.setBotUserId("bot-user");
621+await manager.join({ guildId: "g1", channelId: "1001" });
622+623+await manager.handleVoiceStateUpdate({
624+guild_id: "g1",
625+user_id: "bot-user",
626+channel_id: "1002",
627+} as never);
628+629+expect(joinVoiceChannelMock).toHaveBeenCalledTimes(2);
630+expectConnectedStatus(manager, "1001");
631+});
632+563633it("skips destroying stale tracked voice connections that are already destroyed", async () => {
564634const staleConnection = createConnectionMock();
565635staleConnection.state.status = "destroyed";
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。