mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-10-22 22:11:22 +00:00
feat: Use Vitest for testing (#25284)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
This commit is contained in:
1 parent
5d059b7bcb
commit
06f44533af
51 files changed
+2606
-4771
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import * as data from '../mocks/data';
|
||||
import {mockLogger} from '../mocks/logger';
|
||||
import {mockMQTT, events as mockMQTTEvents} from '../mocks/mqtt';
|
||||
import {events as mockMQTTEvents, mockMQTTPublishAsync} from '../mocks/mqtt';
|
||||
import {flushPromises} from '../mocks/utils';
|
||||
import {devices, events as mockZHEvents, returnDevices} from '../mocks/zigbeeHerdsman';
|
||||
|
||||
@@ -13,7 +13,7 @@ import Availability from '../../lib/extension/availability';
|
||||
import * as settings from '../../lib/util/settings';
|
||||
import utils from '../../lib/util/utils';
|
||||
|
||||
const mocksClear = [mockMQTT.publishAsync, mockLogger.warning, mockLogger.info];
|
||||
const mocksClear = [mockMQTTPublishAsync, mockLogger.warning, mockLogger.info];
|
||||
|
||||
returnDevices.push(
|
||||
devices.bulb_color.ieeeAddr,
|
||||
@@ -37,22 +37,22 @@ describe('Extension: Availability', () => {
|
||||
};
|
||||
|
||||
const setTimeAndAdvanceTimers = async (value: number): Promise<void> => {
|
||||
jest.setSystemTime(Date.now() + value);
|
||||
await jest.advanceTimersByTimeAsync(value);
|
||||
vi.setSystemTime(Date.now() + value);
|
||||
await vi.advanceTimersByTimeAsync(value);
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
jest.spyOn(utils, 'sleep').mockImplementation();
|
||||
jest.useFakeTimers();
|
||||
vi.spyOn(utils, 'sleep').mockImplementation(vi.fn());
|
||||
vi.useFakeTimers();
|
||||
settings.reRead();
|
||||
settings.set(['availability'], {enabled: true});
|
||||
controller = new Controller(jest.fn(), jest.fn());
|
||||
controller = new Controller(vi.fn(), vi.fn());
|
||||
await controller.start();
|
||||
await flushPromises();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.setSystemTime(utils.minutes(1));
|
||||
vi.setSystemTime(utils.minutes(1));
|
||||
data.writeDefaultConfiguration();
|
||||
settings.reRead();
|
||||
settings.set(['availability'], {enabled: true});
|
||||
@@ -67,16 +67,16 @@ describe('Extension: Availability', () => {
|
||||
|
||||
afterAll(async () => {
|
||||
await controller.stop();
|
||||
jest.useRealTimers();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('Should publish availability on startup for device where it is enabled for', async () => {
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'online'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'online'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/remote/availability', stringify({state: 'online'}), {retain: true, qos: 1});
|
||||
expect(mockMQTT.publishAsync).not.toHaveBeenCalledWith('zigbee2mqtt/bulb_color_2/availability', stringify({state: 'online'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/remote/availability', stringify({state: 'online'}), {retain: true, qos: 1});
|
||||
expect(mockMQTTPublishAsync).not.toHaveBeenCalledWith('zigbee2mqtt/bulb_color_2/availability', stringify({state: 'online'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
@@ -106,14 +106,14 @@ describe('Extension: Availability', () => {
|
||||
});
|
||||
|
||||
it('Should publish offline for active device when not seen for 10 minutes', async () => {
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
await setTimeAndAdvanceTimers(utils.minutes(5));
|
||||
expect(devices.bulb_color.ping).toHaveBeenCalledTimes(0);
|
||||
|
||||
await setTimeAndAdvanceTimers(utils.minutes(7));
|
||||
expect(devices.bulb_color.ping).toHaveBeenCalledTimes(1);
|
||||
expect(devices.bulb_color.ping).toHaveBeenNthCalledWith(1, true);
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'offline'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'offline'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
@@ -127,20 +127,20 @@ describe('Extension: Availability', () => {
|
||||
});
|
||||
|
||||
it('Should publish offline for passive device when not seen for 25 hours', async () => {
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
await setTimeAndAdvanceTimers(utils.hours(26));
|
||||
expect(devices.remote.ping).toHaveBeenCalledTimes(0);
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/remote/availability', stringify({state: 'offline'}), {retain: true, qos: 1});
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/remote/availability', stringify({state: 'offline'}), {retain: true, qos: 1});
|
||||
});
|
||||
|
||||
it('Should reset ping timer when device last seen changes for active device', async () => {
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
|
||||
await setTimeAndAdvanceTimers(utils.minutes(5));
|
||||
expect(devices.bulb_color.ping).toHaveBeenCalledTimes(0);
|
||||
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color});
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'offline'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'offline'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
@@ -154,7 +154,7 @@ describe('Extension: Availability', () => {
|
||||
});
|
||||
|
||||
it('Should ping again when first ping fails', async () => {
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color});
|
||||
|
||||
@@ -169,13 +169,13 @@ describe('Extension: Availability', () => {
|
||||
});
|
||||
|
||||
it('Should reset ping timer when device last seen changes for passive device', async () => {
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
|
||||
await setTimeAndAdvanceTimers(utils.hours(24));
|
||||
expect(devices.remote.ping).toHaveBeenCalledTimes(0);
|
||||
|
||||
await mockZHEvents.lastSeenChanged({device: devices.remote});
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/remote/availability', stringify({state: 'offline'}), {retain: true, qos: 1});
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/remote/availability', stringify({state: 'offline'}), {retain: true, qos: 1});
|
||||
|
||||
await setTimeAndAdvanceTimers(utils.hours(25));
|
||||
expect(devices.remote.ping).toHaveBeenCalledTimes(0);
|
||||
@@ -185,10 +185,10 @@ describe('Extension: Availability', () => {
|
||||
});
|
||||
|
||||
it('Should immediately mark device as online when it lastSeen changes', async () => {
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
|
||||
await setTimeAndAdvanceTimers(utils.minutes(15));
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'offline'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'offline'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
@@ -196,7 +196,7 @@ describe('Extension: Availability', () => {
|
||||
devices.bulb_color.lastSeen = Date.now();
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color});
|
||||
await flushPromises();
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'online'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', stringify({state: 'online'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
@@ -310,18 +310,18 @@ describe('Extension: Availability', () => {
|
||||
});
|
||||
|
||||
it('Should republish availability when device is renamed', async () => {
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
|
||||
mockMQTTEvents.message('zigbee2mqtt/bridge/request/device/rename', stringify({from: 'bulb_color', to: 'bulb_new_name'}));
|
||||
await flushPromises();
|
||||
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', '', {retain: true, qos: 1});
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_new_name/availability', stringify({state: 'online'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_color/availability', '', {retain: true, qos: 1});
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_new_name/availability', stringify({state: 'online'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
await setTimeAndAdvanceTimers(utils.hours(12));
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_new_name/availability', stringify({state: 'offline'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/bulb_new_name/availability', stringify({state: 'offline'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
@@ -330,10 +330,10 @@ describe('Extension: Availability', () => {
|
||||
it('Should publish availability payload in JSON format', async () => {
|
||||
await resetExtension();
|
||||
devices.remote.ping.mockClear();
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
await setTimeAndAdvanceTimers(utils.hours(26));
|
||||
expect(devices.remote.ping).toHaveBeenCalledTimes(0);
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/remote/availability', stringify({state: 'offline'}), {retain: true, qos: 1});
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/remote/availability', stringify({state: 'offline'}), {retain: true, qos: 1});
|
||||
});
|
||||
|
||||
it('Should publish availability for groups', async () => {
|
||||
@@ -341,21 +341,21 @@ describe('Extension: Availability', () => {
|
||||
await resetExtension();
|
||||
devices.bulb_color_2.ping.mockClear();
|
||||
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/group_tradfri_remote/availability', stringify({state: 'online'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/group_tradfri_remote/availability', stringify({state: 'online'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
await setTimeAndAdvanceTimers(utils.minutes(12));
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/group_tradfri_remote/availability', stringify({state: 'offline'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/group_tradfri_remote/availability', stringify({state: 'offline'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
mockMQTT.publishAsync.mockClear();
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
devices.bulb_color_2.lastSeen = Date.now();
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color_2});
|
||||
await flushPromises();
|
||||
expect(mockMQTT.publishAsync).toHaveBeenCalledWith('zigbee2mqtt/group_tradfri_remote/availability', stringify({state: 'online'}), {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith('zigbee2mqtt/group_tradfri_remote/availability', stringify({state: 'online'}), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
});
|
||||
@@ -365,7 +365,7 @@ describe('Extension: Availability', () => {
|
||||
// @ts-expect-error private
|
||||
const availability = controller.extensions.find((extension) => extension instanceof Availability)!;
|
||||
// @ts-expect-error private
|
||||
const publishAvailabilitySpy = jest.spyOn(availability, 'publishAvailability');
|
||||
const publishAvailabilitySpy = vi.spyOn(availability, 'publishAvailability');
|
||||
|
||||
devices.bulb_color.ping.mockImplementationOnce(() => new Promise((resolve) => setTimeout(resolve, 1000)));
|
||||
// @ts-expect-error private
|
||||
@@ -380,7 +380,7 @@ describe('Extension: Availability', () => {
|
||||
expect(availability.pingQueue).toEqual([]);
|
||||
// Validate the stop-interrupt implicitly by checking that it prevents further function invocations
|
||||
expect(publishAvailabilitySpy).not.toHaveBeenCalled();
|
||||
devices.bulb_color.ping = jest.fn(); // ensure reset
|
||||
devices.bulb_color.ping = vi.fn(); // ensure reset
|
||||
});
|
||||
|
||||
it('Should prevent instance restart', async () => {
|
||||
|
||||
Reference in new issue
Block a user