feat: Add event-based automation triggers (#2537)
This commit is contained in:
committed by
dermotduffy
parent
b701366762
commit
a31816c168
@@ -6,6 +6,7 @@ import { CallTrigger } from '../../../src/condition-trigger/triggers/triggers/ca
|
||||
import { CameraTrigger } from '../../../src/condition-trigger/triggers/triggers/camera';
|
||||
import { ConfigTrigger } from '../../../src/condition-trigger/triggers/triggers/config';
|
||||
import { DisplayModeTrigger } from '../../../src/condition-trigger/triggers/triggers/display-mode';
|
||||
import { EventTrigger } from '../../../src/condition-trigger/triggers/triggers/event';
|
||||
import { ExpandTrigger } from '../../../src/condition-trigger/triggers/triggers/expand';
|
||||
import { FullscreenTrigger } from '../../../src/condition-trigger/triggers/triggers/fullscreen';
|
||||
import { InitializedTrigger } from '../../../src/condition-trigger/triggers/triggers/initialized';
|
||||
@@ -24,6 +25,7 @@ import {
|
||||
} from '../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { ViewTrigger } from '../../../src/condition-trigger/triggers/triggers/view';
|
||||
import { Trigger } from '../../../src/config/schema/condition-trigger/triggers/types';
|
||||
import { createHASSManager } from '../../test-utils';
|
||||
|
||||
type TriggerEvaluatorConstructor = new (...args: never[]) => TriggerEvaluator;
|
||||
|
||||
@@ -32,9 +34,11 @@ describe('createTriggerEvaluator', () => {
|
||||
const context = (): TriggerEvaluatorContext => ({
|
||||
stateManager: new ConditionStateManager(),
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
hassManager: createHASSManager(),
|
||||
});
|
||||
|
||||
it.each<[Trigger, TriggerEvaluatorConstructor]>([
|
||||
[{ trigger: 'event', event_type: 'zha_event' }, EventTrigger],
|
||||
[{ trigger: 'state', entity_id: 'binary_sensor.x' }, StateTrigger],
|
||||
[{ trigger: 'numeric_state', entity_id: 'sensor.x', above: 5 }, NumericStateTrigger],
|
||||
[{ trigger: 'template', value_template: '{{ true }}' }, TemplateTrigger],
|
||||
|
||||
@@ -2,7 +2,7 @@ import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { ConditionStateManager } from '../../../src/condition-trigger/conditions/state-manager';
|
||||
import { TriggersManager } from '../../../src/condition-trigger/triggers/manager';
|
||||
import { Trigger } from '../../../src/config/schema/condition-trigger/triggers/types';
|
||||
import { createHASS, createStateEntity } from '../../test-utils';
|
||||
import { createHASS, createHASSManager, createStateEntity } from '../../test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('TriggersManager', () => {
|
||||
@@ -14,7 +14,7 @@ describe('TriggersManager', () => {
|
||||
listener: Mock;
|
||||
} => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const manager = new TriggersManager(triggers, stateManager);
|
||||
const manager = new TriggersManager(triggers, stateManager, createHASSManager());
|
||||
const listener = vi.fn();
|
||||
return { manager, stateManager, listener };
|
||||
};
|
||||
@@ -107,6 +107,7 @@ describe('TriggersManager', () => {
|
||||
const manager = new TriggersManager(
|
||||
[{ trigger: 'camera', cameras: ['front'], enabled }],
|
||||
stateManager,
|
||||
createHASSManager(),
|
||||
);
|
||||
const listener = vi.fn();
|
||||
manager.addListener(listener);
|
||||
@@ -169,6 +170,7 @@ describe('TriggersManager', () => {
|
||||
const manager = new TriggersManager(
|
||||
[{ trigger: 'camera', cameras: ['front', 'back'], enabled: ENABLED_TEMPLATE }],
|
||||
stateManager,
|
||||
createHASSManager(),
|
||||
);
|
||||
const listener = vi.fn();
|
||||
manager.addListener(listener);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { CallTrigger } from '../../../../src/condition-trigger/triggers/triggers/call';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('CallTrigger', () => {
|
||||
@@ -11,10 +11,9 @@ describe('CallTrigger', () => {
|
||||
): { stateManager: ConditionStateManager; callback: Mock } => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
new CallTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
}).subscribe(callback);
|
||||
new CallTrigger(trigger, createTriggerEvaluatorContext({ stateManager })).subscribe(
|
||||
callback,
|
||||
);
|
||||
return { stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { CameraTrigger } from '../../../../src/condition-trigger/triggers/triggers/camera';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createConfig } from '../../../test-utils';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('CameraTrigger', () => {
|
||||
@@ -16,10 +16,10 @@ describe('CameraTrigger', () => {
|
||||
} => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
const cameraTrigger = new CameraTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
});
|
||||
const cameraTrigger = new CameraTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
);
|
||||
return { cameraTrigger, stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { ConfigTrigger } from '../../../../src/condition-trigger/triggers/triggers/config';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createConfig } from '../../../test-utils';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('ConfigTrigger', () => {
|
||||
@@ -16,10 +16,10 @@ describe('ConfigTrigger', () => {
|
||||
} => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
const configTrigger = new ConfigTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
});
|
||||
const configTrigger = new ConfigTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
);
|
||||
return { configTrigger, stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { DisplayModeTrigger } from '../../../../src/condition-trigger/triggers/triggers/display-mode';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('DisplayModeTrigger', () => {
|
||||
@@ -11,10 +11,10 @@ describe('DisplayModeTrigger', () => {
|
||||
): { stateManager: ConditionStateManager; callback: Mock } => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
new DisplayModeTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
}).subscribe(callback);
|
||||
new DisplayModeTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
).subscribe(callback);
|
||||
return { stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import {
|
||||
EventSubscriptionRequest,
|
||||
EventWatcherSubscriptionInterface,
|
||||
} from '../../../../src/card-controller/hass/event-watcher';
|
||||
import { EventTrigger } from '../../../../src/condition-trigger/triggers/triggers/event';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createHASSEvent, createHASSManager } from '../../../test-utils';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
interface Harness {
|
||||
trigger: EventTrigger;
|
||||
eventWatcher: EventWatcherSubscriptionInterface;
|
||||
callback: Mock;
|
||||
}
|
||||
|
||||
const create = (config: TriggerOfType<'event'>): Harness => {
|
||||
const eventWatcher = mock<EventWatcherSubscriptionInterface>();
|
||||
const hassManager = createHASSManager({ eventWatcher });
|
||||
|
||||
const callback = vi.fn();
|
||||
const trigger = new EventTrigger(
|
||||
config,
|
||||
createTriggerEvaluatorContext({ hassManager }),
|
||||
);
|
||||
return { trigger, eventWatcher, callback };
|
||||
};
|
||||
|
||||
const getLastMatcher = (
|
||||
eventWatcher: EventWatcherSubscriptionInterface,
|
||||
n = 0,
|
||||
): EventSubscriptionRequest['matcher'] =>
|
||||
vi.mocked(eventWatcher.subscribe).mock.calls[n][0].matcher;
|
||||
|
||||
const callEventCallback = (
|
||||
eventWatcher: EventWatcherSubscriptionInterface,
|
||||
event: ReturnType<typeof createHASSEvent>,
|
||||
n = 0,
|
||||
): void => {
|
||||
vi.mocked(eventWatcher.subscribe).mock.calls[n][0].callback(event);
|
||||
};
|
||||
|
||||
describe('EventTrigger', () => {
|
||||
it('should register one EventWatcher request per event_type', () => {
|
||||
const { trigger, eventWatcher, callback } = create({
|
||||
trigger: 'event',
|
||||
event_type: 'zha_event',
|
||||
});
|
||||
trigger.subscribe(callback);
|
||||
expect(eventWatcher.subscribe).toBeCalledTimes(1);
|
||||
expect(vi.mocked(eventWatcher.subscribe).mock.calls[0][0].event_type).toBe(
|
||||
'zha_event',
|
||||
);
|
||||
});
|
||||
|
||||
it('should dedupe duplicate event_types in list form', () => {
|
||||
// A repeated entry would otherwise produce two requests and fire the
|
||||
// callback twice for every matching event.
|
||||
const { trigger, eventWatcher, callback } = create({
|
||||
trigger: 'event',
|
||||
event_type: ['zha_event', 'zha_event'],
|
||||
});
|
||||
trigger.subscribe(callback);
|
||||
expect(eventWatcher.subscribe).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should expand list-form event_type into one request per type', () => {
|
||||
const { trigger, eventWatcher, callback } = create({
|
||||
trigger: 'event',
|
||||
event_type: ['zha_event', 'deconz_event'],
|
||||
});
|
||||
trigger.subscribe(callback);
|
||||
expect(eventWatcher.subscribe).toBeCalledTimes(2);
|
||||
expect(vi.mocked(eventWatcher.subscribe).mock.calls[0][0].event_type).toBe(
|
||||
'zha_event',
|
||||
);
|
||||
expect(vi.mocked(eventWatcher.subscribe).mock.calls[1][0].event_type).toBe(
|
||||
'deconz_event',
|
||||
);
|
||||
});
|
||||
|
||||
it('should fire with the full HA event on dispatch', () => {
|
||||
const { trigger, eventWatcher, callback } = create({
|
||||
trigger: 'event',
|
||||
event_type: 'zha_event',
|
||||
});
|
||||
trigger.subscribe(callback);
|
||||
const event = createHASSEvent('zha_event', { command: 'press' });
|
||||
callEventCallback(eventWatcher, event);
|
||||
expect(callback).toBeCalledWith({ platform: 'event', event });
|
||||
});
|
||||
|
||||
it('should omit the matcher when neither event_data nor context is set', () => {
|
||||
const { trigger, eventWatcher, callback } = create({
|
||||
trigger: 'event',
|
||||
event_type: 'zha_event',
|
||||
});
|
||||
trigger.subscribe(callback);
|
||||
expect(vi.mocked(eventWatcher.subscribe).mock.calls[0][0].matcher).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should attach an event_data matcher', () => {
|
||||
const { trigger, eventWatcher, callback } = create({
|
||||
trigger: 'event',
|
||||
event_type: 'zha_event',
|
||||
event_data: { command: 'press' },
|
||||
});
|
||||
trigger.subscribe(callback);
|
||||
const matcher = getLastMatcher(eventWatcher);
|
||||
expect(matcher?.(createHASSEvent('zha_event', { command: 'press' }))).toBe(true);
|
||||
expect(matcher?.(createHASSEvent('zha_event', { command: 'release' }))).toBe(false);
|
||||
});
|
||||
|
||||
it('should attach a context matcher', () => {
|
||||
const { trigger, eventWatcher, callback } = create({
|
||||
trigger: 'event',
|
||||
event_type: 'zha_event',
|
||||
context: { user_id: 'u-1' },
|
||||
});
|
||||
trigger.subscribe(callback);
|
||||
const matcher = getLastMatcher(eventWatcher);
|
||||
expect(
|
||||
matcher?.(
|
||||
createHASSEvent('zha_event', {}, { id: 'i', user_id: 'u-1', parent_id: null }),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
matcher?.(
|
||||
createHASSEvent('zha_event', {}, { id: 'i', user_id: 'u-2', parent_id: null }),
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should AND event_data and context filters', () => {
|
||||
const { trigger, eventWatcher, callback } = create({
|
||||
trigger: 'event',
|
||||
event_type: 'zha_event',
|
||||
event_data: { command: 'press' },
|
||||
context: { user_id: 'u-1' },
|
||||
});
|
||||
trigger.subscribe(callback);
|
||||
const matcher = getLastMatcher(eventWatcher);
|
||||
|
||||
const matchingContext = { id: 'i', user_id: 'u-1', parent_id: null };
|
||||
const nonMatchingContext = { id: 'i', user_id: 'u-2', parent_id: null };
|
||||
|
||||
expect(
|
||||
matcher?.(createHASSEvent('zha_event', { command: 'press' }, matchingContext)),
|
||||
).toBe(true);
|
||||
expect(
|
||||
matcher?.(createHASSEvent('zha_event', { command: 'press' }, nonMatchingContext)),
|
||||
).toBe(false);
|
||||
expect(
|
||||
matcher?.(createHASSEvent('zha_event', { command: 'release' }, matchingContext)),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should unsubscribe every request on destroy', () => {
|
||||
const { trigger, eventWatcher, callback } = create({
|
||||
trigger: 'event',
|
||||
event_type: ['zha_event', 'deconz_event'],
|
||||
});
|
||||
trigger.subscribe(callback);
|
||||
trigger.destroy();
|
||||
expect(eventWatcher.unsubscribe).toBeCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should be a no-op when destroyed without subscribing', () => {
|
||||
const { trigger, eventWatcher } = create({
|
||||
trigger: 'event',
|
||||
event_type: 'zha_event',
|
||||
});
|
||||
trigger.destroy();
|
||||
expect(eventWatcher.unsubscribe).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { ExpandTrigger } from '../../../../src/condition-trigger/triggers/triggers/expand';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('ExpandTrigger', () => {
|
||||
@@ -11,10 +11,10 @@ describe('ExpandTrigger', () => {
|
||||
): { stateManager: ConditionStateManager; callback: Mock } => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
new ExpandTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
}).subscribe(callback);
|
||||
new ExpandTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
).subscribe(callback);
|
||||
return { stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { FullscreenTrigger } from '../../../../src/condition-trigger/triggers/triggers/fullscreen';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('FullscreenTrigger', () => {
|
||||
@@ -15,10 +15,10 @@ describe('FullscreenTrigger', () => {
|
||||
} => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
const fullscreenTrigger = new FullscreenTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
});
|
||||
const fullscreenTrigger = new FullscreenTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
);
|
||||
return { fullscreenTrigger, stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { InteractionTrigger } from '../../../../src/condition-trigger/triggers/triggers/interaction';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('InteractionTrigger', () => {
|
||||
@@ -11,10 +11,10 @@ describe('InteractionTrigger', () => {
|
||||
): { stateManager: ConditionStateManager; callback: Mock } => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
new InteractionTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
}).subscribe(callback);
|
||||
new InteractionTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
).subscribe(callback);
|
||||
return { stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { MediaLoadedTrigger } from '../../../../src/condition-trigger/triggers/triggers/media-loaded';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createMediaLoadedInfo } from '../../../test-utils';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('MediaLoadedTrigger', () => {
|
||||
@@ -12,10 +12,10 @@ describe('MediaLoadedTrigger', () => {
|
||||
): { stateManager: ConditionStateManager; callback: Mock } => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
new MediaLoadedTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
}).subscribe(callback);
|
||||
new MediaLoadedTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
).subscribe(callback);
|
||||
return { stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { MicrophoneState } from '../../../../src/card-controller/types';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { MicrophoneTrigger } from '../../../../src/condition-trigger/triggers/triggers/microphone';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('MicrophoneTrigger', () => {
|
||||
@@ -19,10 +19,10 @@ describe('MicrophoneTrigger', () => {
|
||||
): { stateManager: ConditionStateManager; callback: Mock } => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
new MicrophoneTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
}).subscribe(callback);
|
||||
new MicrophoneTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
).subscribe(callback);
|
||||
return { stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { HassEntities, HassEntity } from 'home-assistant-js-websocket';
|
||||
import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { NumericStateTrigger } from '../../../../src/condition-trigger/triggers/triggers/numeric-state';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createHASS, createStateEntity } from '../../../test-utils';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
const SENSOR = 'sensor.temperature';
|
||||
const SENSOR_TWO = 'sensor.humidity';
|
||||
@@ -21,10 +21,10 @@ describe('NumericStateTrigger', () => {
|
||||
} => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
const trigger = new NumericStateTrigger(config, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
});
|
||||
const trigger = new NumericStateTrigger(
|
||||
config,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
);
|
||||
return { trigger, stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { HassEntities, HassEntity } from 'home-assistant-js-websocket';
|
||||
import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { StateTrigger } from '../../../../src/condition-trigger/triggers/triggers/state';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createHASS, createStateEntity } from '../../../test-utils';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
const ENTITY = 'binary_sensor.door';
|
||||
const ENTITY_TWO = 'binary_sensor.window';
|
||||
@@ -20,10 +20,10 @@ describe('StateTrigger', () => {
|
||||
} => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
const trigger = new StateTrigger(config, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
});
|
||||
const trigger = new StateTrigger(
|
||||
config,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
);
|
||||
return { trigger, stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { TemplateTrigger } from '../../../../src/condition-trigger/triggers/triggers/template';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createHASS, createStateEntity } from '../../../test-utils';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
const ENTITY_ONE = 'sensor.foo';
|
||||
const ENTITY_TWO = 'sensor.bar';
|
||||
@@ -21,10 +21,10 @@ describe('TemplateTrigger', () => {
|
||||
} => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
const trigger = new TemplateTrigger(config, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
});
|
||||
const trigger = new TemplateTrigger(
|
||||
config,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
);
|
||||
return { trigger, stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { TriggerEvaluatorContext } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createHASSManager } from '../../../test-utils';
|
||||
|
||||
export const createTriggerEvaluatorContext = (
|
||||
context?: Partial<TriggerEvaluatorContext>,
|
||||
): TriggerEvaluatorContext => ({
|
||||
stateManager: new ConditionStateManager(),
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
hassManager: createHASSManager(),
|
||||
...context,
|
||||
});
|
||||
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { TriggeredTrigger } from '../../../../src/condition-trigger/triggers/triggers/triggered';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('TriggeredTrigger', () => {
|
||||
@@ -11,10 +11,10 @@ describe('TriggeredTrigger', () => {
|
||||
): { stateManager: ConditionStateManager; callback: Mock } => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
new TriggeredTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
}).subscribe(callback);
|
||||
new TriggeredTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
).subscribe(callback);
|
||||
return { stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { TemplateRenderer } from '../../../../src/card-controller/templates';
|
||||
import { ConditionStateManager } from '../../../../src/condition-trigger/conditions/state-manager';
|
||||
import { TriggerOfType } from '../../../../src/condition-trigger/triggers/triggers/types';
|
||||
import { createTriggerEvaluatorContext } from './test-utils';
|
||||
import { ViewTrigger } from '../../../../src/condition-trigger/triggers/triggers/view';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
@@ -15,10 +15,10 @@ describe('ViewTrigger', () => {
|
||||
} => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const callback = vi.fn();
|
||||
const viewTrigger = new ViewTrigger(trigger, {
|
||||
stateManager,
|
||||
templateRenderer: new TemplateRenderer(),
|
||||
});
|
||||
const viewTrigger = new ViewTrigger(
|
||||
trigger,
|
||||
createTriggerEvaluatorContext({ stateManager }),
|
||||
);
|
||||
return { viewTrigger, stateManager, callback };
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user