@lobehub/chat
Version:
Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.
165 lines (133 loc) • 5.3 kB
text/typescript
import { act, renderHook, waitFor } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { withSWR } from '~test-utils';
import { syncService } from '@/services/sync';
import { useUserStore } from '@/store/user';
import { userProfileSelectors } from '@/store/user/selectors';
import { syncSettingsSelectors } from '@/store/user/selectors';
vi.mock('zustand/traditional');
vi.mock('swr', async (importOriginal) => {
const modules = await importOriginal();
return {
...(modules as any),
mutate: vi.fn(),
};
});
afterEach(() => {
vi.restoreAllMocks();
});
describe('createSyncSlice', () => {
describe('refreshConnection', () => {
it('should not call triggerEnableSync when userId is empty', async () => {
const { result } = renderHook(() => useUserStore());
const onEvent = vi.fn();
vi.spyOn(userProfileSelectors, 'userId').mockReturnValueOnce(undefined as any);
const triggerEnableSyncSpy = vi.spyOn(result.current, 'triggerEnableSync');
await act(async () => {
await result.current.refreshConnection(onEvent);
});
expect(triggerEnableSyncSpy).not.toHaveBeenCalled();
});
it('should call triggerEnableSync when userId exists', async () => {
const { result } = renderHook(() => useUserStore());
const onEvent = vi.fn();
const userId = 'user-id';
vi.spyOn(userProfileSelectors, 'userId').mockReturnValueOnce(userId);
const triggerEnableSyncSpy = vi.spyOn(result.current, 'triggerEnableSync');
await act(async () => {
await result.current.refreshConnection(onEvent);
});
expect(triggerEnableSyncSpy).toHaveBeenCalledWith(userId, onEvent);
});
});
describe('triggerEnableSync', () => {
it('should return false when sync.channelName is empty', async () => {
const { result } = renderHook(() => useUserStore());
const userId = 'user-id';
const onEvent = vi.fn();
vi.spyOn(syncSettingsSelectors, 'webrtcConfig').mockReturnValueOnce({
channelName: '',
enabled: true,
});
const data = await act(async () => {
return result.current.triggerEnableSync(userId, onEvent);
});
expect(data).toBe(false);
});
it('should call globalService.enabledSync when sync.channelName exists', async () => {
const userId = 'user-id';
const onEvent = vi.fn();
const channelName = 'channel-name';
const channelPassword = 'channel-password';
const deviceName = 'device-name';
const signaling = 'signaling';
vi.spyOn(syncSettingsSelectors, 'webrtcConfig').mockReturnValueOnce({
channelName,
channelPassword,
signaling,
enabled: true,
});
vi.spyOn(syncSettingsSelectors, 'deviceName').mockReturnValueOnce(deviceName);
const enabledSyncSpy = vi.spyOn(syncService, 'enabledSync').mockResolvedValueOnce(true);
const { result } = renderHook(() => useUserStore());
const data = await act(async () => {
return result.current.triggerEnableSync(userId, onEvent);
});
expect(enabledSyncSpy).toHaveBeenCalledWith({
channel: { name: channelName, password: channelPassword },
onAwarenessChange: expect.any(Function),
onSyncEvent: onEvent,
onSyncStatusChange: expect.any(Function),
signaling,
user: expect.objectContaining({ id: userId, name: deviceName }),
});
expect(data).toBe(true);
});
});
describe('useEnabledSync', () => {
it('should return false when userId is empty', async () => {
const { result } = renderHook(
() =>
useUserStore().useEnabledSync(true, {
userEnableSync: true,
userId: undefined,
onEvent: vi.fn(),
}),
{
wrapper: withSWR,
},
);
await waitFor(() => expect(result.current.data).toBe(false));
});
it('should call syncService.disableSync when userEnableSync is false', async () => {
const disableSyncSpy = vi.spyOn(syncService, 'disableSync').mockResolvedValueOnce(false);
const { result } = renderHook(
() =>
useUserStore().useEnabledSync(true, {
userEnableSync: false,
userId: 'user-id',
onEvent: vi.fn(),
}),
{ wrapper: withSWR },
);
await waitFor(() => expect(result.current.data).toBeUndefined());
expect(disableSyncSpy).toHaveBeenCalled();
});
it('should call triggerEnableSync when userEnableSync and userId exist', async () => {
const userId = 'user-id';
const onEvent = vi.fn();
const triggerEnableSyncSpy = vi.fn().mockResolvedValueOnce(true);
const { result } = renderHook(() => useUserStore());
// replace triggerEnableSync as a mock
result.current.triggerEnableSync = triggerEnableSyncSpy;
const { result: swrResult } = renderHook(
() => result.current.useEnabledSync(true, { userEnableSync: true, userId, onEvent }),
{
wrapper: withSWR,
},
);
await waitFor(() => expect(swrResult.current.data).toBe(true));
expect(triggerEnableSyncSpy).toHaveBeenCalledWith(userId, onEvent);
});
});
});