Skip to content

Commit

Permalink
✅ test: add test (lobehub#1433)
Browse files Browse the repository at this point in the history
* ✅ test: add test

* ✅ test: add tests
  • Loading branch information
arvinxx authored Mar 1, 2024
1 parent 11f8497 commit 438b4c2
Show file tree
Hide file tree
Showing 5 changed files with 387 additions and 13 deletions.
2 changes: 2 additions & 0 deletions src/store/chat/slices/enchance/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export const chatEnhance: StateCreator<
const getMessageById = (id: string) => chatSelectors.getMessageById(id)(get());

const message = getMessageById(messageId);
if (!message) return;

const parent = getMessageById(message!.parentId!);
const originPrompt = parent?.content;

Expand Down
86 changes: 86 additions & 0 deletions src/store/chat/slices/share/action.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { act, renderHook } from '@testing-library/react';

import { DEFAULT_USER_AVATAR_URL } from '@/const/meta';
import { shareGPTService } from '@/services/share';
import { useChatStore } from '@/store/chat';

describe('shareSlice actions', () => {
let shareGPTServiceSpy: any;
let windowOpenSpy;

beforeEach(() => {
shareGPTServiceSpy = vi
.spyOn(shareGPTService, 'createShareGPTUrl')
.mockResolvedValue('test-url');
windowOpenSpy = vi.spyOn(window, 'open');
});

afterEach(() => {
vi.restoreAllMocks();
});

describe('shareToShareGPT', () => {
it('should share to ShareGPT and open a new window', async () => {
const { result } = renderHook(() => useChatStore());
const shareGPTServiceSpy = vi.spyOn(shareGPTService, 'createShareGPTUrl');
const windowOpenSpy = vi.spyOn(window, 'open');
const avatar = 'avatar-url';
const withPluginInfo = true;
const withSystemRole = true;

await act(async () => {
await result.current.shareToShareGPT({ avatar, withPluginInfo, withSystemRole });
});

expect(shareGPTServiceSpy).toHaveBeenCalled();
expect(windowOpenSpy).toHaveBeenCalled();
});
it('should handle messages from different roles correctly', async () => {
// 注意:此处需要你根据实际情况模拟 chatSelectors.currentChats 和 agentSelectors 返回的数据
// 此外,你可能需要调整 useChatStore 的引用路径
const { result } = renderHook(() => useChatStore());
await act(async () => {
await result.current.shareToShareGPT({
withPluginInfo: true,
withSystemRole: true,
});
});
// 根据你的逻辑添加对应的expect断言
});

it('should not include system role information when withSystemRole is false or systemRole is undefined', async () => {
// 模拟不同的配置以测试这个行为
// 你可能需要调整 useChatStore 的引用路径
const { result } = renderHook(() => useChatStore());
await act(async () => {
await result.current.shareToShareGPT({
withSystemRole: false,
});
});
// 根据你的逻辑添加对应的expect断言
});

it('should use default avatar URL when avatar is not provided', async () => {
const { result } = renderHook(() => useChatStore());
await act(async () => {
await result.current.shareToShareGPT({});
});

expect(shareGPTServiceSpy).toHaveBeenCalledWith(
expect.objectContaining({
avatarUrl: DEFAULT_USER_AVATAR_URL,
}),
);
});

it('should set shareLoading to true before sharing and to false after sharing', async () => {
const { result } = renderHook(() => useChatStore());
expect(result.current.shareLoading).toBe(false);
await act(async () => {
await result.current.shareToShareGPT({});
});
expect(result.current.shareLoading).toBe(false);
// 注意:这里的验证可能需要你根据实际的状态管理逻辑进行调整
});
});
});
185 changes: 173 additions & 12 deletions src/store/global/slices/common/action.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import { act, renderHook } from '@testing-library/react';
import { router } from 'next/client';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { act, renderHook, waitFor } from '@testing-library/react';
import { mutate } from 'swr';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { withSWR } from '~test-utils';

import { globalService } from '@/services/global';
import { userService } from '@/services/user';
import { useGlobalStore } from '@/store/global';
import { GlobalServerConfig } from '@/types/settings';
import { switchLang } from '@/utils/switchLang';

import { SidebarTabKey } from './initialState';
vi.mock('zustand/traditional');

// Mock globalService
vi.mock('@/services/global', () => ({
globalService: {
getLatestVersion: vi.fn(),
getGlobalConfig: vi.fn(),
},
vi.mock('@/utils/switchLang', () => ({
switchLang: vi.fn(),
}));

beforeEach(() => {
vi.clearAllMocks();
vi.mock('swr', async (importOriginal) => {
const modules = await importOriginal();
return {
...(modules as any),
mutate: vi.fn(),
};
});

afterEach(() => {
Expand All @@ -38,4 +42,161 @@ describe('createCommonSlice', () => {
expect(router.push).toHaveBeenCalledWith('/chat?session=session-id');
});
});

describe('refreshUserConfig', () => {
it('should refresh user config', async () => {
const { result } = renderHook(() => useGlobalStore());

await act(async () => {
await result.current.refreshUserConfig();
});

expect(mutate).toHaveBeenCalledWith(['fetchUserConfig', true]);
});
});

describe('updateAvatar', () => {
it('should update avatar', async () => {
const { result } = renderHook(() => useGlobalStore());
const avatar = 'new-avatar';

const spyOn = vi.spyOn(result.current, 'refreshUserConfig');
const updateAvatarSpy = vi.spyOn(userService, 'updateAvatar');

await act(async () => {
await result.current.updateAvatar(avatar);
});

expect(updateAvatarSpy).toHaveBeenCalledWith(avatar);
expect(spyOn).toHaveBeenCalled();
});
});

describe('useCheckLatestVersion', () => {
it('should set hasNewVersion to false if there is no new version', async () => {
const latestVersion = '0.0.1';

vi.spyOn(globalService, 'getLatestVersion').mockResolvedValueOnce(latestVersion);

const { result } = renderHook(() => useGlobalStore().useCheckLatestVersion(), {
wrapper: withSWR,
});

await waitFor(() => {
expect(result.current.data).toBe(latestVersion);
});

expect(useGlobalStore.getState().hasNewVersion).toBeUndefined();
expect(useGlobalStore.getState().latestVersion).toBeUndefined();
});

it('should set hasNewVersion to true if there is a new version', async () => {
const latestVersion = '10000000.0.0';

vi.spyOn(globalService, 'getLatestVersion').mockResolvedValueOnce(latestVersion);

const { result } = renderHook(() => useGlobalStore().useCheckLatestVersion(), {
wrapper: withSWR,
});

await waitFor(() => {
expect(result.current.data).toBe(latestVersion);
});

expect(useGlobalStore.getState().hasNewVersion).toBe(true);
expect(useGlobalStore.getState().latestVersion).toBe(latestVersion);
});
});

describe('useFetchServerConfig', () => {
it('should fetch server config correctly', async () => {
const mockServerConfig = {
defaultAgent: 'agent1',
languageModel: 'model1',
} as GlobalServerConfig;
vi.spyOn(globalService, 'getGlobalConfig').mockResolvedValueOnce(mockServerConfig);

const { result } = renderHook(() => useGlobalStore().useFetchServerConfig());

await waitFor(() => expect(result.current.data).toEqual(mockServerConfig));
});
});

describe('useFetchUserConfig', () => {
it('should not fetch user config if initServer is false', async () => {
const mockUserConfig: any = undefined; // 模拟未初始化服务器的情况
vi.spyOn(userService, 'getUserConfig').mockResolvedValueOnce(mockUserConfig);

const { result } = renderHook(() => useGlobalStore().useFetchUserConfig(false), {
wrapper: withSWR,
});

// 因为 initServer 为 false,所以不会触发 getUserConfig 的调用
expect(userService.getUserConfig).not.toHaveBeenCalled();
// 确保状态未改变
expect(result.current.data).toBeUndefined();
});

it('should fetch user config correctly when initServer is true', async () => {
const mockUserConfig: any = {
avatar: 'new-avatar-url',
settings: {
language: 'en',
},
};
vi.spyOn(userService, 'getUserConfig').mockResolvedValueOnce(mockUserConfig);

const { result } = renderHook(() => useGlobalStore().useFetchUserConfig(true), {
wrapper: withSWR,
});

// 等待 SWR 完成数据获取
await waitFor(() => expect(result.current.data).toEqual(mockUserConfig));

// 验证状态是否正确更新
expect(useGlobalStore.getState().avatar).toBe(mockUserConfig.avatar);
expect(useGlobalStore.getState().settings).toEqual(mockUserConfig.settings);

// 验证是否正确处理了语言设置
expect(switchLang).not.toHaveBeenCalledWith('auto');
});
it('should call switch language when language is auto', async () => {
const mockUserConfig: any = {
avatar: 'new-avatar-url',
settings: {
language: 'auto',
},
};
vi.spyOn(userService, 'getUserConfig').mockResolvedValueOnce(mockUserConfig);

const { result } = renderHook(() => useGlobalStore().useFetchUserConfig(true), {
wrapper: withSWR,
});

// 等待 SWR 完成数据获取
await waitFor(() => expect(result.current.data).toEqual(mockUserConfig));

// 验证状态是否正确更新
expect(useGlobalStore.getState().avatar).toBe(mockUserConfig.avatar);
expect(useGlobalStore.getState().settings).toEqual(mockUserConfig.settings);

// 验证是否正确处理了语言设置
expect(switchLang).toHaveBeenCalledWith('auto');
});

it('should handle the case when user config is null', async () => {
vi.spyOn(userService, 'getUserConfig').mockResolvedValueOnce(null as any);

const { result } = renderHook(() => useGlobalStore().useFetchUserConfig(true), {
wrapper: withSWR,
});

// 等待 SWR 完成数据获取
await waitFor(() => expect(result.current.data).toBeNull());

// 验证状态未被错误更新
expect(useGlobalStore.getState().avatar).toBeUndefined();
expect(useGlobalStore.getState().settings).toEqual({});
});
});
});
Loading

0 comments on commit 438b4c2

Please sign in to comment.