diff --git a/src/features/core/index.ts b/src/features/core/index.ts index 9a28d105..2b3fae95 100644 --- a/src/features/core/index.ts +++ b/src/features/core/index.ts @@ -1,2 +1,6 @@ export { Client } from './internal/Client/index.js'; -export { Voice } from './internal/Voice/index.js'; +export { + Voice, + getJoinableStateStatus, + JOINABLE_STATE_STATUS, +} from './internal/Voice/index.js'; diff --git a/src/features/core/internal/Voice/index.ts b/src/features/core/internal/Voice/index.ts index 961677d0..b73bac49 100644 --- a/src/features/core/internal/Voice/index.ts +++ b/src/features/core/internal/Voice/index.ts @@ -1 +1,5 @@ export { Voice } from './internal/Voice.class.js'; +export { + getJoinableStateStatus, + JOINABLE_STATE_STATUS, +} from './internal/funcs/getJoinableStateStatus/index.js'; 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 ad5c603e..c75278e2 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.spec.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.spec.ts @@ -14,9 +14,9 @@ import { getInteractionMemberId } from '@/features/others/discord/index.js'; import { Voice } from './Voice.class.js'; import { - JOINABLE_TYPE_MAP, - checkJoinable, -} from './funcs/checkJoinable/index.js'; + JOINABLE_STATE_STATUS, + getJoinableStateStatus, +} from './funcs/getJoinableStateStatus/index.js'; vi.mock('@/features/others/discord/index.js', async () => { const actual = (await vi.importActual( @@ -39,13 +39,13 @@ vi.mock('@/features/library/index.js', async () => { }; }); -vi.mock('./funcs/checkJoinable/index.js', async () => { +vi.mock('./funcs/getJoinableStateStatus/index.js', async () => { const actual = (await vi.importActual( - './funcs/checkJoinable/index.js' + './funcs/getJoinableStateStatus/index.js' )) as object; return { ...actual, - checkJoinable: vi.fn(), + getJoinableStateStatus: vi.fn(), }; }); @@ -69,11 +69,13 @@ describe('Voice', () => { (getInteractionMemberId as Mock).mockResolvedValueOnce({ voice: { channel: null }, }); - (checkJoinable as Mock).mockReturnValueOnce(JOINABLE_TYPE_MAP.NOT_FOUND); + (getJoinableStateStatus as Mock).mockReturnValueOnce( + JOINABLE_STATE_STATUS.NOT_FOUND + ); await voice.join({ interaction: mockedInteraction }); - expect(checkJoinable).toHaveBeenCalledWith({ channel: null }); + expect(getJoinableStateStatus).toHaveBeenCalledWith({ channel: null }); expect(mockedInteraction.reply).toHaveBeenCalledWith({ content: '接続先のVCが見つかりません。', ephemeral: false, @@ -88,13 +90,13 @@ describe('Voice', () => { (getInteractionMemberId as Mock).mockResolvedValueOnce({ voice: { channel: { joinable: true } }, }); - (checkJoinable as Mock).mockReturnValueOnce( - JOINABLE_TYPE_MAP.NOT_JOINABLE + (getJoinableStateStatus as Mock).mockReturnValueOnce( + JOINABLE_STATE_STATUS.NOT_JOINABLE ); await voice.join({ interaction: mockedInteraction }); - expect(checkJoinable).toHaveBeenCalledWith({ + expect(getJoinableStateStatus).toHaveBeenCalledWith({ channel: { joinable: true }, }); expect(mockedInteraction.reply).toHaveBeenCalledWith({ @@ -111,13 +113,13 @@ describe('Voice', () => { (getInteractionMemberId as Mock).mockResolvedValueOnce({ voice: { channel: { joinable: true, viewable: false } }, }); - (checkJoinable as Mock).mockReturnValueOnce( - JOINABLE_TYPE_MAP.NOT_VIEWABLE + (getJoinableStateStatus as Mock).mockReturnValueOnce( + JOINABLE_STATE_STATUS.NOT_VIEWABLE ); await voice.join({ interaction: mockedInteraction }); - expect(checkJoinable).toHaveBeenCalledWith({ + expect(getJoinableStateStatus).toHaveBeenCalledWith({ channel: { joinable: true, viewable: false }, }); expect(mockedInteraction.reply).toHaveBeenCalledWith({ @@ -132,11 +134,13 @@ describe('Voice', () => { } as unknown as Readonly; (getInteractionMemberId as Mock).mockRejectedValueOnce( - new LogicException('Channel is null. Please check checkJoinable()') + new LogicException( + 'Channel is null. Please check getJoinableStateStatus()' + ) ); await expect(voice.join({ interaction })).rejects.toThrowError( - 'Channel is null. Please check checkJoinable()' + 'Channel is null. Please check getJoinableStateStatus()' ); }); @@ -148,11 +152,15 @@ describe('Voice', () => { (getInteractionMemberId as Mock).mockResolvedValueOnce({ voice: { channel: null }, }); - (checkJoinable as Mock).mockReturnValueOnce(JOINABLE_TYPE_MAP.JOINABLE); + (getJoinableStateStatus as Mock).mockReturnValueOnce( + JOINABLE_STATE_STATUS.JOINABLE + ); await expect( voice.join({ interaction: mockedInteraction }) - ).rejects.toThrowError('Channel is null. Please check checkJoinable()'); + ).rejects.toThrowError( + 'Channel is null. Please check getJoinableStateStatus()' + ); }); it('should join the voice channel and return true', async () => { @@ -176,11 +184,15 @@ describe('Voice', () => { (getInteractionMemberId as Mock).mockResolvedValueOnce(mockedGuildMember); (joinVoiceChannel as Mock).mockReturnValueOnce('connection'); - (checkJoinable as Mock).mockReturnValueOnce(JOINABLE_TYPE_MAP.JOINABLE); + (getJoinableStateStatus as Mock).mockReturnValueOnce( + JOINABLE_STATE_STATUS.JOINABLE + ); const result = await voice.join({ interaction: mockedInteraction }); - expect(checkJoinable).toHaveBeenCalledWith(mockedGuildMember.voice); + expect(getJoinableStateStatus).toHaveBeenCalledWith( + mockedGuildMember.voice + ); expect(joinVoiceChannel).toHaveBeenCalledWith({ channelId: 'channelId', guildId: 'guildId', @@ -202,7 +214,7 @@ describe('Voice', () => { voice: { channel: null }, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any - (checkJoinable as Mock).mockReturnValueOnce('unknown' as any); + (getJoinableStateStatus as Mock).mockReturnValueOnce('unknown' as any); await expect(voice.join({ interaction })).rejects.toThrowError( 'Unknown joinable type.' diff --git a/src/features/core/internal/Voice/internal/Voice.class.ts b/src/features/core/internal/Voice/internal/Voice.class.ts index 71bea814..ed1014d1 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.ts @@ -11,9 +11,9 @@ import { LogicException } from '@/features/others/Error/LogicException.js'; import { getInteractionMemberId } from '@/features/others/discord/index.js'; import { - JOINABLE_TYPE_MAP, - checkJoinable, -} from './funcs/checkJoinable/index.js'; + JOINABLE_STATE_STATUS, + getJoinableStateStatus, +} from './funcs/getJoinableStateStatus/index.js'; export class Voice { connection: Array<{ @@ -29,36 +29,36 @@ export class Voice { const { voice: { channel }, } = await getInteractionMemberId(interaction); - const joinable = checkJoinable({ + const joinable = getJoinableStateStatus({ channel, }); switch (joinable) { - case JOINABLE_TYPE_MAP.NOT_FOUND: + case JOINABLE_STATE_STATUS.NOT_FOUND: interaction.reply({ content: '接続先のVCが見つかりません。', ephemeral: false, }); return false; - case JOINABLE_TYPE_MAP.NOT_JOINABLE: + case JOINABLE_STATE_STATUS.NOT_JOINABLE: interaction.reply({ content: '接続先のVCに参加できません。権限の見直しをしてください。', ephemeral: true, }); return false; - case JOINABLE_TYPE_MAP.NOT_VIEWABLE: + case JOINABLE_STATE_STATUS.NOT_VIEWABLE: interaction.reply({ content: '接続先のVCに参加できません。権限の見直しをしてください。', ephemeral: true, }); return false; - case JOINABLE_TYPE_MAP.JOINABLE: + case JOINABLE_STATE_STATUS.JOINABLE: if (isNil(channel)) throw new LogicException( - 'Channel is null. Please check checkJoinable()' + 'Channel is null. Please check getJoinableStateStatus()' ); const connection = joinVoiceChannel({ channelId: channel.id, diff --git a/src/features/core/internal/Voice/internal/funcs/checkJoinable/index.ts b/src/features/core/internal/Voice/internal/funcs/checkJoinable/index.ts deleted file mode 100644 index f5342245..00000000 --- a/src/features/core/internal/Voice/internal/funcs/checkJoinable/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { checkJoinable } from './internal/checkJoinable.func.js'; -export { JOINABLE_TYPE_MAP } from './internal/checkJoinable.constants.js'; diff --git a/src/features/core/internal/Voice/internal/funcs/checkJoinable/internal/checkJoinable.func.ts b/src/features/core/internal/Voice/internal/funcs/checkJoinable/internal/checkJoinable.func.ts deleted file mode 100644 index 0ddd2b01..00000000 --- a/src/features/core/internal/Voice/internal/funcs/checkJoinable/internal/checkJoinable.func.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { isNil, type VoiceBasedChannel } from '@/features/library/index.js'; - -import { JOINABLE_TYPE_MAP } from './checkJoinable.constants.js'; - -export const checkJoinable = ({ - channel, -}: { - channel: VoiceBasedChannel | null; -}): (typeof JOINABLE_TYPE_MAP)[keyof typeof JOINABLE_TYPE_MAP] => { - if (isNil(channel)) { - return JOINABLE_TYPE_MAP.NOT_FOUND; - } else if (!channel.joinable) { - return JOINABLE_TYPE_MAP.NOT_JOINABLE; - } else if (!channel.viewable) { - return JOINABLE_TYPE_MAP.NOT_VIEWABLE; - } else { - return JOINABLE_TYPE_MAP.JOINABLE; - } -}; diff --git a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/index.ts b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/index.ts new file mode 100644 index 00000000..e11e9768 --- /dev/null +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/index.ts @@ -0,0 +1,2 @@ +export { getJoinableStateStatus } from './internal/getJoinableStateStatus.func.js'; +export { JOINABLE_STATE_STATUS } from './internal/getJoinableStateStatus.constants.js'; diff --git a/src/features/core/internal/Voice/internal/funcs/checkJoinable/internal/checkJoinable.constants.ts b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.constants.ts similarity index 64% rename from src/features/core/internal/Voice/internal/funcs/checkJoinable/internal/checkJoinable.constants.ts rename to src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.constants.ts index 7ae6264b..902eaeb6 100644 --- a/src/features/core/internal/Voice/internal/funcs/checkJoinable/internal/checkJoinable.constants.ts +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.constants.ts @@ -1,7 +1,7 @@ -export const JOINABLE_TYPE_MAP = { +export const JOINABLE_STATE_STATUS = { JOINABLE: 'JOINABLE', NOT_JOINABLE: 'NOT_JOINABLE', NOT_FOUND: 'NOT_FOUND', NOT_VIEWABLE: 'NOT_VIEWABLE', ALREADY_JOINED: 'ALREADY_JOINED', -} as const; +} as const satisfies Record; 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 new file mode 100644 index 00000000..77454a38 --- /dev/null +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts @@ -0,0 +1,19 @@ +import { isNil, type VoiceBasedChannel } from '@/features/library/index.js'; + +import { JOINABLE_STATE_STATUS } from './getJoinableStateStatus.constants.js'; + +export const getJoinableStateStatus = ({ + channel, +}: { + channel: VoiceBasedChannel | null; +}): (typeof JOINABLE_STATE_STATUS)[keyof typeof JOINABLE_STATE_STATUS] => { + 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 { + return JOINABLE_STATE_STATUS.JOINABLE; + } +}; diff --git a/src/features/core/internal/Voice/internal/funcs/checkJoinable/internal/checkJoinable.spec.ts b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts similarity index 71% rename from src/features/core/internal/Voice/internal/funcs/checkJoinable/internal/checkJoinable.spec.ts rename to src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts index 46921183..e477231f 100644 --- a/src/features/core/internal/Voice/internal/funcs/checkJoinable/internal/checkJoinable.spec.ts +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts @@ -1,16 +1,16 @@ import type { VoiceBasedChannel } from '@/features/library/index.js'; -import { checkJoinable } from './checkJoinable.func.js'; +import { getJoinableStateStatus } from './getJoinableStateStatus.func.js'; -describe('checkJoinable', () => { +describe('getJoinableStateStatus', () => { it('should return NOT_FOUND if the channel is null', () => { - const result = checkJoinable({ channel: null }); + const result = getJoinableStateStatus({ channel: null }); expect(result).toBe('NOT_FOUND'); }); it('should return NOT_JOINABLE if the channel is not joinable', () => { - const result = checkJoinable({ + const result = getJoinableStateStatus({ channel: { joinable: false } as VoiceBasedChannel, }); @@ -18,7 +18,7 @@ describe('checkJoinable', () => { }); it('should return NOT_VIEWABLE if the channel is not viewable', () => { - const result = checkJoinable({ + const result = getJoinableStateStatus({ channel: { joinable: true, viewable: false } as VoiceBasedChannel, }); @@ -26,7 +26,7 @@ describe('checkJoinable', () => { }); it('should return JOINABLE if the channel is joinable and viewable', () => { - const result = checkJoinable({ + const result = getJoinableStateStatus({ channel: { joinable: true, viewable: true } as VoiceBasedChannel, });