UNPKG

@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.

175 lines (142 loc) • 6.1 kB
import { t } from 'i18next'; import { describe, expect, it } from 'vitest'; import { ChatStore } from '@/store/chat'; import { initialState } from '@/store/chat/initialState'; import { merge } from '@/utils/merge'; import { topicSelectors } from './selectors'; // Mock i18next vi.mock('i18next', () => ({ t: vi.fn().mockImplementation((key) => key), })); const initialStore = initialState as ChatStore; const topicMaps = { test: [ { id: 'topic1', name: 'Topic 1', favorite: true }, { id: 'topic2', name: 'Topic 2' }, ], }; describe('topicSelectors', () => { describe('currentTopics', () => { it('should return undefined if there are no topics with activeId', () => { const topics = topicSelectors.currentTopics(initialStore); expect(topics).toBeUndefined(); }); it('should return all current topics from the store', () => { const state = merge(initialStore, { topicMaps, activeId: 'test' }); const topics = topicSelectors.currentTopics(state); expect(topics).toEqual(topicMaps.test); }); }); describe('currentTopicLength', () => { it('should return 0 if there are no topics', () => { const length = topicSelectors.currentTopicLength(initialStore); expect(length).toBe(0); }); it('should return the number of current topics', () => { const state = merge(initialStore, { topicMaps, activeId: 'test' }); const length = topicSelectors.currentTopicLength(state); expect(length).toBe(topicMaps.test.length); }); }); describe('currentActiveTopic', () => { it('should return undefined if there is no active topic', () => { const topic = topicSelectors.currentActiveTopic(initialStore); expect(topic).toBeUndefined(); }); it('should return the current active topic', () => { const state = merge(initialStore, { topicMaps, activeId: 'test', activeTopicId: 'topic1' }); const topic = topicSelectors.currentActiveTopic(state); expect(topic).toEqual(topicMaps.test[0]); }); }); describe('currentUnFavTopics', () => { it('should return all unfavorited topics', () => { const state = merge(initialStore, { topicMaps, activeId: 'test' }); const topics = topicSelectors.currentUnFavTopics(state); expect(topics).toEqual([topicMaps.test[1]]); }); }); describe('displayTopics', () => { it('should return current topics if not searching', () => { const state = merge(initialStore, { topicMaps, activeId: 'test' }); const topics = topicSelectors.displayTopics(state); expect(topics).toEqual(topicMaps.test); }); }); describe('searchTopics', () => { it('should return search topics if searching', () => { const searchTopics = [{ id: 'search1', name: 'Search 1' }]; const state = merge(initialStore, { inSearchingMode: true, searchTopics }); const topics = topicSelectors.searchTopics(state); expect(topics).toEqual(searchTopics); }); }); describe('getTopicById', () => { it('should return undefined if topic is not found', () => { const state = merge(initialStore, { topicMaps, activeId: 'test' }); const topic = topicSelectors.getTopicById('notfound')(state); expect(topic).toBeUndefined(); }); it('should return the topic with the given id', () => { const state = merge(initialStore, { topicMaps, activeId: 'test' }); const topic = topicSelectors.getTopicById('topic1')(state); expect(topic).toEqual(topicMaps.test[0]); }); }); describe('groupedTopicsSelector', () => { it('should return empty array if there are no topics', () => { const state = merge(initialStore, { activeId: 'test' }); const grouped = topicSelectors.groupedTopicsSelector(state); expect(grouped).toEqual([]); }); it('should return grouped topics by time when no favorites exist', () => { const topics = [ { id: 'topic1', name: 'Topic 1', favorite: false, createAt: '2023-01-01' }, { id: 'topic2', name: 'Topic 2', favorite: false, createAt: '2023-01-01' }, ]; const state = merge(initialStore, { topicMaps: { test: topics }, activeId: 'test', }); const grouped = topicSelectors.groupedTopicsSelector(state); expect(grouped).toHaveLength(1); // One time-based group expect(grouped[0].children).toEqual(topics); }); it('should separate favorite and unfavorite topics into different groups', () => { const topics = [ { id: 'topic1', name: 'Topic 1', favorite: true, createAt: '2023-01-01' }, { id: 'topic2', name: 'Topic 2', favorite: false, createAt: '2023-01-01' }, { id: 'topic3', name: 'Topic 3', favorite: true, createAt: '2023-01-01' }, ]; const state = merge(initialStore, { topicMaps: { test: topics }, activeId: 'test', }); const grouped = topicSelectors.groupedTopicsSelector(state); expect(grouped).toHaveLength(2); // Favorite group + one time-based group // Check favorite group expect(grouped[0]).toEqual({ id: 'favorite', title: 'favorite', // This matches the mocked t function return children: topics.filter((t) => t.favorite), }); // Check unfavorite group expect(grouped[1].children).toEqual(topics.filter((t) => !t.favorite)); }); it('should only create time-based groups when there are no favorites', () => { const topics = [ { id: 'topic1', name: 'Topic 1', favorite: false, createAt: '2023-01-01' }, { id: 'topic2', name: 'Topic 2', favorite: false, createAt: '2023-02-01' }, ]; const state = merge(initialStore, { topicMaps: { test: topics }, activeId: 'test', }); const grouped = topicSelectors.groupedTopicsSelector(state); // Should not have a favorites group expect(grouped.find((g) => g.id === 'favorite')).toBeUndefined(); // Should have time-based groups expect(grouped.every((g) => g.id !== 'favorite')).toBeTruthy(); }); }); });