@homebridge-plugins/homebridge-august 3.1.0 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/.github/scripts/npm-version-script-esm-auto.js +201 -0
  2. package/.github/scripts/resolve-version-bump-esm.js +118 -0
  3. package/.github/workflows/release.yml +62 -13
  4. package/CHANGELOG.md +9 -2
  5. package/dist/devices/device.d.ts +1 -0
  6. package/dist/devices/device.d.ts.map +1 -1
  7. package/dist/devices/device.js +6 -4
  8. package/dist/devices/device.js.map +1 -1
  9. package/dist/devices/lock.js +2 -2
  10. package/dist/devices/lock.js.map +1 -1
  11. package/dist/homebridge-ui/server.js.map +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +2 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/package.json +6 -7
  16. package/dist/platform.d.ts +1 -1
  17. package/dist/platform.d.ts.map +1 -1
  18. package/dist/platform.js +2 -9
  19. package/dist/platform.js.map +1 -1
  20. package/dist/platform.matter.d.ts +45 -0
  21. package/dist/platform.matter.d.ts.map +1 -1
  22. package/dist/platform.matter.js +120 -65
  23. package/dist/platform.matter.js.map +1 -1
  24. package/dist/settings.d.ts +4 -4
  25. package/dist/settings.d.ts.map +1 -1
  26. package/docs/variables/default.html +1 -1
  27. package/package.json +6 -7
  28. package/typedoc.json +1 -1
  29. package/dist/devices/device.test.d.ts +0 -2
  30. package/dist/devices/device.test.d.ts.map +0 -1
  31. package/dist/devices/device.test.js +0 -281
  32. package/dist/devices/device.test.js.map +0 -1
  33. package/dist/devices/lock.test.d.ts +0 -2
  34. package/dist/devices/lock.test.d.ts.map +0 -1
  35. package/dist/devices/lock.test.js +0 -265
  36. package/dist/devices/lock.test.js.map +0 -1
  37. package/dist/index.test.d.ts +0 -2
  38. package/dist/index.test.d.ts.map +0 -1
  39. package/dist/index.test.js +0 -97
  40. package/dist/index.test.js.map +0 -1
  41. package/dist/platform.matter.test.d.ts +0 -2
  42. package/dist/platform.matter.test.d.ts.map +0 -1
  43. package/dist/platform.matter.test.js +0 -385
  44. package/dist/platform.matter.test.js.map +0 -1
  45. package/dist/platform.test.d.ts +0 -2
  46. package/dist/platform.test.d.ts.map +0 -1
  47. package/dist/platform.test.js +0 -514
  48. package/dist/platform.test.js.map +0 -1
  49. package/dist/settings.test.d.ts +0 -2
  50. package/dist/settings.test.d.ts.map +0 -1
  51. package/dist/settings.test.js +0 -138
  52. package/dist/settings.test.js.map +0 -1
