Skip to content

Commit ecf4ae1

Browse files
committed
feat: 修改msg错误以及routerweb下没有在特定位置return,以及一些其他问题
1 parent a9977b0 commit ecf4ae1

25 files changed

Lines changed: 483 additions & 29 deletions

File tree

.agents/skills/mpx2rn/references/rn-api-reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1730,7 +1730,7 @@ mpx.config.rnConfig.bluetoothPermission = () => {
17301730
| `stopWifi` | 结束 Wi‑Fi 模块并清空列表监听;RN iOS 目标直接走 `fail`| RN Android 成功时为 `{ errMsg: 'stopWifi:ok' }`|
17311731
| `getWifiList` | `startWifi` 就绪后扫描热点,通过 `onGetWifiList` 交付列表;RN iOS 目标直接走 `fail`| `success``{ errMsg: 'getWifiList:ok', errno: 0, errCode: 0 }`;热点列表不在此载荷中。 |
17321732
| `onGetWifiList` | 注册接收热点列表的回调。 | `{ wifiList }`;每项含 `SSID``BSSID``frequency``signalStrength`|
1733-
| `offGetWifiList` | 移除热点列表回调。 | 传入与注册时同一 `callback`当前实现不支持省略参数清空全部|
1733+
| `offGetWifiList` | 移除热点列表回调。 | 传入与注册时同一 `callback`省略参数清空全部|
17341734
| `getConnectedWifi` | 读取当前已连接 Wi‑Fi;支持 `partialInfo`,且需先 `startWifi` 成功就绪。 | `{ errMsg: 'getConnectedWifi:ok', wifi }``wifi``SSID``BSSID``signalStrength``frequency`|
17351735

17361736
Wi-Fi API 的成功 `errMsg` 与微信文档保持一致,均以 `:ok` 结尾。
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { ENV_OBJ } from '../../src/common/js'
2+
import { setNavigationBarTitle } from '../../src/platform/api/set-navigation-bar/index.ali'
3+
4+
jest.mock('../../src/common/js/index', () => {
5+
const actual = jest.requireActual('../../src/common/js/index')
6+
return Object.assign({}, actual, {
7+
ENV_OBJ: {
8+
canIUse: jest.fn(() => true),
9+
setNavigationBarTitle: jest.fn()
10+
}
11+
})
12+
})
13+
14+
describe('Ali setNavigationBarTitle', () => {
15+
test('should normalize the success errMsg', () => {
16+
const success = jest.fn()
17+
ENV_OBJ.setNavigationBarTitle.mockImplementation(({ success }) => {
18+
success({})
19+
})
20+
21+
setNavigationBarTitle({
22+
title: 'title',
23+
success
24+
})
25+
26+
expect(success).toHaveBeenCalledWith({
27+
errMsg: 'setNavigationBarTitle:ok'
28+
})
29+
})
30+
})

packages/api-proxy/__tests__/rn/ble-connection.spec.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,18 @@ describe('RN BLE connection APIs', () => {
109109
}))
110110
expect(BleManager.requestMTU).not.toHaveBeenCalled()
111111
})
112+
113+
test.each([false, 0, ''])('generic parameter check should reject invalid value %p', (value) => {
114+
const fail = jest.fn()
115+
const complete = jest.fn()
116+
117+
getBLEDeviceRSSI({ deviceId: value, fail, complete })
118+
119+
expect(fail).toHaveBeenCalledWith({
120+
errMsg: 'getBLEDeviceRSSI:fail parameter error',
121+
errno: 1509000
122+
})
123+
expect(complete).toHaveBeenCalled()
124+
expect(BleManager.readRSSI).not.toHaveBeenCalled()
125+
})
112126
})
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import CameraContext from '../../src/platform/api/camera/rnCamera'
2+
3+
describe('RN CameraContext', () => {
4+
test('setZoom should invoke fail only when the native method throws', () => {
5+
const cameraContext = new CameraContext()
6+
const success = jest.fn()
7+
const fail = jest.fn()
8+
const complete = jest.fn()
9+
cameraContext.camera = {
10+
setZoom: jest.fn(() => {
11+
throw new Error('set zoom failed')
12+
})
13+
}
14+
15+
cameraContext.setZoom({
16+
zoom: 2,
17+
success,
18+
fail,
19+
complete
20+
})
21+
22+
expect(cameraContext.camera.setZoom).toHaveBeenCalledWith(2)
23+
expect(success).not.toHaveBeenCalled()
24+
expect(fail).toHaveBeenCalledWith({
25+
errMsg: 'setZoom:fail set zoom failed'
26+
})
27+
expect(complete).toHaveBeenCalledTimes(1)
28+
expect(complete).toHaveBeenCalledWith({
29+
errMsg: 'setZoom:fail set zoom failed'
30+
})
31+
})
32+
})

