308 lines
8.7 KiB
TypeScript
308 lines
8.7 KiB
TypeScript
import { act, renderHook } from '@testing-library/react'
|
|
import * as ModelAtoms from './Model.atom'
|
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
|
|
|
describe('Model.atom.ts', () => {
|
|
let mockJotaiGet: jest.Mock
|
|
let mockJotaiSet: jest.Mock
|
|
|
|
beforeEach(() => {
|
|
mockJotaiGet = jest.fn()
|
|
mockJotaiSet = jest.fn()
|
|
})
|
|
|
|
afterEach(() => {
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
describe('stateModel', () => {
|
|
it('should initialize with correct default values', () => {
|
|
expect(ModelAtoms.stateModel.init).toEqual({
|
|
state: 'start',
|
|
loading: false,
|
|
model: '',
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('selectedModelAtom', () => {
|
|
it('should initialize as undefined', () => {
|
|
expect(ModelAtoms.selectedModelAtom.init).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe('showEngineListModelAtom', () => {
|
|
it('should initialize with local engines', () => {
|
|
expect(ModelAtoms.showEngineListModelAtom.init).toEqual([
|
|
'nitro',
|
|
'cortex',
|
|
'llama-cpp',
|
|
'onnxruntime',
|
|
'tensorrt-llm',
|
|
])
|
|
})
|
|
})
|
|
|
|
describe('addDownloadingModelAtom', () => {
|
|
it('should add downloading model', async () => {
|
|
const { result: reset } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.downloadingModelsAtom)
|
|
)
|
|
const { result: setAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.addDownloadingModelAtom)
|
|
)
|
|
const { result: getAtom } = renderHook(() =>
|
|
useAtomValue(ModelAtoms.getDownloadingModelAtom)
|
|
)
|
|
act(() => {
|
|
setAtom.current({ id: '1' } as any)
|
|
})
|
|
expect(getAtom.current).toEqual([{ id: '1' }])
|
|
reset.current([])
|
|
})
|
|
})
|
|
|
|
describe('removeDownloadingModelAtom', () => {
|
|
it('should remove downloading model', async () => {
|
|
const { result: reset } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.downloadingModelsAtom)
|
|
)
|
|
|
|
const { result: setAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.addDownloadingModelAtom)
|
|
)
|
|
const { result: removeAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.removeDownloadingModelAtom)
|
|
)
|
|
const { result: getAtom } = renderHook(() =>
|
|
useAtomValue(ModelAtoms.getDownloadingModelAtom)
|
|
)
|
|
expect(getAtom.current).toEqual([])
|
|
act(() => {
|
|
setAtom.current('1')
|
|
removeAtom.current('1')
|
|
})
|
|
expect(getAtom.current).toEqual([])
|
|
reset.current([])
|
|
})
|
|
})
|
|
|
|
describe('removeDownloadedModelAtom', () => {
|
|
it('should remove downloaded model', async () => {
|
|
const { result: reset } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.downloadingModelsAtom)
|
|
)
|
|
const { result: setAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.downloadedModelsAtom)
|
|
)
|
|
const { result: removeAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.removeDownloadedModelAtom)
|
|
)
|
|
const { result: getAtom } = renderHook(() =>
|
|
useAtomValue(ModelAtoms.downloadedModelsAtom)
|
|
)
|
|
act(() => {
|
|
setAtom.current([{ id: '1' }] as any)
|
|
})
|
|
expect(getAtom.current).toEqual([
|
|
{
|
|
id: '1',
|
|
},
|
|
])
|
|
act(() => {
|
|
removeAtom.current('1')
|
|
})
|
|
expect(getAtom.current).toEqual([])
|
|
reset.current([])
|
|
})
|
|
})
|
|
|
|
describe('importingModelAtom', () => {
|
|
afterEach(() => {
|
|
jest.resetAllMocks()
|
|
jest.clearAllMocks()
|
|
})
|
|
it('should not update for non-existing import', async () => {
|
|
const { result: importAtom } = renderHook(() =>
|
|
useAtom(ModelAtoms.importingModelsAtom)
|
|
)
|
|
const { result: updateAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.updateImportingModelProgressAtom)
|
|
)
|
|
act(() => {
|
|
importAtom.current[1]([])
|
|
updateAtom.current('2', 50)
|
|
})
|
|
expect(importAtom.current[0]).toEqual([])
|
|
})
|
|
it('should update progress for existing import', async () => {
|
|
const { result: importAtom } = renderHook(() =>
|
|
useAtom(ModelAtoms.importingModelsAtom)
|
|
)
|
|
const { result: updateAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.updateImportingModelProgressAtom)
|
|
)
|
|
|
|
act(() => {
|
|
importAtom.current[1]([
|
|
{ importId: '1', status: 'MODEL_SELECTED' },
|
|
] as any)
|
|
updateAtom.current('1', 50)
|
|
})
|
|
expect(importAtom.current[0]).toEqual([
|
|
{
|
|
importId: '1',
|
|
status: 'IMPORTING',
|
|
percentage: 50,
|
|
},
|
|
])
|
|
})
|
|
|
|
it('should not update with invalid data', async () => {
|
|
const { result: importAtom } = renderHook(() =>
|
|
useAtom(ModelAtoms.importingModelsAtom)
|
|
)
|
|
const { result: updateAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.updateImportingModelProgressAtom)
|
|
)
|
|
|
|
act(() => {
|
|
importAtom.current[1]([
|
|
{ importId: '1', status: 'MODEL_SELECTED' },
|
|
] as any)
|
|
updateAtom.current('2', 50)
|
|
})
|
|
expect(importAtom.current[0]).toEqual([
|
|
{
|
|
importId: '1',
|
|
status: 'MODEL_SELECTED',
|
|
},
|
|
])
|
|
})
|
|
it('should update import error', async () => {
|
|
const { result: importAtom } = renderHook(() =>
|
|
useAtom(ModelAtoms.importingModelsAtom)
|
|
)
|
|
const { result: errorAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.setImportingModelErrorAtom)
|
|
)
|
|
act(() => {
|
|
importAtom.current[1]([
|
|
{ importId: '1', status: 'IMPORTING', percentage: 50 },
|
|
] as any)
|
|
errorAtom.current('1', 'unknown')
|
|
})
|
|
expect(importAtom.current[0]).toEqual([
|
|
{
|
|
importId: '1',
|
|
status: 'FAILED',
|
|
percentage: 50,
|
|
},
|
|
])
|
|
})
|
|
it('should not update import error on invalid import ID', async () => {
|
|
const { result: importAtom } = renderHook(() =>
|
|
useAtom(ModelAtoms.importingModelsAtom)
|
|
)
|
|
const { result: errorAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.setImportingModelErrorAtom)
|
|
)
|
|
act(() => {
|
|
importAtom.current[1]([
|
|
{ importId: '1', status: 'IMPORTING', percentage: 50 },
|
|
] as any)
|
|
errorAtom.current('2', 'unknown')
|
|
})
|
|
expect(importAtom.current[0]).toEqual([
|
|
{
|
|
importId: '1',
|
|
status: 'IMPORTING',
|
|
percentage: 50,
|
|
},
|
|
])
|
|
})
|
|
|
|
it('should update import success', async () => {
|
|
const { result: importAtom } = renderHook(() =>
|
|
useAtom(ModelAtoms.importingModelsAtom)
|
|
)
|
|
const { result: successAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.setImportingModelSuccessAtom)
|
|
)
|
|
|
|
act(() => {
|
|
importAtom.current[1]([{ importId: '1', status: 'IMPORTING' }] as any)
|
|
successAtom.current('1', 'id')
|
|
})
|
|
expect(importAtom.current[0]).toEqual([
|
|
{
|
|
importId: '1',
|
|
status: 'IMPORTED',
|
|
percentage: 1,
|
|
modelId: 'id',
|
|
},
|
|
])
|
|
})
|
|
|
|
it('should update with invalid import ID', async () => {
|
|
const { result: importAtom } = renderHook(() =>
|
|
useAtom(ModelAtoms.importingModelsAtom)
|
|
)
|
|
const { result: successAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.setImportingModelSuccessAtom)
|
|
)
|
|
|
|
act(() => {
|
|
importAtom.current[1]([{ importId: '1', status: 'IMPORTING' }] as any)
|
|
successAtom.current('2', 'id')
|
|
})
|
|
expect(importAtom.current[0]).toEqual([
|
|
{
|
|
importId: '1',
|
|
status: 'IMPORTING',
|
|
},
|
|
])
|
|
})
|
|
it('should not update with valid data', async () => {
|
|
const { result: importAtom } = renderHook(() =>
|
|
useAtom(ModelAtoms.importingModelsAtom)
|
|
)
|
|
const { result: updateAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.updateImportingModelAtom)
|
|
)
|
|
|
|
act(() => {
|
|
importAtom.current[1]([
|
|
{ importId: '1', status: 'IMPORTING', percentage: 1 },
|
|
] as any)
|
|
updateAtom.current('1', 'name', 'description', ['tag'])
|
|
})
|
|
expect(importAtom.current[0]).toEqual([
|
|
{
|
|
importId: '1',
|
|
percentage: 1,
|
|
status: 'IMPORTING',
|
|
name: 'name',
|
|
tags: ['tag'],
|
|
description: 'description',
|
|
},
|
|
])
|
|
})
|
|
|
|
it('should not update when there is no importing model', async () => {
|
|
const { result: importAtom } = renderHook(() =>
|
|
useAtom(ModelAtoms.importingModelsAtom)
|
|
)
|
|
const { result: updateAtom } = renderHook(() =>
|
|
useSetAtom(ModelAtoms.updateImportingModelAtom)
|
|
)
|
|
|
|
act(() => {
|
|
importAtom.current[1]([])
|
|
updateAtom.current('1', 'name', 'description', ['tag'])
|
|
})
|
|
expect(importAtom.current[0]).toEqual([])
|
|
})
|
|
})
|
|
})
|