Skip to content

Commit

Permalink
もっと汎化する
Browse files Browse the repository at this point in the history
  • Loading branch information
na2na-p committed Nov 22, 2023
1 parent fadad66 commit cd5eacf
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 60 deletions.
6 changes: 5 additions & 1 deletion src/features/core/index.ts
Original file line number Diff line number Diff line change
@@ -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';
4 changes: 4 additions & 0 deletions src/features/core/internal/Voice/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export { Voice } from './internal/Voice.class.js';
export {
getJoinableStateStatus,
JOINABLE_STATE_STATUS,
} from './internal/funcs/getJoinableStateStatus/index.js';
54 changes: 33 additions & 21 deletions src/features/core/internal/Voice/internal/Voice.class.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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(),
};
});

Expand All @@ -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,
Expand All @@ -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({
Expand All @@ -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({
Expand All @@ -132,11 +134,13 @@ describe('Voice', () => {
} as unknown as Readonly<ChatInputCommandInteraction>;

(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()'
);
});

Expand All @@ -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 () => {
Expand All @@ -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',
Expand All @@ -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.'
Expand Down
18 changes: 9 additions & 9 deletions src/features/core/internal/Voice/internal/Voice.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<{
Expand All @@ -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,
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { getJoinableStateStatus } from './internal/getJoinableStateStatus.func.js';
export { JOINABLE_STATE_STATUS } from './internal/getJoinableStateStatus.constants.js';
Original file line number Diff line number Diff line change
@@ -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<string, string>;
Original file line number Diff line number Diff line change
@@ -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;
}
};
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
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,
});

expect(result).toBe('NOT_JOINABLE');
});

it('should return NOT_VIEWABLE if the channel is not viewable', () => {
const result = checkJoinable({
const result = getJoinableStateStatus({
channel: { joinable: true, viewable: false } as VoiceBasedChannel,
});

expect(result).toBe('NOT_VIEWABLE');
});

it('should return JOINABLE if the channel is joinable and viewable', () => {
const result = checkJoinable({
const result = getJoinableStateStatus({
channel: { joinable: true, viewable: true } as VoiceBasedChannel,
});

Expand Down

0 comments on commit cd5eacf

Please sign in to comment.