forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathzero-value.test.ts
More file actions
135 lines (116 loc) · 4.18 KB
/
Copy pathzero-value.test.ts
File metadata and controls
135 lines (116 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* Regression tests for issue #12979:
* A valid zero-valued BLE characteristic must not be treated as absent.
*
* - getAudioCodec() with codec byte 0x00 must report PCM16 (codec id 0), not PCM8
* - getBatteryLevel() with battery byte 0x00 must report 0, not -1
* - Missing/empty characteristic payloads must still fall back as before.
*/
jest.mock('react-native', () => ({
Platform: { OS: 'ios' },
}));
type AnyChar = { uuid: string; read: jest.Mock };
let mockBleManagerImpl: Record<string, unknown> = {};
jest.mock('react-native-ble-plx', () => ({
BleManager: jest.fn().mockImplementation(function BleManagerMock() {
return { ...mockBleManagerImpl };
}),
Subscription: jest.fn(),
Device: jest.fn(),
}));
import { OmiConnection } from '../OmiConnection';
import { BleAudioCodec } from '../types';
const OMI_SERVICE_UUID = '19b10000-e8f2-537e-4f6c-d104768a1214';
const AUDIO_CODEC_CHARACTERISTIC_UUID = '19b10002-e8f2-537e-4f6c-d104768a1214';
const BATTERY_SERVICE_UUID = '0000180f-0000-1000-8000-00805f9b34fb';
const BATTERY_LEVEL_CHARACTERISTIC_UUID = '00002a19-0000-1000-8000-00805f9b34fb';
const zeroByteBase64 = Buffer.from([0x00]).toString('base64'); // "AA=="
function makeCharacteristic(uuid: string, base64: string): AnyChar {
return {
uuid,
read: jest.fn(() => Promise.resolve({ value: base64 })),
};
}
/**
* Install a fake Device with the requested service/characteristic tree and
* make `new BleManager().connectToDevice()` return it.
*/
function installFakeDevice(serviceToChars: Record<string, AnyChar[]>) {
const device = {
id: 'test-device-id',
name: 'Test Device',
discoverAllServicesAndCharacteristics: jest.fn(() => Promise.resolve()),
services: jest.fn(() =>
Promise.resolve(
Object.entries(serviceToChars).map(([uuid, chars]) => ({
uuid,
characteristics: () => Promise.resolve(chars),
}))
)
),
cancelConnection: jest.fn(() => Promise.resolve()),
onDisconnected: jest.fn(() => ({ remove: jest.fn() })),
};
mockBleManagerImpl = {
startDeviceScan: jest.fn(),
stopDeviceScan: jest.fn(),
connectToDevice: jest.fn(() => Promise.resolve(device)),
state: jest.fn(() => Promise.resolve('PoweredOn')),
};
return device;
}
async function connectedConnection(): Promise<OmiConnection> {
const conn = new OmiConnection();
const ok = await conn.connect('test-device-id');
expect(ok).toBe(true);
return conn;
}
describe('zero-valued BLE characteristic readings (issue #12979)', () => {
afterEach(() => {
jest.clearAllMocks();
mockBleManagerImpl = {};
});
it('reports PCM16 when the codec byte is 0 instead of falling back to PCM8', async () => {
installFakeDevice({
[OMI_SERVICE_UUID]: [
makeCharacteristic(AUDIO_CODEC_CHARACTERISTIC_UUID, zeroByteBase64),
],
});
const conn = await connectedConnection();
await expect(conn.getAudioCodec()).resolves.toBe(BleAudioCodec.PCM16);
});
it('reports battery level 0 instead of -1 when the battery byte is 0', async () => {
installFakeDevice({
[BATTERY_SERVICE_UUID]: [
makeCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID, zeroByteBase64),
],
});
const conn = await connectedConnection();
await expect(conn.getBatteryLevel()).resolves.toBe(0);
});
it('still falls back when the characteristic payload is empty', async () => {
installFakeDevice({
[OMI_SERVICE_UUID]: [
makeCharacteristic(AUDIO_CODEC_CHARACTERISTIC_UUID, ''),
],
[BATTERY_SERVICE_UUID]: [
makeCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID, ''),
],
});
const conn = await connectedConnection();
await expect(conn.getAudioCodec()).resolves.toBe(BleAudioCodec.PCM8);
await expect(conn.getBatteryLevel()).resolves.toBe(-1);
});
it('still maps non-zero codec ids unchanged (no behavior regression)', async () => {
installFakeDevice({
[OMI_SERVICE_UUID]: [
makeCharacteristic(
AUDIO_CODEC_CHARACTERISTIC_UUID,
Buffer.from([20]).toString('base64')
),
],
});
const conn = await connectedConnection();
await expect(conn.getAudioCodec()).resolves.toBe(BleAudioCodec.OPUS);
});
});