homebridge-tsvesync 1.4.6 → 1.4.7

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.
@@ -95,7 +95,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
95
95
  }
96
96
 
97
97
  describe('Filter Service Setup', () => {
98
- it('should create filter maintenance service for all air purifiers', () => {
98
+ it('should not add FilterMaintenance service (migrated to AirPurifier service)', () => {
99
99
  const mockDevice = createMockAirPurifier({ filterLife: 60 });
100
100
 
101
101
  const accessory = {
@@ -109,28 +109,31 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
109
109
  if (service === platform.Service.FilterMaintenance) return filterService;
110
110
  return filterService;
111
111
  }),
112
+ removeService: jest.fn(),
112
113
  };
113
114
 
114
- const airPurifier = new AirPurifierAccessory(platform, accessory as any, mockDevice as any);
115
+ new AirPurifierAccessory(platform, accessory as any, mockDevice as any);
115
116
 
116
- // Verify filter maintenance service was added
117
- expect(accessory.addService).toHaveBeenCalledWith(platform.Service.FilterMaintenance);
117
+ expect(accessory.addService).not.toHaveBeenCalledWith(platform.Service.FilterMaintenance);
118
118
  });
119
119
 
120
- it('should reuse existing filter maintenance service', () => {
120
+ it('should remove legacy FilterMaintenance service if present', () => {
121
121
  const mockDevice = createMockAirPurifier();
122
122
 
123
123
  const accessory = {
124
124
  getService: jest.fn((service) => {
125
+ if (service === platform.Service.AccessoryInformation) return infoService;
126
+ if (service === platform.Service.AirPurifier) return airPurifierService;
125
127
  if (service === platform.Service.FilterMaintenance) return filterService;
126
- return airPurifierService;
128
+ return null;
127
129
  }),
128
130
  addService: jest.fn(),
131
+ removeService: jest.fn(),
129
132
  };
130
133
 
131
134
  new AirPurifierAccessory(platform, accessory as any, mockDevice as any);
132
135
 
133
- // Verify service was not added again
136
+ expect(accessory.removeService).toHaveBeenCalledWith(filterService);
134
137
  expect(accessory.addService).not.toHaveBeenCalledWith(platform.Service.FilterMaintenance);
135
138
  });
136
139
  });
@@ -148,6 +151,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
148
151
  return airPurifierService;
149
152
  }),
150
153
  addService: jest.fn(),
154
+ removeService: jest.fn(),
151
155
  };
152
156
 
153
157
  airPurifier = new AirPurifierAccessory(platform, accessory as any, mockDevice as any);
@@ -211,6 +215,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
211
215
  const accessory = {
212
216
  getService: jest.fn(() => filterService),
213
217
  addService: jest.fn(),
218
+ removeService: jest.fn(),
214
219
  };
215
220
 
216
221
  airPurifier = new AirPurifierAccessory(platform, accessory as any, mockDevice as any);
@@ -249,9 +254,10 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
249
254
 
250
255
  it('should handle NaN filter life values', async () => {
251
256
  mockDevice.filterLife = NaN;
257
+ mockDevice.details!.filter_life = NaN as any;
252
258
 
253
259
  const result = await (airPurifier as any).getFilterLifeLevel();
254
- expect(result).toBe(0); // Default to 0 for NaN
260
+ expect(result).toBe(100); // Default to 100% when data is invalid
255
261
  });
256
262
  });
257
263
 
@@ -262,6 +268,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
262
268
  const accessory = {
263
269
  getService: jest.fn(() => filterService),
264
270
  addService: jest.fn(),
271
+ removeService: jest.fn(),
265
272
  };
266
273
 
267
274
  // Create base air purifier for testing
@@ -323,16 +330,23 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
323
330
 
