Skip to content
11 changes: 10 additions & 1 deletion examples/vite/src/CustomMessageUi/variants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,16 @@ const CustomMessageUiActions = () => {
<button onClick={handleOpenThread} title='Open thread'>
↩️
</button>
<button onClick={handleFlag} title='Flag message'>
<button
onClick={async (event) => {
try {
await handleFlag(event);
} catch (error) {
console.error('Failed to flag the message', error);
}
}}
title='Flag message'
>
{' '}
🚩
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ describe('useDeleteHandler custom hook', () => {
expect(typeof handleDelete).toBe('function');
});

it('should throw without deleting when the message has no id', async () => {
const deleteSpy = vi.spyOn(channel.messageOperations, 'delete');
const handleDelete = await renderUseDeleteHandler(
generateMessage({ id: undefined }) as typeof testMessage,
);
await act(async () => {
await expect(handleDelete()).rejects.toThrow(
'useDeleteHandler was called but it is missing one or more necessary parameters.',
);
});
expect(deleteSpy).not.toHaveBeenCalled();
});

it('should delete a message without options via the channel local-update path', async () => {
const deleteSpy = vi
.spyOn(channel.messageOperations, 'delete')
Expand Down
10 changes: 6 additions & 4 deletions src/components/Message/hooks/__tests__/useFlagHandler.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ describe('useHandleFlag custom hook', () => {
expect(typeof handleFlag).toBe('function');
});

it('should throw a warning when there are missing parameters and the handler is called', async () => {
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementationOnce(() => null);
it('should throw when there are missing parameters and the handler is called', async () => {
const flagSpy = vi.spyOn(client.moderation, 'flagMessage');
const handleFlag = await renderUseHandleFlagHook(undefined);
await handleFlag(mouseEventMock);
expect(consoleWarnSpy).toHaveBeenCalledWith(missingUseFlagHandlerParameterWarning);
await expect(handleFlag(mouseEventMock)).rejects.toThrow(
missingUseFlagHandlerParameterWarning,
);
expect(flagSpy).not.toHaveBeenCalled();
});

it('should allow to flag a message when it is successful', async () => {
Expand Down
10 changes: 6 additions & 4 deletions src/components/Message/hooks/__tests__/useMuteHandler.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ describe('useHandleMute custom hook', () => {
expect(typeof handleMute).toBe('function');
});

it('should throw a warning when there are missing parameters and the handler is called', async () => {
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementationOnce(() => null);
it('should throw when there are missing parameters and the handler is called', async () => {
const handleMute = await renderUseHandleMuteHook(undefined);
await handleMute(mouseEventMock);
expect(consoleWarnSpy).toHaveBeenCalledWith(missingUseMuteHandlerParamsWarning);
await expect(handleMute(mouseEventMock)).rejects.toThrow(
missingUseMuteHandlerParamsWarning,
);
expect(mute).not.toHaveBeenCalled();
expect(unmute).not.toHaveBeenCalled();
});

it('should allow to mute a user when it is successful', async () => {
Expand Down
11 changes: 11 additions & 0 deletions src/components/Message/hooks/__tests__/usePinHandler.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,17 @@ describe('usePinHandler custom hook', () => {
expect(getStoredMessage(message.id)?.pinned_by).toEqual(newerPinner);
});

it('should throw without pinning when the message is missing', async () => {
const pinSpy = vi.spyOn(client, 'pinMessage');
const { handlePin } = await renderUsePinHandler(undefined as unknown as LocalMessage);
await act(async () => {
await expect(handlePin(mouseEventMock)).rejects.toThrow(
'usePinHandler was called but it is missing the message.',
);
});
expect(pinSpy).not.toHaveBeenCalled();
});

it('should keep a newer pin with the same pinned value that arrived while pinning', async () => {
const rejectRequest = mockPendingRequest('pinMessage');
const newerPinner = generateUser();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ import { generateMessage, initClientWithChannels } from '../../../../mock-builde
import { Channel } from '../../../Channel';
import { Chat } from '../../../Chat';

vi.spyOn(console, 'warn').mockImplementation(() => null);

const event = fromPartial<React.BaseSyntheticEvent>({ preventDefault: vi.fn() });
const missingMessageIdError = 'Mark unread handler does not have access to message id';
const message = generateMessage() as unknown as LocalMessage;

let channel: ChannelType;
Expand Down Expand Up @@ -47,22 +46,22 @@ describe('useMarkUnreadHandler', () => {
vi.restoreAllMocks();
});

it('does not call channel.markUnread if no message is provided', async () => {
it('throws without calling channel.markUnread if no message is provided', async () => {
const markUnreadSpy = vi.spyOn(channel, 'markUnread');
const handleMarkUnread = renderUseMarkUnreadHandlerHook();
await act(async () => {
await handleMarkUnread(event);
await expect(handleMarkUnread(event)).rejects.toThrow(missingMessageIdError);
});
expect(markUnreadSpy).not.toHaveBeenCalled();
});

it('does not call channel.markUnread if message is missing id', async () => {
it('throws without calling channel.markUnread if message is missing id', async () => {
const markUnreadSpy = vi.spyOn(channel, 'markUnread');
const handleMarkUnread = renderUseMarkUnreadHandlerHook({
message: generateMessage({ id: undefined }) as unknown as LocalMessage,
});
await act(async () => {
await handleMarkUnread(event);
await expect(handleMarkUnread(event)).rejects.toThrow(missingMessageIdError);
});
expect(markUnreadSpy).not.toHaveBeenCalled();
});
Expand Down
4 changes: 3 additions & 1 deletion src/components/Message/hooks/useDeleteHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ export const useDeleteHandler = (

return async (options?: DeleteMessageOptions) => {
if (!message?.id || !client) {
return;
throw new Error(
'useDeleteHandler was called but it is missing one or more necessary parameters.',
);
}

try {
Expand Down
3 changes: 1 addition & 2 deletions src/components/Message/hooks/useFlagHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export const useFlagHandler = (message?: LocalMessage): ReactEventHandler => {
event.preventDefault();

if (!client || !t || !message?.id) {
console.warn(missingUseFlagHandlerParameterWarning);
return;
throw new Error(missingUseFlagHandlerParameterWarning);
}

await client.moderation.flagMessage({ message_id: message.id });
Expand Down
3 changes: 1 addition & 2 deletions src/components/Message/hooks/useMarkUnreadHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ export const useMarkUnreadHandler = (
return async (event) => {
event.preventDefault();
if (!message?.id) {
console.warn('Mark unread handler does not have access to message id');
return;
throw new Error('Mark unread handler does not have access to message id');
}

// Request failures propagate so the caller can report them; `notify` only reports success.
Expand Down
3 changes: 1 addition & 2 deletions src/components/Message/hooks/useMuteHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ export const useMuteHandler = (

// The action runs even without `notify` (`Message` passes none); it only reports the outcome.
if (!message?.user || !client) {
console.warn(missingUseMuteHandlerParamsWarning);
return;
throw new Error(missingUseMuteHandlerParamsWarning);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
}
const mutes = client.mutedUsersStore.getLatestValue().mutedUsers ?? [];

Expand Down
4 changes: 3 additions & 1 deletion src/components/Message/hooks/usePinHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ export const usePinHandler = (
const handlePin: ReactEventHandler = async (event) => {
event.preventDefault();

if (!message) return;
if (!message) {
throw new Error('usePinHandler was called but it is missing the message.');
}

if (!message.pinned) {
const optimisticMessage: LocalMessage = {
Expand Down
Loading