Skip to content

Commit 29daf53

Browse files
bwp91claude
andcommitted
test: cover safe accessory lookups in slow/timeout warnings
Adds two Accessory tests verifying the fix from 03b49f9: when a GET /characteristics or PUT /characteristics request includes an aid.iid that does not resolve to a known accessory or characteristic, the slow-read/slow-write and timeout warning timers must skip the entry rather than crash on `getAccessoryByAID(aid)!.getCharacteristicByIID(iid)!`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0416816 commit 29daf53

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ All notable changes to `@homebridge/hap-nodejs` will be documented in this file.
1414
- test: cover RTP proxy setup rejection handling
1515
- test: cover SEQUENCE_NUM presence check in pair handlers
1616
- test: cover M1 reset prevention in pair-setup
17+
- test: cover safe accessory lookups in slow/timeout warnings
1718

1819
### Homebridge Dependencies
1920

src/lib/Accessory.spec.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,61 @@ describe("Accessory", () => {
12031203
});
12041204
});
12051205

1206+
describe("non-null assertions in accessory lookups (fix 03b49f9f)", () => {
1207+
test("slow read / timeout warning should not crash for unknown aid.iid in request", async () => {
1208+
jest.useFakeTimers({ doNotFake: ["nextTick", "queueMicrotask"] });
1209+
1210+
try {
1211+
// @ts-expect-error: private access
1212+
accessory.handleGetCharacteristics(connection, {
1213+
ids: [
1214+
{ aid: 999, iid: 999 }, // unknown accessory — exercises `!accessory`
1215+
{ aid: aid, iid: 9999 }, // known accessory, unknown iid — exercises `!characteristic`
1216+
],
1217+
includeMeta: false,
1218+
includeEvent: false,
1219+
includeType: false,
1220+
includePerms: false,
1221+
}, callback);
1222+
1223+
// 3s slow read warning fires; without the fix this would throw on
1224+
// `accessory!.getCharacteristicByIID(...)` or `characteristic!.displayName`.
1225+
jest.advanceTimersByTime(3000);
1226+
// 6s later the timeout warning fires and the response is emitted.
1227+
jest.advanceTimersByTime(6000);
1228+
1229+
await callbackPromise;
1230+
expect(callback).toHaveBeenCalledTimes(1);
1231+
// unknown ids are skipped, so the response has no characteristics
1232+
expect(callback.mock.calls[0][1].characteristics).toEqual([]);
1233+
} finally {
1234+
jest.useRealTimers();
1235+
}
1236+
});
1237+
1238+
test("slow write / timeout warning should not crash for unknown aid.iid in request", async () => {
1239+
jest.useFakeTimers({ doNotFake: ["nextTick", "queueMicrotask"] });
1240+
1241+
try {
1242+
// @ts-expect-error: private access
1243+
accessory.handleSetCharacteristics(connection, {
1244+
characteristics: [
1245+
{ aid: 999, iid: 999, value: true },
1246+
{ aid: aid, iid: 9999, value: true },
1247+
],
1248+
}, callback);
1249+
1250+
jest.advanceTimersByTime(3000);
1251+
jest.advanceTimersByTime(6000);
1252+
1253+
await callbackPromise;
1254+
expect(callback).toHaveBeenCalledTimes(1);
1255+
} finally {
1256+
jest.useRealTimers();
1257+
}
1258+
});
1259+
});
1260+
12061261
describe("handleSetCharacteristic", () => {
12071262
let consoleWarnSpy: jest.SpyInstance;
12081263

0 commit comments

Comments
 (0)