324
331
  beforeEach(() => {
325
332
  mockCharacteristic = {
333
+ onGet: jest.fn().mockReturnThis(),
334
+ onSet: jest.fn().mockReturnThis(),
335
+ setProps: jest.fn().mockReturnThis(),
326
336
  updateValue: jest.fn(),
327
337
  };
328
338
 
329
339
  mockDevice = createMockAirPurifier();
330
340
 
331
341
  const accessory = {
332
- getService: jest.fn(() => ({
333
- getCharacteristic: jest.fn(() => mockCharacteristic),
334
- })),
342
+ getService: jest.fn((service) => {
343
+ if (service === platform.Service.AccessoryInformation) return infoService;
344
+ return {
345
+ getCharacteristic: jest.fn(() => mockCharacteristic),
346
+ };
347
+ }),
335
348
  addService: jest.fn(),
349
+ removeService: jest.fn(),
336
350
  };
337
351
 
338
352
  airPurifier = new AirPurifierAccessory(platform, accessory as any, mockDevice as any);
@@ -380,19 +394,30 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
380
394
  let airPurifier: AirPurifierAccessory;
381
395
  let mockDevice: MockAirPurifierWithFilter;
382
396
  let mockCharacteristic: any;
397
+ let airPurifierServiceMock: any;
383
398
 
384
399
  beforeEach(() => {
385
400
  mockCharacteristic = {
401
+ onGet: jest.fn().mockReturnThis(),
402
+ onSet: jest.fn().mockReturnThis(),
403
+ setProps: jest.fn().mockReturnThis(),
386
404
  updateValue: jest.fn(),
387
405
  };
388
406
 
389
407
  mockDevice = createMockAirPurifier();
408
+
409
+ airPurifierServiceMock = {
410
+ getCharacteristic: jest.fn(() => mockCharacteristic),
411
+ updateCharacteristic: jest.fn(),
412
+ };
390
413
 
391
414
  const accessory = {
392
- getService: jest.fn(() => ({
393
- getCharacteristic: jest.fn(() => mockCharacteristic),
394
- })),
415
+ getService: jest.fn((service) => {
416
+ if (service === platform.Service.AccessoryInformation) return infoService;
417
+ return airPurifierServiceMock;
418
+ }),
395
419
  addService: jest.fn(),
420
+ removeService: jest.fn(),
396
421
  };
397
422
 
398
423
  airPurifier = new AirPurifierAccessory(platform, accessory as any, mockDevice as any);
@@ -402,10 +427,17 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
402
427
  // Simulate device update
403
428
  mockDevice.filterLife = 30;
404
429
 
405
- await (airPurifier as any).updateDeviceState();
430
+ await (airPurifier as any).updateDeviceSpecificStates(mockDevice);
406
431
 
407
- // Verify characteristics were updated
408
- expect(mockCharacteristic.updateValue).toHaveBeenCalled();
432
+ // Verify filter characteristics were updated
433
+ expect(airPurifierServiceMock.updateCharacteristic).toHaveBeenCalledWith(
434
+ platform.Characteristic.FilterChangeIndication,
435
+ 0
436
+ );
437
+ expect(airPurifierServiceMock.updateCharacteristic).toHaveBeenCalledWith(
438
+ platform.Characteristic.FilterLifeLevel,
439
+ 30
440
+ );
409
441
  });
410
442
 
411
443
  it('should handle rapid filter life changes', async () => {
@@ -433,6 +465,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
433
465
  const accessory = {
434
466
  getService: jest.fn(() => filterService),
435
467
  addService: jest.fn(),
468
+ removeService: jest.fn(),
436
469
  };
437
470
 
438
471
  airPurifier = new AirPurifierAccessory(platform, accessory as any, mockDevice as any);
@@ -464,8 +497,8 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
464
497
  const lifeResult = await (airPurifier as any).getFilterLifeLevel();
465
498
  const changeResult = await (airPurifier as any).getFilterChangeIndication();
466
499
 
467
- expect(lifeResult).toBe(0);
468
- expect(changeResult).toBe(1); // CHANGE_FILTER for corrupted data
500
+ expect(lifeResult).toBe(100);
501
+ expect(changeResult).toBe(0); // FILTER_OK when data is missing/invalid
469
502
  });
470
503
 
471
504
  it('should handle invalid filter life types', async () => {
@@ -473,7 +506,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
473
506
  mockDevice.details!.filter_life = 'invalid' as any;
474
507
 
475
508
  const lifeResult = await (airPurifier as any).getFilterLifeLevel();
476
- expect(lifeResult).toBe(0);
509
+ expect(lifeResult).toBe(100);
477
510
  });
478
511
 
479
512
  it('should handle extreme filter life values gracefully', async () => {
@@ -500,6 +533,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
500
533
  const accessory = {
501
534
  getService: jest.fn(() => filterService),
502
535
  addService: jest.fn(),
536
+ removeService: jest.fn(),
503
537
  };
504
538
 
505
539
  const airPurifier = new AirPurifierAccessory(platform, accessory as any, coreDevice as any);
@@ -518,6 +552,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
518
552
  const accessory = {
519
553
  getService: jest.fn(() => filterService),
520
554
  addService: jest.fn(),
555
+ removeService: jest.fn(),
521
556
  };
522
557
 
523
558
  const airPurifier = new AirPurifierAccessory(platform, accessory as any, lapDevice as any);
@@ -536,6 +571,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
536
571
  const accessory = {
537
572
  getService: jest.fn(() => filterService),
538
573
  addService: jest.fn(),
574
+ removeService: jest.fn(),
539
575
  };
540
576
 
541
577
  const airPurifier = new AirPurifierAccessory(platform, accessory as any, lvDevice as any);
@@ -555,6 +591,7 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
555
591
  const accessory = {
556
592
  getService: jest.fn(() => filterService),
557
593
  addService: jest.fn(),
594
+ removeService: jest.fn(),
558
595
  };
559
596
 
560
597
  airPurifier = new AirPurifierAccessory(platform, accessory as any, mockDevice as any);
@@ -592,4 +629,4 @@ describe('AirPurifierAccessory Filter Maintenance Features', () => {
592
629
  expect(result).toBe(0); // FILTER_OK
593
630
  });
594
631
  });
595
- });
632
+ });