-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
6af17c6
commit 36c1306
Showing
2 changed files
with
225 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
// useCreateNewThread.test.ts | ||
import { renderHook, act } from '@testing-library/react' | ||
import { useCreateNewThread } from './useCreateNewThread' | ||
import { useAtomValue, useSetAtom } from 'jotai' | ||
import { useActiveModel } from './useActiveModel' | ||
import useRecommendedModel from './useRecommendedModel' | ||
import useSetActiveThread from './useSetActiveThread' | ||
import { extensionManager } from '@/extension' | ||
import { toaster } from '@/containers/Toast' | ||
|
||
// Mock the dependencies | ||
jest.mock('jotai', () => { | ||
const originalModule = jest.requireActual('jotai') | ||
return { | ||
...originalModule, | ||
useAtomValue: jest.fn(), | ||
useSetAtom: jest.fn(), | ||
} | ||
}) | ||
jest.mock('./useActiveModel') | ||
jest.mock('./useRecommendedModel') | ||
jest.mock('./useSetActiveThread') | ||
jest.mock('@/extension') | ||
jest.mock('@/containers/Toast') | ||
|
||
describe('useCreateNewThread', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks() | ||
}) | ||
|
||
it('should create a new thread', async () => { | ||
const mockSetAtom = jest.fn() | ||
;(useSetAtom as jest.Mock).mockReturnValue(mockSetAtom) | ||
;(useAtomValue as jest.Mock).mockReturnValue({ | ||
metadata: {}, | ||
assistants: [ | ||
{ | ||
id: 'assistant1', | ||
name: 'Assistant 1', | ||
instructions: undefined, | ||
}, | ||
], | ||
}) | ||
;(useActiveModel as jest.Mock).mockReturnValue({ stopInference: jest.fn() }) | ||
;(useRecommendedModel as jest.Mock).mockReturnValue({ | ||
recommendedModel: { id: 'model1', parameters: [], settings: [] }, | ||
downloadedModels: [], | ||
}) | ||
;(useSetActiveThread as jest.Mock).mockReturnValue({ | ||
setActiveThread: jest.fn(), | ||
}) | ||
;(extensionManager.get as jest.Mock).mockReturnValue({ | ||
saveThread: jest.fn(), | ||
}) | ||
|
||
const { result } = renderHook(() => useCreateNewThread()) | ||
|
||
await act(async () => { | ||
await result.current.requestCreateNewThread({ | ||
id: 'assistant1', | ||
name: 'Assistant 1', | ||
model: { | ||
id: 'model1', | ||
parameters: [], | ||
settings: [], | ||
}, | ||
} as any) | ||
}) | ||
|
||
expect(mockSetAtom).toHaveBeenCalledTimes(6) // Check if all the necessary atoms were set | ||
expect(extensionManager.get).toHaveBeenCalled() | ||
}) | ||
|
||
it('should create a new thread with instructions', async () => { | ||
const mockSetAtom = jest.fn() | ||
;(useSetAtom as jest.Mock).mockReturnValue(mockSetAtom) | ||
;(useAtomValue as jest.Mock).mockReturnValueOnce(false) | ||
;(useAtomValue as jest.Mock).mockReturnValue({ | ||
metadata: {}, | ||
assistants: [ | ||
{ | ||
id: 'assistant1', | ||
name: 'Assistant 1', | ||
instructions: 'Hello Jan', | ||
}, | ||
], | ||
}) | ||
;(useAtomValue as jest.Mock).mockReturnValueOnce(false) | ||
;(useActiveModel as jest.Mock).mockReturnValue({ stopInference: jest.fn() }) | ||
;(useRecommendedModel as jest.Mock).mockReturnValue({ | ||
recommendedModel: { id: 'model1', parameters: [], settings: [] }, | ||
downloadedModels: [], | ||
}) | ||
;(useSetActiveThread as jest.Mock).mockReturnValue({ | ||
setActiveThread: jest.fn(), | ||
}) | ||
;(extensionManager.get as jest.Mock).mockReturnValue({ | ||
saveThread: jest.fn(), | ||
}) | ||
|
||
const { result } = renderHook(() => useCreateNewThread()) | ||
|
||
await act(async () => { | ||
await result.current.requestCreateNewThread({ | ||
id: 'assistant1', | ||
name: 'Assistant 1', | ||
instructions: "Hello Jan Assistant", | ||
model: { | ||
id: 'model1', | ||
parameters: [], | ||
settings: [], | ||
}, | ||
} as any) | ||
}) | ||
|
||
expect(mockSetAtom).toHaveBeenCalledTimes(6) // Check if all the necessary atoms were set | ||
expect(extensionManager.get).toHaveBeenCalled() | ||
expect(mockSetAtom).toHaveBeenNthCalledWith( | ||
2, | ||
expect.objectContaining({ | ||
assistants: expect.arrayContaining([ | ||
expect.objectContaining({ instructions: 'Hello Jan Assistant' }), | ||
]), | ||
}) | ||
) | ||
}) | ||
|
||
it('should create a new thread with previous instructions', async () => { | ||
const mockSetAtom = jest.fn() | ||
;(useSetAtom as jest.Mock).mockReturnValue(mockSetAtom) | ||
;(useAtomValue as jest.Mock).mockReturnValueOnce(true) | ||
;(useAtomValue as jest.Mock).mockReturnValueOnce({ | ||
metadata: {}, | ||
assistants: [ | ||
{ | ||
id: 'assistant1', | ||
name: 'Assistant 1', | ||
instructions: 'Hello Jan', | ||
}, | ||
], | ||
}) | ||
;(useAtomValue as jest.Mock).mockReturnValueOnce(true) | ||
;(useActiveModel as jest.Mock).mockReturnValue({ stopInference: jest.fn() }) | ||
;(useRecommendedModel as jest.Mock).mockReturnValue({ | ||
recommendedModel: { id: 'model1', parameters: [], settings: [] }, | ||
downloadedModels: [], | ||
}) | ||
;(useSetActiveThread as jest.Mock).mockReturnValue({ | ||
setActiveThread: jest.fn(), | ||
}) | ||
;(extensionManager.get as jest.Mock).mockReturnValue({ | ||
saveThread: jest.fn(), | ||
}) | ||
|
||
const { result } = renderHook(() => useCreateNewThread()) | ||
|
||
await act(async () => { | ||
await result.current.requestCreateNewThread({ | ||
id: 'assistant1', | ||
name: 'Assistant 1', | ||
model: { | ||
id: 'model1', | ||
parameters: [], | ||
settings: [], | ||
}, | ||
} as any) | ||
}) | ||
|
||
expect(mockSetAtom).toHaveBeenCalledTimes(6) // Check if all the necessary atoms were set | ||
expect(extensionManager.get).toHaveBeenCalled() | ||
expect(mockSetAtom).toHaveBeenNthCalledWith( | ||
2, | ||
expect.objectContaining({ | ||
assistants: expect.arrayContaining([ | ||
expect.objectContaining({ instructions: 'Hello Jan' }), | ||
]), | ||
}) | ||
) | ||
}) | ||
|
||
it('should show a warning toast if trying to create an empty thread', async () => { | ||
;(useAtomValue as jest.Mock).mockReturnValue([{ metadata: {} }]) // Mock an empty thread | ||
;(useRecommendedModel as jest.Mock).mockReturnValue({ | ||
recommendedModel: null, | ||
downloadedModels: [], | ||
}) | ||
|
||
const { result } = renderHook(() => useCreateNewThread()) | ||
|
||
await act(async () => { | ||
await result.current.requestCreateNewThread({ | ||
id: 'assistant1', | ||
name: 'Assistant 1', | ||
tools: [], | ||
} as any) | ||
}) | ||
|
||
expect(toaster).toHaveBeenCalledWith( | ||
expect.objectContaining({ | ||
title: 'No new thread created.', | ||
type: 'warning', | ||
}) | ||
) | ||
}) | ||
|
||
it('should update thread metadata', async () => { | ||
const mockUpdateThread = jest.fn() | ||
;(useSetAtom as jest.Mock).mockReturnValue(mockUpdateThread) | ||
;(extensionManager.get as jest.Mock).mockReturnValue({ | ||
saveThread: jest.fn(), | ||
}) | ||
|
||
const { result } = renderHook(() => useCreateNewThread()) | ||
|
||
const mockThread = { id: 'thread1', title: 'Test Thread' } | ||
|
||
await act(async () => { | ||
await result.current.updateThreadMetadata(mockThread as any) | ||
}) | ||
|
||
expect(mockUpdateThread).toHaveBeenCalledWith(mockThread) | ||
expect(extensionManager.get).toHaveBeenCalled() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters