Skip to content

Commit

Permalink
feat: Add support for async event handlers (#258)
Browse files Browse the repository at this point in the history
  • Loading branch information
tjtanjin authored Nov 6, 2024
1 parent c202ac4 commit 48a405d
Show file tree
Hide file tree
Showing 34 changed files with 140 additions and 125 deletions.
12 changes: 6 additions & 6 deletions __tests__/hooks/internal/useAudioInternal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe("useAudioInternal Hook", () => {
// initial values
const initialAudioToggledOn = MockDefaultSettings.audio?.defaultToggledOn;

it("should toggle audio correctly, change state and emit rcb-toggle-audio event", () => {
it("should toggle audio correctly, change state and emit rcb-toggle-audio event", async () => {
// mocks rcb event handler
const callRcbEventMock = jest.fn().mockReturnValue({ defaultPrevented: false });
mockUseRcbEventInternal.mockReturnValue({
Expand All @@ -39,8 +39,8 @@ describe("useAudioInternal Hook", () => {
expect(result.current.audioToggledOn).toBe(initialAudioToggledOn);

// simulates clicking the toggle action
act(() => {
result.current.toggleAudio();
await act(async () => {
await result.current.toggleAudio();
});

// checks if callRcbEvent was called with rcb-toggle-audio and correct arguments
Expand All @@ -53,7 +53,7 @@ describe("useAudioInternal Hook", () => {
expect(result.current.audioToggledOn).toBe(!initialAudioToggledOn);
});

it("should prevent toggling when event is defaultPrevented", () => {
it("should prevent toggling when event is defaultPrevented", async () => {
// mocks rcb event handler
const callRcbEventMock = jest.fn().mockReturnValue({ defaultPrevented: true });
mockUseRcbEventInternal.mockReturnValue({
Expand All @@ -69,8 +69,8 @@ describe("useAudioInternal Hook", () => {
expect(result.current.audioToggledOn).toBe(initialAudioToggledOn);

// simulates clicking the toggle action
act(() => {
result.current.toggleAudio();
await act(async () => {
await result.current.toggleAudio();
});

// checks if callRcbEvent was called with rcb-toggle-audio and correct arguments
Expand Down
4 changes: 2 additions & 2 deletions __tests__/hooks/internal/useChatHistoryInternal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ describe("useChatHistoryInternal Hook", () => {
expect(result.current.isLoadingChatHistory).toBe(initialIsLoadingChatHistory);

// simulates clicking on load chat history button
act(() => {
result.current.showChatHistory();
await act(async () => {
await result.current.showChatHistory();
});

// checks if loading state is true
Expand Down
22 changes: 11 additions & 11 deletions __tests__/hooks/internal/useChatWindowInternal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe("useChatWindowInternal Hook", () => {
// initial values
const initialChatWindowOpen = MockDefaultSettings.chatWindow?.defaultOpen;

it("should toggle chat window correctly, change state and emit rcb-toggle-chat-window event", () => {
it("should toggle chat window correctly, change state and emit rcb-toggle-chat-window event", async () => {
// mocks rcb event handler
const callRcbEventMock = jest.fn().mockReturnValue({ defaultPrevented: false });
mockUseRcbEventInternal.mockReturnValue({
Expand All @@ -39,8 +39,8 @@ describe("useChatWindowInternal Hook", () => {
expect(result.current.isChatWindowOpen).toBe(initialChatWindowOpen);

// simulates clicking the toggle action
act(() => {
result.current.toggleChatWindow();
await act(async () => {
await result.current.toggleChatWindow();
});

// checks if callRcbEvent was called with rcb-toggle-chat-window and correct arguments
Expand All @@ -53,7 +53,7 @@ describe("useChatWindowInternal Hook", () => {
expect(result.current.isChatWindowOpen).toBe(!initialChatWindowOpen);
});

it("should prevent toggling when event is defaultPrevented", () => {
it("should prevent toggling when event is defaultPrevented", async () => {
// mocks rcb event handler
const callRcbEventMock = jest.fn().mockReturnValue({ defaultPrevented: true });
mockUseRcbEventInternal.mockReturnValue({
Expand All @@ -69,8 +69,8 @@ describe("useChatWindowInternal Hook", () => {
expect(result.current.isChatWindowOpen).toBe(initialChatWindowOpen);

// simulates clicking the toggle action
act(() => {
result.current.toggleChatWindow();
await act(async () => {
await result.current.toggleChatWindow();
});

// checks if callRcbEvent was called with rcb-toggle-chat-window and correct arguments
Expand All @@ -83,7 +83,7 @@ describe("useChatWindowInternal Hook", () => {
expect(result.current.isChatWindowOpen).toBe(initialChatWindowOpen);
});

it("should call openChat with correct parameters to open and close the chat window", () => {
it("should call openChat with correct parameters to open and close the chat window", async () => {
// mocks rcb event handler
const callRcbEventMock = jest.fn().mockReturnValue({ defaultPrevented: false });
mockUseRcbEventInternal.mockReturnValue({
Expand All @@ -99,8 +99,8 @@ describe("useChatWindowInternal Hook", () => {
expect(result.current.isChatWindowOpen).toBe(initialChatWindowOpen);

// opens the chat window
act(() => {
result.current.openChat(true);
await act(async () => {
await result.current.openChat(true);
});

// checks if callRcbEvent was called with rcb-toggle-chat-window and correct arguments
Expand All @@ -113,8 +113,8 @@ describe("useChatWindowInternal Hook", () => {
expect(result.current.isChatWindowOpen).toBe(!initialChatWindowOpen);

// closes the chat window
act(() => {
result.current.openChat(false);
await act(async () => {
await result.current.openChat(false);
});

// checks if callRcbEvent was called with rcb-toggle-chat-window and correct arguments
Expand Down
12 changes: 6 additions & 6 deletions __tests__/hooks/internal/useNotificationsInternal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe("useNotificationsInternal Hook", () => {
// initial values
const initialNotificationsToggledOn = MockDefaultSettings.notification?.defaultToggledOn;

it("should toggle notifications correctly, change state and emit rcb-toggle-notifications event", () => {
it("should toggle notifications correctly, change state and emit rcb-toggle-notifications event", async () => {
// mocks rcb event handler
const callRcbEventMock = jest.fn().mockReturnValue({ defaultPrevented: false });
mockUseRcbEventInternal.mockReturnValue({
Expand All @@ -39,8 +39,8 @@ describe("useNotificationsInternal Hook", () => {
expect(result.current.notificationsToggledOn).toBe(initialNotificationsToggledOn);

// simulates clicking the toggle action
act(() => {
result.current.toggleNotifications();
await act(async () => {
await result.current.toggleNotifications();
});

// checks if callRcbEvent was called with rcb-toggle-notifications and correct arguments
Expand All @@ -53,7 +53,7 @@ describe("useNotificationsInternal Hook", () => {
expect(result.current.notificationsToggledOn).toBe(!initialNotificationsToggledOn);
});

it("should prevent toggling when event is defaultPrevented", () => {
it("should prevent toggling when event is defaultPrevented", async () => {
// mocks rcb event handler
const callRcbEventMock = jest.fn().mockReturnValue({ defaultPrevented: true });
mockUseRcbEventInternal.mockReturnValue({
Expand All @@ -69,8 +69,8 @@ describe("useNotificationsInternal Hook", () => {
expect(result.current.notificationsToggledOn).toBe(initialNotificationsToggledOn);

// simulates clicking the toggle action
act(() => {
result.current.toggleNotifications();
await act(async () => {
await result.current.toggleNotifications();
});

// checks if callRcbEvent was called with rcb-toggle-notifications and correct arguments
Expand Down
4 changes: 2 additions & 2 deletions __tests__/hooks/internal/usePathsInternal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe("usePathsInternal Hook", () => {
const { result } = renderHook(() => usePathsInternal());

await act(async () => {
const success = result.current.goToPath("newPath");
const success = await result.current.goToPath("newPath");
expect(success).toBe(true);
});

Expand Down Expand Up @@ -88,7 +88,7 @@ describe("usePathsInternal Hook", () => {
const { result } = renderHook(() => usePathsInternal());

await act(async () => {
const success = result.current.goToPath("blockedPath");
const success = await result.current.goToPath("blockedPath");
expect(success).toBe(false);
});

Expand Down
6 changes: 3 additions & 3 deletions __tests__/hooks/internal/useTextAreaInternal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ describe("useTextAreaInternal Hook", () => {
expect(result.current.getTextAreaValue().length).toBe(1000);
});

it("should prevent setting value if event is defaultPrevented", () => {
it("should prevent setting value if event is defaultPrevented", async () => {
const callRcbEventMock = jest.fn().mockReturnValue({ defaultPrevented: true });
mockUseRcbEventInternal.mockReturnValue({
callRcbEvent: callRcbEventMock,
Expand All @@ -136,8 +136,8 @@ describe("useTextAreaInternal Hook", () => {

const { result } = renderHook(() => useTextAreaInternal());

act(() => {
result.current.setTextAreaValue("Test value");
await act(async () => {
await result.current.setTextAreaValue("Test value");
});

expect(result.current.getTextAreaValue()).toBe("");
Expand Down
36 changes: 18 additions & 18 deletions __tests__/hooks/internal/useToastsInternal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ describe('useToastsInternal', () => {
jest.clearAllMocks();
});

it('should add a new toast when not exceeding maxCount', () => {
it('should add a new toast when not exceeding maxCount', async () => {
// Test adding a toast when maxCount is not reached
mockRcbEventInternal.callRcbEvent.mockReturnValue({ defaultPrevented: false,
data: { toast: { id: 'mocked-uuid', content: 'New toast content', timeout: undefined }
} });
const { result } = renderHook(() => useToastsInternal());
act(() => {
result.current.showToast('New toast content');
await act(async () => {
await result.current.showToast('New toast content');
});
expect(generateSecureUUID).toHaveBeenCalled();
expect(mockToastsContext.setToasts).toHaveBeenCalledWith(expect.any(Function));
Expand All @@ -81,16 +81,16 @@ describe('useToastsInternal', () => {
expect(newToasts).toEqual([{ id: 'mocked-uuid', content: 'New toast content', timeout: undefined }]);
});

it('should not add a new toast if maxCount is reached and forbidOnMax is true', () => {
it('should not add a new toast if maxCount is reached and forbidOnMax is true', async () => {
// Test forbidding new toast if maxCount is reached
mockToastsContext.toasts = [{ id: '1' }, { id: '2' }, { id: '3' }];
const { result } = renderHook(() => useToastsInternal());
const toastId = result.current.showToast('Toast content');
const toastId = await result.current.showToast('Toast content');
expect(toastId).toBeNull();
expect(mockToastsContext.setToasts).not.toHaveBeenCalled();
});

it('should remove the oldest toast and add a new one if maxCount is reached but forbidOnMax is false', () => {
it('should remove the oldest toast and add a new one if maxCount is reached but forbidOnMax is false', async () => {
// Test replacing oldest toast if maxCount reached and forbidOnMax is false
mockSettingsContext.settings.toast.forbidOnMax = false;
mockToastsContext.toasts = [{ id: '1' }, { id: '2' }, { id: '3' }];
Expand All @@ -99,8 +99,8 @@ describe('useToastsInternal', () => {
content: 'New toast content', timeout: undefined }
} });
const { result } = renderHook(() => useToastsInternal());
act(() => {
result.current.showToast('New toast content');
await act(async () => {
await result.current.showToast('New toast content');
});
expect(mockToastsContext.setToasts).toHaveBeenCalledWith(expect.any(Function));

Expand All @@ -114,14 +114,14 @@ describe('useToastsInternal', () => {
]);
});

it('should dismiss a toast by id', () => {
it('should dismiss a toast by id', async () => {
// Test dismissing a toast by ID
const toast = { id: 'toast-1', content: 'Toast to dismiss' };
mockToastsContext.toasts = [toast];
mockRcbEventInternal.callRcbEvent.mockReturnValue({ defaultPrevented: false });
const { result } = renderHook(() => useToastsInternal());
act(() => {
result.current.dismissToast('toast-1');
await act(async () => {
await result.current.dismissToast('toast-1');
});
expect(mockToastsContext.setToasts).toHaveBeenCalledWith(expect.any(Function));

Expand All @@ -131,32 +131,32 @@ describe('useToastsInternal', () => {
expect(updatedToasts).toEqual([]);
});

it('should not dismiss a toast if the id is not found', () => {
it('should not dismiss a toast if the id is not found', async () => {
// Test no dismissal if ID not found
mockToastsContext.toasts = [{ id: 'toast-2', content: 'Another toast' }];
const { result } = renderHook(() => useToastsInternal());
const resultId = result.current.dismissToast('invalid-id');
const resultId = await result.current.dismissToast('invalid-id');
expect(resultId).toBeNull();
expect(mockToastsContext.setToasts).not.toHaveBeenCalled();
});

it('should not show toast if rcbShowToast event is prevented', () => {
it('should not show toast if rcbShowToast event is prevented', async () => {
// Test prevention of toast display by event
mockRcbEventInternal.callRcbEvent.mockReturnValue({ defaultPrevented: true });
const { result } = renderHook(() => useToastsInternal());
const resultId = result.current.showToast('Prevented toast');
const resultId = await result.current.showToast('Prevented toast');
expect(resultId).toBeNull();
expect(mockToastsContext.setToasts).not.toHaveBeenCalled();
});

it('should call rcbDismissToast event when dismissing a toast', () => {
it('should call rcbDismissToast event when dismissing a toast', async () => {
// Test triggering of dismiss event upon toast removal
const toast = { id: 'toast-1', content: 'Toast to dismiss' };
mockToastsContext.toasts = [toast];
mockRcbEventInternal.callRcbEvent.mockReturnValue({ defaultPrevented: false });
const { result } = renderHook(() => useToastsInternal());
act(() => {
result.current.dismissToast('toast-1');
await act(async () => {
await result.current.dismissToast('toast-1');
});
expect(mockRcbEventInternal.callRcbEvent).toHaveBeenCalledWith(RcbEvent.DISMISS_TOAST, { toast });
});
Expand Down
6 changes: 3 additions & 3 deletions __tests__/hooks/internal/useVoiceInternal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe("useVoiceInternal Hook", () => {
// initial values
const initialVoiceToggledOn = MockDefaultSettings.voice?.defaultToggledOn;

it("should toggle voice correctly, change state and emit rcb-toggle-voice event", () => {
it("should toggle voice correctly, change state and emit rcb-toggle-voice event", async () => {
// mocks rcb event handler
const callRcbEventMock = jest.fn().mockReturnValue({ defaultPrevented: false });
mockUseRcbEventInternal.mockReturnValue({
Expand All @@ -42,8 +42,8 @@ describe("useVoiceInternal Hook", () => {
expect(result.current.voiceToggledOn).toBe(initialVoiceToggledOn);

// simulates clicking the toggle action
act(() => {
result.current.toggleVoice();
await act(async () => {
await result.current.toggleVoice();
});

// checks if callRcbEvent was called with rcb-toggle-voice and correct arguments
Expand Down
16 changes: 8 additions & 8 deletions __tests__/services/RcbEventService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('emitRcbEvent', () => {
});

// Test for emitting a cancellable event
it('should emit a cancellable event and return the event', () => {
it('should emit a cancellable event and return the event', async () => {
const eventName = RcbEvent.TOGGLE_AUDIO;
const eventDetail: EventDetail = {
botId: 'testBotId',
Expand All @@ -34,7 +34,7 @@ describe('emitRcbEvent', () => {
const data = { someData: 'testData' };

// Call emitRcbEvent and capture the result
const result = emitRcbEvent(eventName, eventDetail, data);
const result = await emitRcbEvent(eventName, eventDetail, data);

// Verify that the event was dispatched correctly
if (dispatchedEvent) {
Expand All @@ -49,7 +49,7 @@ describe('emitRcbEvent', () => {
});

// Test for emitting a non-cancellable event
it('should emit a non-cancellable event and return the event', () => {
it('should emit a non-cancellable event and return the event', async () => {
const eventName = RcbEvent.POST_INJECT_MESSAGE;
const eventDetail: EventDetail = {
botId: 'testBotId',
Expand All @@ -58,7 +58,7 @@ describe('emitRcbEvent', () => {
};
const data = { someData: 'testData' };

const result = emitRcbEvent(eventName, eventDetail, data);
const result = await emitRcbEvent(eventName, eventDetail, data);

// Verify that the event was dispatched as non-cancellable
if (dispatchedEvent) {
Expand All @@ -73,15 +73,15 @@ describe('emitRcbEvent', () => {
});

// Test for handling an event with empty data
it('should handle an event with empty data', () => {
it('should handle an event with empty data', async () => {
const eventName = RcbEvent.TOGGLE_VOICE;
const eventDetail: EventDetail = {
botId: 'testBotId',
currPath: 'testCurrentPath',
prevPath: 'testPreviousPath'
};

const result = emitRcbEvent(eventName, eventDetail, {});
const result = await emitRcbEvent(eventName, eventDetail, {});

// Verify the event was dispatched with empty data
if (dispatchedEvent) {
Expand All @@ -95,10 +95,10 @@ describe('emitRcbEvent', () => {
});

// Test for handling an event with no detail and empty data
it('should handle an event with no detail and data', () => {
it('should handle an event with no detail and data', async () => {
const eventName = RcbEvent.CHANGE_PATH;

const result = emitRcbEvent(eventName, {
const result = await emitRcbEvent(eventName, {
botId: null,
currPath: null,
prevPath: null
Expand Down
Loading

0 comments on commit 48a405d

Please sign in to comment.