@@ -1,281 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from 'vitest';
2
- // Create a simplified test implementation that mimics the updateCharacteristic behavior
3
- class MockDeviceWithCharacteristics {
4
- accessory = { context: {}, displayName: 'Test Lock' };
5
- debugLog = vi.fn();
6
- debugWarnLog = vi.fn();
7
- infoLog = vi.fn();
8
- async updateCharacteristic(Service, ServiceName, Characteristic, CharacteristicValue, CharacteristicName, Value, StatusMatch, StatusDoesNotMatch) {
9
- if (CharacteristicValue === undefined) {
10
- await this.debugLog(`${CharacteristicName}: ${CharacteristicValue}`);
11
- }
12
- else {
13
- const contextKey = `${ServiceName}${CharacteristicName}`;
14
- await this.debugWarnLog(`context before: ${this.accessory.context[contextKey]}`);
15
- const contextBefore = this.accessory.context[contextKey];
16
- this.accessory.context[contextKey] = CharacteristicValue;
17
- await this.debugWarnLog(`context after: ${this.accessory.context[contextKey]}`);
18
- await this.debugLog(`updateCharacteristic ${CharacteristicName}: ${CharacteristicValue} (${CharacteristicValue === Value ? StatusMatch : StatusDoesNotMatch})`);
19
- if (contextBefore !== CharacteristicValue) {
20
- // Value actually changed - push update to HomeKit
21
- Service.updateCharacteristic(Characteristic, CharacteristicValue);
22
- // Only log state change messages when we had a prior known value (not initial discovery)
23
- if (contextBefore !== undefined && StatusMatch && StatusDoesNotMatch) {
24
- await this.infoLog(`was ${CharacteristicValue === Value ? StatusMatch : StatusDoesNotMatch}`);
25
- }
26
- }
27
- }
28
- }
29
- }
30
- // Create a simplified test implementation that mimics the statusCode behavior
31
- class MockDevice {
32
- debugLog = vi.fn();
33
- debugErrorLog = vi.fn();
34
- /**
35
- * Check if error is a network timeout or session expiration that requires session refresh
36
- * Handles 502 Bad Gateway, 401 Unauthorized, 503 Service Unavailable, and network timeouts
37
- */
38
- isTimeoutError(error) {
39
- // Check for network timeout errors
40
- if (error.message && error.message.includes('ETIMEDOUT')) {
41
- return true;
42
- }
43
- // Check for status codes that indicate session expiration or temporary server issues
44
- // 502 Bad Gateway - typically indicates session has expired or server issues
45
- // 503 Service Unavailable - temporary server issues
46
- // 401 Unauthorized - session has expired
47
- if (error.statusCode && (error.statusCode === 502 || error.statusCode === 503 || error.statusCode === 401)) {
48
- return true;
49
- }
50
- // Check for error messages containing these status codes (from tiny-json-http error format)
51
- // Format: "POST failed with: 502" or "GET failed with: 401"
52
- if (error.message) {
53
- const sessionErrorPatterns = [
54
- /failed with: 502/i,
55
- /failed with: 503/i,
56
- /failed with: 401/i,
57
- /Bad Gateway/i,
58
- /Service Unavailable/i,
59
- /Unauthorized/i,
60
- ];
61
- return sessionErrorPatterns.some(pattern => pattern.test(error.message));
62
- }
63
- return false;
64
- }
65
- async statusCode(action, error) {
66
- const statusCodeString = error.message || ''; // Convert statusCode to a string, handle undefined/null
67
- // Check if the error is an AggregateError or doesn't contain a status code
68
- if (error.constructor?.name === 'AggregateError' || !/^\d{3}/.test(statusCodeString)) {
69
- await this.debugErrorLog(`${action} failed with ${error.constructor?.name || 'Error'}: ${statusCodeString}`);
70
- return;
71
- }
72
- const statusCode = statusCodeString.slice(0, 3);
73
- const logMap = {
74
- 100: `Command successfully sent, statusCode: ${statusCodeString}`,
75
- 200: `Request successful, statusCode: ${statusCodeString}`,
76
- 400: `Bad Request, statusCode: ${statusCodeString}`,
77
- 429: `Too Many Requests, exceeded the number of requests allowed for a given time window, statusCode: ${statusCodeString}`,
78
- };
79
- const logMessage = logMap[statusCode]
80
- ?? `Unknown statusCode: ${statusCodeString}, Submit Bugs Here: https://tinyurl.com/AugustYaleBug`;
81
- await this.debugLog(logMessage);
82
- if (!logMap[statusCode]) {
83
- await this.debugErrorLog(`failed ${action}, Error: ${error}`);
84
- }
85
- }
86
- }
87
- describe('statusCode error handling', () => {
88
- let mockDevice;
89
- beforeEach(() => {
90
- mockDevice = new MockDevice();
91
- });
92
- describe('isTimeoutError method', () => {
93
- it('should detect ETIMEDOUT network errors', () => {
94
- const error = { message: 'ETIMEDOUT connection timed out' };
95
- expect(mockDevice.isTimeoutError(error)).toBe(true);
96
- });
97
- it('should detect 502 Bad Gateway status code', () => {
98
- const error = { message: 'POST failed with: 502', statusCode: 502 };
99
- expect(mockDevice.isTimeoutError(error)).toBe(true);
100
- });
101
- it('should detect 502 in error message', () => {
102
- const error = { message: 'POST failed with: 502' };
103
- expect(mockDevice.isTimeoutError(error)).toBe(true);
104
- });
105
- it('should detect 503 Service Unavailable status code', () => {
106
- const error = { message: 'GET failed with: 503', statusCode: 503 };
107
- expect(mockDevice.isTimeoutError(error)).toBe(true);
108
- });
109
- it('should detect 503 in error message', () => {
110
- const error = { message: 'Service Unavailable' };
111
- expect(mockDevice.isTimeoutError(error)).toBe(true);
112
- });
113
- it('should detect 401 Unauthorized status code', () => {
114
- const error = { message: 'POST failed with: 401', statusCode: 401 };
115
- expect(mockDevice.isTimeoutError(error)).toBe(true);
116
- });
117
- it('should detect 401 in error message', () => {
118
- const error = { message: 'Unauthorized access' };
119
- expect(mockDevice.isTimeoutError(error)).toBe(true);
120
- });
121
- it('should detect Bad Gateway in error message', () => {
122
- const error = { message: 'Bad Gateway' };
123
- expect(mockDevice.isTimeoutError(error)).toBe(true);
124
- });
125
- it('should return false for non-timeout errors', () => {
126
- const error = { message: '404 Not Found' };
127
- expect(mockDevice.isTimeoutError(error)).toBe(false);
128
- });
129
- it('should return false for 400 Bad Request', () => {
130
- const error = { message: '400 Bad Request', statusCode: 400 };
131
- expect(mockDevice.isTimeoutError(error)).toBe(false);
132
- });
133
- it('should return false for 429 Too Many Requests', () => {
134
- const error = { message: '429 Too Many Requests', statusCode: 429 };
135
- expect(mockDevice.isTimeoutError(error)).toBe(false);
136
- });
137
- it('should return false for empty message', () => {
138
- const error = { message: '' };
139
- expect(mockDevice.isTimeoutError(error)).toBe(false);
140
- });
141
- it('should not match 401 in non-HTTP status contexts', () => {
142
- const error = { message: 'Expected 4012 records but found 401' };
143
- expect(mockDevice.isTimeoutError(error)).toBe(false);
144
- });
145
- it('should not match 502 in non-HTTP status contexts', () => {
146
- const error = { message: 'Lock ID 50234 not found' };
147
- expect(mockDevice.isTimeoutError(error)).toBe(false);
148
- });
149
- });
150
- describe('statusCode method', () => {
151
- it('should handle standard HTTP status codes', async () => {
152
- await mockDevice.statusCode('test action', { message: '400 Bad Request' });
153
- expect(mockDevice.debugLog).toHaveBeenCalledWith('Bad Request, statusCode: 400 Bad Request');
154
- expect(mockDevice.debugErrorLog).not.toHaveBeenCalled();
155
- });
156
- it('should handle AggregateError specifically', async () => {
157
- await mockDevice.statusCode('refreshStatus', {
158
- message: 'Multiple errors occurred',
159
- constructor: { name: 'AggregateError' },
160
- });
161
- expect(mockDevice.debugErrorLog).toHaveBeenCalledWith('refreshStatus failed with AggregateError: Multiple errors occurred');
162
- expect(mockDevice.debugLog).not.toHaveBeenCalled();
163
- });
164
- it('should handle error with empty message', async () => {
165
- await mockDevice.statusCode('refreshStatus', { message: '' });
166
- expect(mockDevice.debugErrorLog).toHaveBeenCalledWith('refreshStatus failed with Object: ');
167
- expect(mockDevice.debugLog).not.toHaveBeenCalled();
168
- });
169
- it('should handle error message without numeric status code', async () => {
170
- await mockDevice.statusCode('refreshStatus', { message: 'Network connection failed' });
171
- expect(mockDevice.debugErrorLog).toHaveBeenCalledWith('refreshStatus failed with Object: Network connection failed');
172
- expect(mockDevice.debugLog).not.toHaveBeenCalled();
173
- });
174
- it('should handle 429 Too Many Requests status code', async () => {
175
- await mockDevice.statusCode('test action', { message: '429 Too Many Requests' });
176
- expect(mockDevice.debugLog).toHaveBeenCalledWith('Too Many Requests, exceeded the number of requests allowed for a given time window, statusCode: 429 Too Many Requests');
177
- expect(mockDevice.debugErrorLog).not.toHaveBeenCalled();
178
- });
179
- it('should handle unknown numeric status codes', async () => {
180
- await mockDevice.statusCode('test action', { message: '503 Service Unavailable' });
181
- expect(mockDevice.debugLog).toHaveBeenCalledWith('Unknown statusCode: 503 Service Unavailable, Submit Bugs Here: https://tinyurl.com/AugustYaleBug');
182
- expect(mockDevice.debugErrorLog).toHaveBeenCalledWith('failed test action, Error: [object Object]');
183
- });
184
- });
185
- });
186
- describe('updateCharacteristic', () => {
187
- let device;
188
- let mockService;
189
- const CHARACTERISTIC = 'LockCurrentState';
190
- beforeEach(() => {
191
- device = new MockDeviceWithCharacteristics();
192
- mockService = {
193
- updateCharacteristic: vi.fn(),
194
- };
195
- });
196
- it('should skip HomeKit update when CharacteristicValue is undefined', async () => {
197
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, undefined, 'LockCurrentState');
198
- expect(mockService.updateCharacteristic).not.toHaveBeenCalled();
199
- expect(device.debugLog).toHaveBeenCalledWith('LockCurrentState: undefined');
200
- });
201
- describe('initial state discovery (no prior context)', () => {
202
- it('should push value to HomeKit on first update', async () => {
203
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
204
- expect(mockService.updateCharacteristic).toHaveBeenCalledWith(CHARACTERISTIC, 0);
205
- });
206
- it('should NOT log info message on initial discovery', async () => {
207
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
208
- expect(device.infoLog).not.toHaveBeenCalled();
209
- });
210
- it('should store the value in context for future comparisons', async () => {
211
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
212
- expect(device.accessory.context.LockMechanismLockCurrentState).toBe(0);
213
- });
214
- });
215
- describe('subsequent updates with unchanged value', () => {
216
- it('should NOT push to HomeKit when value has not changed', async () => {
217
- // Seed context as if a previous update occurred
218
- device.accessory.context.LockMechanismLockCurrentState = 1;
219
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 1, 'LockCurrentState', 1, 'Locked', 'Unlocked');
220
- expect(mockService.updateCharacteristic).not.toHaveBeenCalled();
221
- });
222
- it('should NOT log info message when value has not changed', async () => {
223
- device.accessory.context.LockMechanismLockCurrentState = 1;
224
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 1, 'LockCurrentState', 1, 'Locked', 'Unlocked');
225
- expect(device.infoLog).not.toHaveBeenCalled();
226
- });
227
- });
228
- describe('genuine state change', () => {
229
- it('should push to HomeKit when value changes', async () => {
230
- device.accessory.context.LockMechanismLockCurrentState = 1;
231
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
232
- expect(mockService.updateCharacteristic).toHaveBeenCalledWith(CHARACTERISTIC, 0);
233
- });
234
- it('should log "was Unlocked" when lock changes from secured to unsecured', async () => {
235
- device.accessory.context.LockMechanismLockCurrentState = 1;
236
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
237
- expect(device.infoLog).toHaveBeenCalledWith('was Unlocked');
238
- });
239
- it('should log "was Locked" when lock changes from unsecured to secured', async () => {
240
- device.accessory.context.LockMechanismLockCurrentState = 0;
241
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 1, 'LockCurrentState', 1, 'Locked', 'Unlocked');
242
- expect(device.infoLog).toHaveBeenCalledWith('was Locked');
243
- });
244
- it('should update context to new value', async () => {
245
- device.accessory.context.LockMechanismLockCurrentState = 1;
246
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
247
- expect(device.accessory.context.LockMechanismLockCurrentState).toBe(0);
248
- });
249
- });
250
- describe('contact sensor state changes', () => {
251
- it('should log "was Closed" when door changes to closed', async () => {
252
- device.accessory.context.ContactSensorContactSensorState = 1;
253
- await device.updateCharacteristic(mockService, 'ContactSensor', 'ContactSensorState', 0, 'ContactSensorState', 1, 'Opened', 'Closed');
254
- expect(device.infoLog).toHaveBeenCalledWith('was Closed');
255
- });
256
- it('should log "was Opened" when door changes to open', async () => {
257
- device.accessory.context.ContactSensorContactSensorState = 0;
258
- await device.updateCharacteristic(mockService, 'ContactSensor', 'ContactSensorState', 1, 'ContactSensorState', 1, 'Opened', 'Closed');
259
- expect(device.infoLog).toHaveBeenCalledWith('was Opened');
260
- });
261
- });
262
- describe('updates without StatusMatch/StatusDoesNotMatch', () => {
263
- it('should push to HomeKit but not log info when no status strings provided', async () => {
264
- device.accessory.context.BatteryBatteryLevel = 90;
265
- await device.updateCharacteristic(mockService, 'Battery', 'BatteryLevel', 85, 'BatteryLevel');
266
- expect(mockService.updateCharacteristic).toHaveBeenCalledWith('BatteryLevel', 85);
267
- expect(device.infoLog).not.toHaveBeenCalled();
268
- });
269
- });
270
- describe('startup simulation (seeded context matches API response)', () => {
271
- it('should not push to HomeKit or log when seeded context matches first API value', async () => {
272
- // Simulate constructor seeding: accessory.context.LockMechanismLockCurrentState ??= SECURED
273
- device.accessory.context.LockMechanismLockCurrentState = 1;
274
- // First API response returns same state (SECURED = 1)
275
- await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 1, 'LockCurrentState', 1, 'Locked', 'Unlocked');
276
- expect(mockService.updateCharacteristic).not.toHaveBeenCalled();
277
- expect(device.infoLog).not.toHaveBeenCalled();
278
- });
279
- });
280
- });
281
- //# sourceMappingURL=device.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"device.test.js","sourceRoot":"","sources":["../../src/devices/device.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=lock.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock.test.d.ts","sourceRoot":"","sources":["../../src/devices/lock.test.ts"],"names":[],"mappings":""}
@@ -1,265 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { describe, expect, it } from 'vitest';
4
- describe('lock pushChanges method', () => {
5
- // Test that the improved pushChanges method has better logging and validation
6
- it('should add defensive logging for API calls', () => {
7
- // This test validates that our code improvements are present
8
- // We test the actual code changes by checking the source contains our improvements
9
- const lockTsPath = join(__dirname, 'lock.ts');
10
- const lockTsContent = readFileSync(lockTsPath, 'utf8');
11
- // Verify that our defensive logging is present
12
- expect(lockTsContent).toContain('Making API call - Target:');
13
- expect(lockTsContent).toContain('States synchronized before API call');
14
- expect(lockTsContent).toContain('Double-check that we still need to make the API call');
15
- });
16
- it('should have proper error handling structure', () => {
17
- // Validate that the error handling structure is maintained
18
- const lockTsPath = join(__dirname, 'lock.ts');
19
- const lockTsContent = readFileSync(lockTsPath, 'utf8');
20
- // Verify error handling is still present
21
- expect(lockTsContent).toContain('await this.statusCode(\'pushChanges\', e)');
22
- expect(lockTsContent).toContain('pushChanges: ${e.message');
23
- });
24
- });
25
- describe('lock context seeding for change detection', () => {
26
- const lockTsPath = join(__dirname, 'lock.ts');
27
- const lockTsContent = readFileSync(lockTsPath, 'utf8');
28
- it('should seed LockMechanism context keys for change detection', () => {
29
- expect(lockTsContent).toContain('accessory.context.LockMechanismLockCurrentState ??= this.LockMechanism.LockCurrentState');
30
- expect(lockTsContent).toContain('accessory.context.LockMechanismLockTargetState ??= this.LockMechanism.LockTargetState');
31
- });
32
- it('should seed ContactSensor context key for change detection', () => {
33
- expect(lockTsContent).toContain('accessory.context.ContactSensorContactSensorState ??= this.ContactSensor.ContactSensorState');
34
- });
35
- it('should seed Battery context keys for change detection', () => {
36
- expect(lockTsContent).toContain('accessory.context.BatteryBatteryLevel ??= this.Battery.BatteryLevel');
37
- expect(lockTsContent).toContain('accessory.context.BatteryStatusLowBattery ??= this.Battery.StatusLowBattery');
38
- });
39
- it('should seed context keys after creating service objects but before initializing characteristics', () => {
40
- // Verify seeding happens between object assignment and characteristic initialization
41
- const lockMechanismSeed = lockTsContent.indexOf('accessory.context.LockMechanismLockCurrentState ??=');
42
- const lockMechanismAssign = lockTsContent.indexOf('accessory.context.LockMechanism = this.LockMechanism as object');
43
- const lockCharInit = lockTsContent.indexOf('this.LockMechanism.Service\n .setCharacteristic(this.hap.Characteristic.Name');
44
- expect(lockMechanismSeed).toBeGreaterThan(lockMechanismAssign);
45
- expect(lockMechanismSeed).toBeLessThan(lockCharInit);
46
- const contactSensorSeed = lockTsContent.indexOf('accessory.context.ContactSensorContactSensorState ??=');
47
- const contactSensorAssign = lockTsContent.indexOf('accessory.context.ContactSensor = this.ContactSensor as object');
48
- const contactCharInit = lockTsContent.indexOf('this.ContactSensor.Service\n .setCharacteristic(this.hap.Characteristic.Name');
49
- expect(contactSensorSeed).toBeGreaterThan(contactSensorAssign);
50
- expect(contactSensorSeed).toBeLessThan(contactCharInit);
51
- });
52
- it('should use nullish coalescing assignment (??=) to preserve existing persisted values', () => {
53
- // Ensure ??= is used (not = or ||=) so that persisted context values from previous runs are kept
54
- const lockCurrentLine = lockTsContent.match(/accessory\.context\.LockMechanismLockCurrentState\s*\?\?=/);
55
- const lockTargetLine = lockTsContent.match(/accessory\.context\.LockMechanismLockTargetState\s*\?\?=/);
56
- const contactLine = lockTsContent.match(/accessory\.context\.ContactSensorContactSensorState\s*\?\?=/);
57
- const batteryLevelLine = lockTsContent.match(/accessory\.context\.BatteryBatteryLevel\s*\?\?=/);
58
- const batteryLowLine = lockTsContent.match(/accessory\.context\.BatteryStatusLowBattery\s*\?\?=/);
59
- expect(lockCurrentLine).not.toBeNull();
60
- expect(lockTargetLine).not.toBeNull();
61
- expect(contactLine).not.toBeNull();
62
- expect(batteryLevelLine).not.toBeNull();
63
- expect(batteryLowLine).not.toBeNull();
64
- });
65
- });
66
- describe('parseStatus uses lockStatus not lockEvent', () => {
67
- const lockTsPath = join(__dirname, 'lock.ts');
68
- const lockTsContent = readFileSync(lockTsPath, 'utf8');
69
- // Extract the two methods so we can assert on each independently
70
- const parseStatusMatch = lockTsContent.match(/async parseStatus\(\)[\s\S]*?(?=\n {2}async parseEventStatus)/);
71
- const parseEventStatusMatch = lockTsContent.match(/async parseEventStatus\(\)[\s\S]*?(?=\n {2}\/\*\*|\n {2}async refreshStatus)/);
72
- const parseStatusBody = parseStatusMatch?.[0] ?? '';
73
- const parseEventStatusBody = parseEventStatusMatch?.[0] ?? '';
74
- it('should have extractable parseStatus and parseEventStatus methods', () => {
75
- expect(parseStatusBody.length).toBeGreaterThan(0);
76
- expect(parseEventStatusBody.length).toBeGreaterThan(0);
77
- });
78
- it('should use lockStatus.state for the guard condition in parseStatus', () => {
79
- // The definitive-state check must reference lockStatus, not lockEvent
80
- expect(parseStatusBody).toContain('this.lockStatus.state.locked !== this.lockStatus.state.unlocked');
81
- });
82
- it('should NOT reference lockEvent.state in parseStatus guard condition', () => {
83
- // Regression guard: lockEvent is undefined on startup when parseStatus runs
84
- expect(parseStatusBody).not.toContain('this.lockEvent.state.locked');
85
- expect(parseStatusBody).not.toContain('this.lockEvent.state.unlocked');
86
- });
87
- it('should log lockStatus in parseStatus warn messages', () => {
88
- // The locking/unlocking warn log and UNKNOWN warn log should reference lockStatus
89
- expect(parseStatusBody).toMatch(/lockStatus: \$\{JSON\.stringify\(this\.lockStatus\)\}/);
90
- expect(parseStatusBody).not.toMatch(/lockEvent: \$\{JSON\.stringify\(this\.lockEvent\)\}/);
91
- });
92
- it('should still use lockEvent.state in parseEventStatus', () => {
93
- // parseEventStatus handles PubNub subscription events where lockEvent IS populated
94
- expect(parseEventStatusBody).toContain('this.lockEvent.state.locked !== this.lockEvent.state.unlocked');
95
- expect(parseEventStatusBody).toContain('this.lockEvent.state.locked');
96
- });
97
- it('should guard parseEventStatus with an if (this.lockEvent) check', () => {
98
- // parseEventStatus must be guarded so it only runs when lockEvent is defined
99
- expect(parseEventStatusBody).toMatch(/if\s*\(this\.lockEvent\)/);
100
- });
101
- it('should still derive LockCurrentState from lockStatus.state in parseStatus', () => {
102
- // The actual state assignment inside the guard should use lockStatus
103
- expect(parseStatusBody).toContain('this.lockStatus.state.locked');
104
- expect(parseStatusBody).toContain('this.lockStatus.state.unlocked');
105
- });
106
- });
107
- describe('lock commands are not dropped during updates', () => {
108
- const lockTsPath = join(__dirname, 'lock.ts');
109
- const lockTsContent = readFileSync(lockTsPath, 'utf8');
110
- const parseStatusMatch = lockTsContent.match(/async parseStatus\(\)[\s\S]*?(?=\n {2}async parseEventStatus)/);
111
- const parseEventStatusMatch = lockTsContent.match(/async parseEventStatus\(\)[\s\S]*?(?=\n {2}\/\*\*|\n {2}async refreshStatus)/);
112
- const parseStatusBody = parseStatusMatch?.[0] ?? '';
113
- const parseEventStatusBody = parseEventStatusMatch?.[0] ?? '';
114
- it('should use filter (not skipWhile) on the refresh interval', () => {
115
- // skipWhile only suppresses at the start of the stream and then permanently
116
- // stops filtering. filter evaluates on every emission.
117
- expect(lockTsContent).toContain('filter(() => !this.lockUpdateInProgress)');
118
- expect(lockTsContent).not.toContain('skipWhile');
119
- });
120
- it('should import filter from rxjs/operators', () => {
121
- expect(lockTsContent).toMatch(/import\s*\{[^}]*filter[^}]*\}\s*from\s*'rxjs\/operators'/);
122
- });
123
- it('should guard LockTargetState sync in parseStatus with lockUpdateInProgress', () => {
124
- // parseStatus must NOT unconditionally overwrite TargetState, or it will
125
- // erase the user's lock/unlock intent before pushChanges can act on it
126
- expect(parseStatusBody).toContain('if (!this.lockUpdateInProgress)');
127
- expect(parseStatusBody).toContain('this.LockMechanism.LockTargetState = this.LockMechanism.LockCurrentState');
128
- });
129
- it('should guard LockTargetState sync in parseEventStatus with lockUpdateInProgress', () => {
130
- // PubNub events arrive continuously and must not reset TargetState during updates
131
- expect(parseEventStatusBody).toContain('if (!this.lockUpdateInProgress)');
132
- expect(parseEventStatusBody).toContain('this.LockMechanism.LockTargetState = this.LockMechanism.LockCurrentState');
133
- });
134
- it('should always update LockCurrentState regardless of lockUpdateInProgress', () => {
135
- // LockCurrentState should reflect the physical lock state at all times.
136
- // The lockUpdateInProgress guard must only wrap TargetState, not CurrentState.
137
- // Verify that the CurrentState assignment is NOT inside the guard.
138
- const parseStatusCurrentAssign = parseStatusBody.indexOf('this.LockMechanism.LockCurrentState = this.lockStatus.state.locked');
139
- const parseStatusGuard = parseStatusBody.indexOf('if (!this.lockUpdateInProgress)');
140
- expect(parseStatusCurrentAssign).toBeLessThan(parseStatusGuard);
141
- const parseEventCurrentAssign = parseEventStatusBody.indexOf('this.LockMechanism.LockCurrentState = this.lockEvent.state.locked');
142
- const parseEventGuard = parseEventStatusBody.indexOf('if (!this.lockUpdateInProgress)');
143
- expect(parseEventCurrentAssign).toBeLessThan(parseEventGuard);
144
- });
145
- });
146
- describe('session refresh and PubNub subscription lifecycle', () => {
147
- const lockTsPath = join(__dirname, 'lock.ts');
148
- const lockTsContent = readFileSync(lockTsPath, 'utf8');
149
- const platformTsPath = join(__dirname, '..', 'platform.ts');
150
- const platformTsContent = readFileSync(platformTsPath, 'utf8');
151
- // Extract refreshAugustSession and executeSessionRefresh
152
- const refreshMatch = platformTsContent.match(/async refreshAugustSession\(\)[\s\S]*?(?=\n {2}private async executeSessionRefresh)/);
153
- const executeMatch = platformTsContent.match(/private async executeSessionRefresh\(\)[\s\S]*?(?=\n {2}async pluginConfig)/);
154
- const refreshBody = refreshMatch?.[0] ?? '';
155
- const executeBody = executeMatch?.[0] ?? '';
156
- it('should have extractable refreshAugustSession and executeSessionRefresh methods', () => {
157
- expect(refreshBody.length).toBeGreaterThan(0);
158
- expect(executeBody.length).toBeGreaterThan(0);
159
- });
160
- // --- Promise coalescing (concurrent 502 protection) ---
161
- it('should use promise coalescing, not a boolean flag', () => {
162
- // Promise coalescing: concurrent callers share the same promise.
163
- // Boolean flag causes "skip" — callers retry with a dead instance.
164
- expect(refreshBody).toContain('this.sessionRefreshPromise');
165
- expect(platformTsContent).not.toContain('sessionRefreshInProgress');
166
- });
167
- it('should return the existing promise when a refresh is already in progress', () => {
168
- // This is the coalescing: callers await the in-flight refresh
169
- // instead of starting their own or skipping entirely
170
- expect(refreshBody).toContain('return this.sessionRefreshPromise');
171
- });
172
- it('should clear the promise after refresh completes', () => {
173
- // Ensures the next 502 triggers a fresh refresh
174
- expect(refreshBody).toContain('this.sessionRefreshPromise = undefined');
175
- });
176
- // --- Session refresh lifecycle ---
177
- it('should end the old instance before creating a new one', () => {
178
- const endCall = executeBody.indexOf('.end()');
179
- const nullAssign = executeBody.indexOf('this.augustConfig = undefined');
180
- const credentialsCall = executeBody.indexOf('this.augustCredentials()');
181
- // Verify the order: end → null → create
182
- expect(endCall).toBeGreaterThan(-1);
183
- expect(nullAssign).toBeGreaterThan(endCall);
184
- expect(credentialsCall).toBeGreaterThan(nullAssign);
185
- });
186
- it('should NOT rebuild PubNub subscriptions during session refresh', () => {
187
- // PubNub subscriptions are independent of the HTTP session and should
188
- // NOT be torn down or rebuilt during a session refresh. Doing so
189
- // caused the 502 cascade + memory leak in earlier versions.
190
- expect(executeBody).not.toContain('resubscribeCallbacks');
191
- expect(executeBody).not.toContain('subscribeAugust');
192
- expect(platformTsContent).not.toContain('registerResubscribeCallback');
193
- expect(platformTsContent).not.toContain('unregisterResubscribeCallback');
194
- });
195
- // --- PubNub subscription cleanup on lock removal ---
196
- it('should capture the unsubscribe function returned by August.subscribe', () => {
197
- // Previously the return value was discarded, leaking PubNub instances.
198
- expect(lockTsContent).toMatch(/this\.pubnubUnsubscribe\s*=\s*await August\.subscribe/);
199
- });
200
- it('should provide a tearDownPubNubSubscription method on LockMechanism', () => {
201
- expect(lockTsContent).toMatch(/tearDownPubNubSubscription\(\)/);
202
- expect(lockTsContent).toContain('this.pubnubUnsubscribe()');
203
- });
204
- it('should call the unsubscribe function and clear the reference', () => {
205
- // Extract tearDownPubNubSubscription method definition (not calls to it)
206
- const tearDownMatch = lockTsContent.match(/tearDownPubNubSubscription\(\):\s*void\s*\{[\s\S]*?\n {2}\}/);
207
- const tearDownBody = tearDownMatch?.[0] ?? '';
208
- expect(tearDownBody).toContain('this.pubnubUnsubscribe()');
209
- expect(tearDownBody).toContain('this.pubnubUnsubscribe = undefined');
210
- });
211
- it('should tear down PubNub subscription before creating a new one (idempotent subscribeAugust)', () => {
212
- // subscribeAugust() should clean up any previous subscription first,
213
- // so repeated calls do not leak PubNub instances.
214
- const subscribeMatch = lockTsContent.match(/async subscribeAugust\(\)[\s\S]*?(?=\n {2}\/\*\*|\n {2}tearDownPubNubSubscription)/);
215
- const subscribeBody = subscribeMatch?.[0] ?? '';
216
- const tearDownCall = subscribeBody.indexOf('this.tearDownPubNubSubscription()');
217
- const augustSubscribeCall = subscribeBody.indexOf('August.subscribe');
218
- expect(tearDownCall).toBeGreaterThan(-1);
219
- expect(augustSubscribeCall).toBeGreaterThan(tearDownCall);
220
- });
221
- // --- Platform-side tracking for proper cleanup ---
222
- it('should track LockMechanism instances by lockId for cleanup', () => {
223
- expect(platformTsContent).toMatch(/lockMechanisms\s*=\s*new Map<string, LockMechanism>/);
224
- });
225
- it('should tear down LockMechanism PubNub subscription when unregistering accessory', () => {
226
- expect(platformTsContent).toMatch(/tearDownLockMechanism\(device\.lockId\)/);
227
- });
228
- it('should tear down LockMechanism when excluding lock via excludeLockIds', () => {
229
- expect(platformTsContent).toMatch(/tearDownLockMechanism\(excludedId\)/);
230
- });
231
- it('tearDownLockMechanism should call tearDownPubNubSubscription and remove from map', () => {
232
- const tearDownMatch = platformTsContent.match(/private tearDownLockMechanism\([\s\S]*?(?=\n {2}\})/);
233
- const body = tearDownMatch?.[0] ?? '';
234
- expect(body).toContain('tearDownPubNubSubscription()');
235
- expect(body).toContain('this.lockMechanisms.delete');
236
- });
237
- });
238
- describe('session refresh cooldown', () => {
239
- const platformTsPath = join(__dirname, '..', 'platform.ts');
240
- const platformTsContent = readFileSync(platformTsPath, 'utf8');
241
- const refreshMatch = platformTsContent.match(/async refreshAugustSession\(\)[\s\S]*?(?=\n {2}private async executeSessionRefresh)/);
242
- const refreshBody = refreshMatch?.[0] ?? '';
243
- it('should track the time of the last refresh attempt', () => {
244
- expect(platformTsContent).toMatch(/lastSessionRefresh\s*=\s*0/);
245
- });
246
- it('should define a cooldown constant', () => {
247
- expect(platformTsContent).toMatch(/SESSION_REFRESH_COOLDOWN_MS/);
248
- });
249
- it('should skip refresh when within the cooldown window', () => {
250
- expect(refreshBody).toContain('sinceLastRefresh');
251
- expect(refreshBody).toMatch(/sinceLastRefresh\s*<\s*AugustPlatform\.SESSION_REFRESH_COOLDOWN_MS/);
252
- });
253
- it('should update lastSessionRefresh after a refresh completes', () => {
254
- expect(refreshBody).toContain('this.lastSessionRefresh = Date.now()');
255
- });
256
- it('should check cooldown after coalescing check', () => {
257
- // Promise coalescing should still take priority over the cooldown.
258
- // If a refresh is in flight, callers await it regardless of cooldown.
259
- const coalescingCheck = refreshBody.indexOf('this.sessionRefreshPromise');
260
- const cooldownCheck = refreshBody.indexOf('sinceLastRefresh');
261
- expect(coalescingCheck).toBeGreaterThan(-1);
262
- expect(cooldownCheck).toBeGreaterThan(coalescingCheck);
263
- });
264
- });
265
- //# sourceMappingURL=lock.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock.test.js","sourceRoot":"","sources":["../../src/devices/lock.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}