refactor(core): distinguish network errors from auth failures and refactor real-time messaging pipeline
- Add isNetworkError() helper and FetchCurrentUserResult discriminated union to prevent logout on network failures
- Refactor authService to return { kind: 'user' } | { kind: 'auth_failed' } | { kind: 'network_error' }
- Update authStore to preserve login state on network errors, only logout on auth failures
- Replace WSMessageHandler with RealtimeIngestionPipeline for improved real-time message handling
- Remove MessageDeduplication service; add store-level idempotent addOrReplaceMessage for message dedup
- Add atomic systemUnreadCount operations to prevent race conditions
- Add SearchHeader component for consistent search UI across screens
- Add 'home' TabBar variant with underline style matching HomeScreen
- Add Jest test infrastructure and exclude tests from tsconfig
- Fix ChatScreen history lock being stuck when scrolling to latest messages
- Remove unused call_participant_joined/left WS event types
This commit is contained in:
46
jest.config.js
Normal file
46
jest.config.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Jest 配置
|
||||
*
|
||||
* 仅对消息状态核心逻辑(store 幂等性 / 实时事件管道 / 未读计数原子性)做单测,
|
||||
* 不覆盖 RN / Expo UI。所有平台依赖(@/services/core、@/database、@/core/events、
|
||||
* @/stores/auth、@/services/message)在测试中通过 moduleNameMapper 映射到 mock。
|
||||
*/
|
||||
const { pathsToModuleNameMapper } = require('ts-jest');
|
||||
|
||||
const tsconfig = require('./tsconfig.json');
|
||||
const tsconfigBase = require('expo/tsconfig.base.json');
|
||||
|
||||
// 合并 base + 项目 paths
|
||||
const paths = {
|
||||
...(tsconfigBase.compilerOptions.paths || {}),
|
||||
...(tsconfig.compilerOptions.paths || {}),
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
roots: ['<rootDir>/src'],
|
||||
testMatch: ['**/__tests__/**/*.test.ts'],
|
||||
moduleNameMapper: {
|
||||
// 平台依赖统一映射到 mock(必须放在 @/* 通配之前,否则会被通配吞掉)
|
||||
'^@/services/core$': '<rootDir>/src/stores/message/__tests__/mocks/coreMock.ts',
|
||||
'^@/services/message$': '<rootDir>/src/stores/message/__tests__/mocks/messageServiceMock.ts',
|
||||
'^@/database$': '<rootDir>/src/stores/message/__tests__/mocks/databaseMock.ts',
|
||||
'^@/core/events/EventBus$': '<rootDir>/src/stores/message/__tests__/mocks/eventBusMock.ts',
|
||||
'^@/stores/auth/authStore$': '<rootDir>/src/stores/message/__tests__/mocks/authStoreMock.ts',
|
||||
'^@react-native-async-storage/async-storage$':
|
||||
'<rootDir>/src/stores/message/__tests__/mocks/asyncStorageMock.ts',
|
||||
// @/* 路径别名 → 真实 src(通配兜底,放最后)
|
||||
...pathsToModuleNameMapper(paths, { prefix: '<rootDir>/' }),
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.tsx?$': [
|
||||
'ts-jest',
|
||||
{
|
||||
tsconfig: '<rootDir>/src/stores/message/__tests__/tsconfig.json',
|
||||
isolatedModules: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
clearMocks: true,
|
||||
};
|
||||
Reference in New Issue
Block a user