packages/api-proxy/__tests__/rn/keyboard.spec.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@ const mockAddListener = jest.fn(eventName => {
99
return subscription
1010
})
1111
const mockRemoveAllListeners = jest.fn()
12+
const mockDismiss = jest.fn()
1213

1314
jest.mock('react-native', () => ({
1415
Keyboard: {
1516
addListener: mockAddListener,
16-
removeAllListeners: mockRemoveAllListeners
17+
removeAllListeners: mockRemoveAllListeners,
18+
dismiss: mockDismiss
1719
}
1820
}), { virtual: true })
1921

2022
const {
2123
onKeyboardHeightChange,
22-
offKeyboardHeightChange
24+
offKeyboardHeightChange,
25+
hideKeyboard
2326
} = require('../../src/platform/api/keyboard/index.ios')
2427

2528
describe('RN keyboard', () => {
@@ -28,6 +31,7 @@ describe('RN keyboard', () => {
2831
mockSubscriptions.length = 0
2932
mockAddListener.mockClear()
3033
mockRemoveAllListeners.mockClear()
34+
mockDismiss.mockReset()
3135
})
3236

3337
it('should only remove owned subscriptions when called without callback', () => {
@@ -66,4 +70,23 @@ describe('RN keyboard', () => {
6670
// 首轮订阅释放后再次注册,需要重新创建两个底层订阅。
6771
expect(mockAddListener).toHaveBeenCalledTimes(4)
6872
})
73+
74+
it('should include the API name in the hideKeyboard fail errMsg', () => {
75+
const fail = jest.fn()
76+
const complete = jest.fn()
77+
mockDismiss.mockImplementation(() => {
78+
throw new Error('dismiss failed')
79+
})
80+
81+
hideKeyboard({
82+
fail,
83+
complete
84+
})
85+
86+
const result = {
87+
errMsg: 'hideKeyboard:fail dismiss failed'
88+
}
89+
expect(fail).toHaveBeenCalledWith(result)
90+
expect(complete).toHaveBeenCalledWith(result)
91+
})
6992
})

packages/api-proxy/__tests__/rn/network.spec.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,27 @@ jest.mock('@react-native-community/netinfo', () => ({
1414
}
1515
}), { virtual: true })
1616

17+
jest.mock('../../src/common/js', () => ({
18+
successHandle: jest.fn(),
19+
failHandle: jest.fn(),
20+
defineUnsupportedProps: jest.fn()
21+
}))
22+
1723
const {
24+
getNetworkType,
1825
offNetworkStatusChange,
1926
onNetworkStatusChange
2027
} = require('../../src/platform/api/device/network/rnNetwork')
28+
const NetInfo = require('@react-native-community/netinfo').default
29+
const { failHandle } = require('../../src/common/js')
2130

2231
describe('RN network events', () => {
2332
beforeEach(() => {
2433
offNetworkStatusChange()
2534
mockAddEventListener.mockClear()
2635
mockUnsubscribe.mockClear()
36+
NetInfo.fetch.mockReset()
37+
failHandle.mockClear()
2738
})
2839

2940
test('should clear callbacks and native subscription when callback is null', () => {
@@ -35,6 +46,19 @@ describe('RN network events', () => {
3546
expect(mockUnsubscribe).toHaveBeenCalledTimes(1)
3647
})
3748

49+
test('should release native subscription after the last callback is removed', () => {
50+
const callbackA = jest.fn()
51+
const callbackB = jest.fn()
52+
onNetworkStatusChange(callbackA)
53+
onNetworkStatusChange(callbackB)
54+
55+
offNetworkStatusChange(callbackA)
56+
expect(mockUnsubscribe).not.toHaveBeenCalled()
57+
58+
offNetworkStatusChange(callbackB)
59+
expect(mockUnsubscribe).toHaveBeenCalledTimes(1)
60+
})
61+
3862
test('should subscribe again after all callbacks are removed', () => {
3963
onNetworkStatusChange(jest.fn())
4064
offNetworkStatusChange()
@@ -44,4 +68,18 @@ describe('RN network events', () => {
4468

4569
expect(mockAddEventListener).toHaveBeenCalledTimes(2)
4670
})
71+
72+
test('getNetworkType should include API name when fetching fails', async () => {
73+
const fail = jest.fn()
74+
const complete = jest.fn()
75+
NetInfo.fetch.mockRejectedValue(new Error('fetch failed'))
76+
77+
getNetworkType({ fail, complete })
78+
await Promise.resolve()
79+
await Promise.resolve()
80+
81+
expect(failHandle).toHaveBeenCalledWith({
82+
errMsg: 'getNetworkType:fail fetch failed'
83+
}, fail, complete)
84+
})
4785
})

packages/api-proxy/__tests__/rn/storage.spec.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import AsyncStorage from '@react-native-async-storage/async-storage'
2-
import { removeStorageSync, clearStorageSync } from '../../src/platform/api/storage/rnStorage'
2+
import { getStorageInfo, removeStorageSync, clearStorageSync } from '../../src/platform/api/storage/rnStorage'
33

44
jest.mock('@react-native-async-storage/async-storage', () => ({
5+
getAllKeys: jest.fn(),
56
removeItem: jest.fn(),
67
clear: jest.fn()
78
}), { virtual: true })
@@ -28,4 +29,22 @@ describe('RN storage APIs', () => {
2829
expect(AsyncStorage.removeItem).not.toHaveBeenCalled()
2930
expect(AsyncStorage.clear).not.toHaveBeenCalled()
3031
})
32+
33+
test('getStorageInfo should use the correct API name when it fails', () => {
34+
const error = new Error('get keys failed')
35+
const fail = jest.fn()
36+
const complete = jest.fn()
37+
AsyncStorage.getAllKeys.mockImplementation(callback => callback(error))
38+
39+
getStorageInfo({
40+
fail,
41+
complete
42+
})
43+
44+
const result = {
45+
errMsg: 'getStorageInfo:fail Error: get keys failed'
46+
}
47+
expect(fail).toHaveBeenCalledWith(result)
48+
expect(complete).toHaveBeenCalledWith(result)
49+
})
3150
})

packages/api-proxy/__tests__/rn/toast.spec.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import Portal from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-portal/index'
22
import { showToast, showLoading } from '../../src/platform/api/toast/rnToast'
33

4+
jest.mock('react/jsx-runtime', () => ({
5+
jsx: (type, props) => ({ type, props }),
6+
jsxs: (type, props) => ({ type, props }),
7+
Fragment: 'Fragment'
8+
}), { virtual: true })
9+
410
jest.mock('react-native', () => ({
511
View: 'View',
612
Text: 'Text',
@@ -17,7 +23,7 @@ jest.mock('react-native', () => ({
1723
jest.mock('@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-portal/index', () => ({
1824
add: jest.fn(),
1925
remove: jest.fn()
20-
}))
26+
}), { virtual: true })
2127

2228
describe('RN toast APIs', () => {
2329
test.each([

0 commit comments

Comments
 (0)