fix: 修复 Jest 测试配置和 useCategories hook 实现
- 修复 jest.setup.js 中不存在的 NativeAnimatedHelper 模块引用 - 优化 jest.config.js 配置,分离 js 和 ts/tsx 的转换配置 - 添加 @testing-library/react 依赖 - 导出 useCategoriesStore 以供测试使用 - 修复 useCategories hook 的参数合并逻辑,确保 inputParams 正确覆盖默认参数 - 修复错误处理时 data 状态设置为 null - 更新 CategoriesState 类型定义,允许 data 为 null Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
687cfcf725
commit
a1544ec85f
|
|
@ -9,13 +9,13 @@ import { OWNER_ID } from '@/lib/auth'
|
||||||
import { handleError } from './use-error'
|
import { handleError } from './use-error'
|
||||||
|
|
||||||
interface CategoriesState {
|
interface CategoriesState {
|
||||||
data: ListCategoriesResult | undefined
|
data: ListCategoriesResult | null | undefined
|
||||||
loading: boolean
|
loading: boolean
|
||||||
error: ApiError | null
|
error: ApiError | null
|
||||||
hasLoaded: boolean
|
hasLoaded: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const useCategoriesStore = create<CategoriesState>((set) => ({
|
export const useCategoriesStore = create<CategoriesState>((set) => ({
|
||||||
data: undefined,
|
data: undefined,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null,
|
error: null,
|
||||||
|
|
@ -37,22 +37,26 @@ export const useCategories = (params?: ListCategoriesInput) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setLocalLoading(true)
|
setLocalLoading(true)
|
||||||
|
useCategoriesStore.setState({ loading: true })
|
||||||
const category = root.get(CategoryController)
|
const category = root.get(CategoryController)
|
||||||
const { data, error } = await handleError(
|
|
||||||
async () =>
|
// Merge params: inputParams > params > defaults
|
||||||
await category.list({
|
const mergedParams = {
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 1000,
|
limit: 1000,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
orderBy: 'sortOrder',
|
orderBy: 'sortOrder' as const,
|
||||||
order: 'desc',
|
order: 'desc' as const,
|
||||||
withChildren: true,
|
withChildren: true,
|
||||||
ownerId: OWNER_ID,
|
ownerId: OWNER_ID,
|
||||||
...(inputParams ?? params),
|
...(params ?? {}),
|
||||||
}),
|
...(inputParams ?? {}),
|
||||||
)
|
}
|
||||||
|
|
||||||
|
const { data, error } = await handleError(async () => await category.list(mergedParams))
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
useCategoriesStore.setState({ error, loading: false, hasLoaded: true })
|
useCategoriesStore.setState({ data: null, error, loading: false, hasLoaded: true })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
useCategoriesStore.setState({ data, loading: false, error: null, hasLoaded: true })
|
useCategoriesStore.setState({ data, loading: false, error: null, hasLoaded: true })
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
const { defaults: tsjPresets } = require('ts-jest/presets')
|
|
||||||
|
|
||||||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
preset: 'react-native',
|
preset: 'react-native',
|
||||||
|
|
@ -7,7 +5,14 @@ module.exports = {
|
||||||
'node_modules/(?!(@react-native|react-native|@react-navigation|expo|expo-.*|@expo|@react-native-community|react-native-.*|@shopify|@better-auth|nativewind|react-native-css-interop)/)',
|
'node_modules/(?!(@react-native|react-native|@react-navigation|expo|expo-.*|@expo|@react-native-community|react-native-.*|@shopify|@better-auth|nativewind|react-native-css-interop)/)',
|
||||||
],
|
],
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.(js|jsx|ts|tsx)$': ['ts-jest', tsjPresets.defaults],
|
'^.+\\.(js|jsx)$': 'babel-jest',
|
||||||
|
'^.+\\.(ts|tsx)$': ['ts-jest', {
|
||||||
|
tsconfig: {
|
||||||
|
jsx: 'react',
|
||||||
|
esModuleInterop: true,
|
||||||
|
allowSyntheticDefaultImports: true,
|
||||||
|
},
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
testMatch: ['**/__tests__/**/*.(test|spec).(js|jsx|ts|tsx)', '**/*.(test|spec).(js|jsx|ts|tsx)'],
|
testMatch: ['**/__tests__/**/*.(test|spec).(js|jsx|ts|tsx)', '**/*.(test|spec).(js|jsx|ts|tsx)'],
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
|
||||||
|
|
@ -26,13 +31,4 @@ module.exports = {
|
||||||
'!**/jest.setup.js',
|
'!**/jest.setup.js',
|
||||||
'!**/metro.config.js',
|
'!**/metro.config.js',
|
||||||
],
|
],
|
||||||
globals: {
|
|
||||||
'ts-jest': {
|
|
||||||
tsconfig: {
|
|
||||||
jsx: 'react',
|
|
||||||
esModuleInterop: true,
|
|
||||||
allowSyntheticDefaultImports: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import '@testing-library/jest-native/extend-expect'
|
require('@testing-library/jest-native/extend-expect')
|
||||||
|
|
||||||
// Mock react-native modules
|
// Mock react-native modules
|
||||||
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')
|
// Note: NativeAnimatedHelper may not be needed in newer React Native versions
|
||||||
|
// jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')
|
||||||
|
|
||||||
// Mock expo modules
|
// Mock expo modules
|
||||||
jest.mock('expo-constants', () => ({
|
jest.mock('expo-constants', () => ({
|
||||||
|
|
|
||||||
15
package.json
15
package.json
|
|
@ -87,6 +87,10 @@
|
||||||
"@babel/cli": "^7.28.3",
|
"@babel/cli": "^7.28.3",
|
||||||
"@babel/core": "^7.28.5",
|
"@babel/core": "^7.28.5",
|
||||||
"@babel/preset-env": "^7.28.5",
|
"@babel/preset-env": "^7.28.5",
|
||||||
|
"@testing-library/jest-native": "^5.4.3",
|
||||||
|
"@testing-library/react": "^12.0.0",
|
||||||
|
"@testing-library/react-native": "^12.8.1",
|
||||||
|
"@types/jest": "^29.5.14",
|
||||||
"@types/react": "^19.2.1",
|
"@types/react": "^19.2.1",
|
||||||
"@types/react-native": "^0.72.8",
|
"@types/react-native": "^0.72.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
||||||
|
|
@ -105,16 +109,13 @@
|
||||||
"eslint-plugin-tailwindcss": "^3.18.0",
|
"eslint-plugin-tailwindcss": "^3.18.0",
|
||||||
"eslint-plugin-unicorn": "^59.0.1",
|
"eslint-plugin-unicorn": "^59.0.1",
|
||||||
"eslint-plugin-unused-imports": "^4.1.4",
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
|
"jest": "^29.7.0",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.12",
|
"prettier-plugin-tailwindcss": "^0.6.12",
|
||||||
"tailwindcss": "3.4.4",
|
|
||||||
"typescript": "~5.9.2",
|
|
||||||
"@testing-library/jest-native": "^5.4.3",
|
|
||||||
"@testing-library/react-native": "^12.8.1",
|
|
||||||
"@types/jest": "^29.5.14",
|
|
||||||
"jest": "^29.7.0",
|
|
||||||
"react-test-renderer": "19.1.0",
|
"react-test-renderer": "19.1.0",
|
||||||
"ts-jest": "^29.2.5"
|
"tailwindcss": "3.4.4",
|
||||||
|
"ts-jest": "^29.2.5",
|
||||||
|
"typescript": "~5.9.2"
|
||||||
},
|
},
|
||||||
"private": true
|
"private": true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue