diff --git a/src/features/core/internal/Voice/internal/Voice.class.spec.ts b/src/features/core/internal/Voice/internal/Voice.class.spec.ts index e8e06751..42d89403 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.spec.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.spec.ts @@ -230,7 +230,7 @@ describe('Voice', () => { .mockReturnValueOnce('unknown' as any); await expect(voice.join({ interaction })).rejects.toThrowError( - 'Unknown joinable type.' + 'unknown is unexpected value. Should have been never.' ); }); }); diff --git a/src/features/core/internal/Voice/internal/Voice.class.ts b/src/features/core/internal/Voice/internal/Voice.class.ts index 49710b4e..b9f902ea 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.ts @@ -111,11 +111,9 @@ export class Voice { default: assertNever(joinable); - // HACK: ここでrejectするとSwitch外のカバレッジがuncoveredになる - break; } - - return Promise.reject(new LogicException('Unknown joinable type.')); + /* c8 ignore next */ + return; } public async leave({ diff --git a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts index 84ffb332..491add4a 100644 --- a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts @@ -10,29 +10,28 @@ export const getJoinableStateStatus = ({ }: { channel: VoiceBasedChannel | null; }): (typeof JOINABLE_STATE_STATUS)[keyof typeof JOINABLE_STATE_STATUS] => { - // getVoiceConnectionやgetVoiceConnectionsを利用せずに、自身がjoinしているかどうかを判定する - const client = channel?.client; - const guildId = channel?.guildId; - if (!client || !guildId) { - return JOINABLE_STATE_STATUS.NOT_FOUND; - } - - const voiceState = (() => { - const guild = client.guilds.cache.get(guildId); - if (!guild) return undefined; - const voiceState = guild.voiceStates.cache.get(client.user.id); - return voiceState; - })(); - if (isNil(channel)) { return JOINABLE_STATE_STATUS.NOT_FOUND; - } else if (!channel.joinable) { - return JOINABLE_STATE_STATUS.NOT_JOINABLE; - } else if (!channel.viewable) { - return JOINABLE_STATE_STATUS.NOT_VIEWABLE; - } else if (!isNil(voiceState)) { - return JOINABLE_STATE_STATUS.ALREADY_JOINED; } else { - return JOINABLE_STATE_STATUS.JOINABLE; + // getVoiceConnectionやgetVoiceConnectionsを利用せずに、自身がjoinしているかどうかを判定する + const client = channel.client; + const guildId = channel.guildId; + + const voiceState = (() => { + const guild = client.guilds.cache.get(guildId); + if (!guild) return undefined; + const voiceState = guild.voiceStates.cache.get(client.user.id); + return voiceState; + })(); + + if (!channel.joinable) { + return JOINABLE_STATE_STATUS.NOT_JOINABLE; + } else if (!channel.viewable) { + return JOINABLE_STATE_STATUS.NOT_VIEWABLE; + } else if (!!voiceState) { + return JOINABLE_STATE_STATUS.ALREADY_JOINED; + } else { + return JOINABLE_STATE_STATUS.JOINABLE; + } } }; diff --git a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts index e477231f..5b903fb5 100644 --- a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts @@ -1,17 +1,22 @@ import type { VoiceBasedChannel } from '@/features/library/index.js'; import { getJoinableStateStatus } from './getJoinableStateStatus.func.js'; +import { JOINABLE_STATE_STATUS } from './getJoinableStateStatus.constants.js'; describe('getJoinableStateStatus', () => { it('should return NOT_FOUND if the channel is null', () => { const result = getJoinableStateStatus({ channel: null }); - expect(result).toBe('NOT_FOUND'); + expect(result).toBe(JOINABLE_STATE_STATUS.NOT_FOUND); }); it('should return NOT_JOINABLE if the channel is not joinable', () => { const result = getJoinableStateStatus({ - channel: { joinable: false } as VoiceBasedChannel, + channel: { + joinable: false, + client: { guilds: { cache: new Map() } }, + guildId: 'guildId', + } as VoiceBasedChannel, }); expect(result).toBe('NOT_JOINABLE'); @@ -19,7 +24,12 @@ describe('getJoinableStateStatus', () => { it('should return NOT_VIEWABLE if the channel is not viewable', () => { const result = getJoinableStateStatus({ - channel: { joinable: true, viewable: false } as VoiceBasedChannel, + channel: { + joinable: true, + viewable: false, + client: { guilds: { cache: new Map() } }, + guildId: 'guildId', + } as VoiceBasedChannel, }); expect(result).toBe('NOT_VIEWABLE'); @@ -27,9 +37,43 @@ describe('getJoinableStateStatus', () => { it('should return JOINABLE if the channel is joinable and viewable', () => { const result = getJoinableStateStatus({ - channel: { joinable: true, viewable: true } as VoiceBasedChannel, + channel: { + joinable: true, + viewable: true, + client: { guilds: { cache: new Map() } }, + guildId: 'guildId', + } as VoiceBasedChannel, }); - expect(result).toBe('JOINABLE'); + expect(result).toBe(JOINABLE_STATE_STATUS.JOINABLE); + }); + + it('should return undefined if the voice state is not found', () => { + const result = getJoinableStateStatus({ + channel: { + joinable: true, + viewable: true, + client: { + user: { id: 'userId' }, + guilds: { + cache: new Map([ + [ + 'guildId', + { + voiceStates: { + cache: new Map([ + ['userId', { voiceStates: { cache: new Map() } }], + ]), + }, + }, + ], + ]), + }, + }, + guildId: 'guildId', + } as unknown as VoiceBasedChannel, + }); + + expect(result).toBe(JOINABLE_STATE_STATUS.ALREADY_JOINED); }); });