Parcourir la source

chore: add unit test to high frequency hooks (#17617)

tags/1.2.0
Joel il y a 6 mois
Parent
révision
5a6219c726
Aucun compte lié à l'adresse e-mail de l'auteur

+ 90
- 0
web/app/components/header/account-setting/model-provider-page/hooks.spec.ts Voir le fichier

@@ -0,0 +1,90 @@
import { renderHook } from '@testing-library/react'
import { useLanguage } from './hooks'
import { useContext } from 'use-context-selector'
import { after } from 'node:test'

jest.mock('swr', () => ({
__esModule: true,
default: jest.fn(), // mock useSWR
useSWRConfig: jest.fn(),
}))

// mock use-context-selector
jest.mock('use-context-selector', () => ({
useContext: jest.fn(),
}))

// mock service/common functions
jest.mock('@/service/common', () => ({
fetchDefaultModal: jest.fn(),
fetchModelList: jest.fn(),
fetchModelProviderCredentials: jest.fn(),
fetchModelProviders: jest.fn(),
getPayUrl: jest.fn(),
}))

// mock context hooks
jest.mock('@/context/i18n', () => ({
__esModule: true,
default: jest.fn(),
}))

jest.mock('@/context/provider-context', () => ({
useProviderContext: jest.fn(),
}))

jest.mock('@/context/modal-context', () => ({
useModalContextSelector: jest.fn(),
}))

jest.mock('@/context/event-emitter', () => ({
useEventEmitterContextContext: jest.fn(),
}))

// mock plugins
jest.mock('@/app/components/plugins/marketplace/hooks', () => ({
useMarketplacePlugins: jest.fn(),
}))

jest.mock('@/app/components/plugins/marketplace/utils', () => ({
getMarketplacePluginsByCollectionId: jest.fn(),
}))

jest.mock('./provider-added-card', () => {
// eslint-disable-next-line no-labels, ts/no-unused-expressions
UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST: []
})

after(() => {
jest.resetModules()
jest.clearAllMocks()
})

describe('useLanguage', () => {
it('should replace hyphen with underscore in locale', () => {
(useContext as jest.Mock).mockReturnValue({
locale: 'en-US',
})
const { result } = renderHook(() => useLanguage())
expect(result.current).toBe('en_US')
})

it('should return locale as is if no hyphen exists', () => {
(useContext as jest.Mock).mockReturnValue({
locale: 'enUS',
})

const { result } = renderHook(() => useLanguage())
expect(result.current).toBe('enUS')
})

it('should handle multiple hyphens', () => {
// Mock the I18n context return value
(useContext as jest.Mock).mockReturnValue({
locale: 'zh-Hans-CN',
})

const { result } = renderHook(() => useLanguage())
expect(result.current).toBe('zh_Hans-CN')
})
})

+ 93
- 0
web/hooks/use-breakpoints.spec.ts Voir le fichier

@@ -0,0 +1,93 @@
import { act, renderHook } from '@testing-library/react'
import useBreakpoints, { MediaType } from './use-breakpoints'

describe('useBreakpoints', () => {
const originalInnerWidth = window.innerWidth

// Mock the window resize event
const fireResize = (width: number) => {
window.innerWidth = width
act(() => {
window.dispatchEvent(new Event('resize'))
})
}

// Restore the original innerWidth after tests
afterAll(() => {
window.innerWidth = originalInnerWidth
})

it('should return mobile for width <= 640px', () => {
// Mock window.innerWidth for mobile
Object.defineProperty(window, 'innerWidth', {
writable: true,
configurable: true,
value: 640,
})

const { result } = renderHook(() => useBreakpoints())
expect(result.current).toBe(MediaType.mobile)
})

it('should return tablet for width > 640px and <= 768px', () => {
// Mock window.innerWidth for tablet
Object.defineProperty(window, 'innerWidth', {
writable: true,
configurable: true,
value: 768,
})

const { result } = renderHook(() => useBreakpoints())
expect(result.current).toBe(MediaType.tablet)
})

it('should return pc for width > 768px', () => {
// Mock window.innerWidth for pc
Object.defineProperty(window, 'innerWidth', {
writable: true,
configurable: true,
value: 1024,
})

const { result } = renderHook(() => useBreakpoints())
expect(result.current).toBe(MediaType.pc)
})

it('should update media type when window resizes', () => {
// Start with desktop
Object.defineProperty(window, 'innerWidth', {
writable: true,
configurable: true,
value: 1024,
})

const { result } = renderHook(() => useBreakpoints())
expect(result.current).toBe(MediaType.pc)

// Resize to tablet
fireResize(768)
expect(result.current).toBe(MediaType.tablet)

// Resize to mobile
fireResize(600)
expect(result.current).toBe(MediaType.mobile)
})

it('should clean up event listeners on unmount', () => {
// Spy on addEventListener and removeEventListener
const addEventListenerSpy = jest.spyOn(window, 'addEventListener')
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener')

const { unmount } = renderHook(() => useBreakpoints())

// Unmount should trigger cleanup
unmount()

expect(addEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function))
expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function))

// Clean up spies
addEventListenerSpy.mockRestore()
removeEventListenerSpy.mockRestore()
})
})

+ 2
- 2
web/jest.config.ts Voir le fichier

@@ -98,7 +98,7 @@ const config: Config = {

// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
moduleNameMapper: {
'^@/components/(.*)$': '<rootDir>/components/$1',
'^@/(.*)$': '<rootDir>/$1',
'^lodash-es$': 'lodash',
},

@@ -133,7 +133,7 @@ const config: Config = {
// restoreMocks: false,

// The root directory that Jest should scan for tests and modules within
// rootDir: undefined,
rootDir: './',

// A list of paths to directories that Jest should use to search for files in
// roots: [

Chargement…
Annuler
Enregistrer