Use custom websocket to avoid needing admin privileges.

This commit is contained in:
Dermot Duffy
2024-08-24 20:00:00 -07:00
parent 5a1d08f3ea
commit 429dd90972
47 changed files with 1219 additions and 874 deletions
+16 -11
View File
@@ -103,36 +103,40 @@ describe('contentsChanged', () => {
describe('errorToConsole', () => {
const spy = vi.spyOn(global.console, 'warn').mockImplementation(() => true);
afterAll(() => {
vi.restoreAllMocks();
});
it('should log given error', () => {
const error = new Error();
const error = new Error('ERROR');
errorToConsole(error);
expect(spy).toHaveBeenCalledWith(error);
expect(spy).toHaveBeenCalledWith('ERROR');
});
it('should log with context given frigate card error', () => {
const data = { foo: 2 };
const error = new FrigateCardError('foo', { foo: 2 });
const error = new FrigateCardError('ERROR', { foo: 2 });
errorToConsole(error);
expect(spy).toHaveBeenCalledWith(error, data);
});
it('should log with custom function', () => {
const func = vi.fn();
const error = new Error();
const error = new Error('ERROR');
errorToConsole(error, func);
expect(func).toHaveBeenCalledWith(error);
expect(func).toHaveBeenCalledWith('ERROR');
});
});
describe('isHoverableDevice', () => {
afterAll(() => {
vi.restoreAllMocks();
});
it('should return hoverable', () => {
const spy = vi
.spyOn(window, 'matchMedia')
.mockReturnValue(<MediaQueryList>{ matches: true });
vi.spyOn(window, 'matchMedia').mockReturnValue(<MediaQueryList>{ matches: true });
expect(isHoverableDevice()).toBeTruthy();
});
it('should return not hoverable', () => {
const spy = vi
.spyOn(window, 'matchMedia')
.mockReturnValue(<MediaQueryList>{ matches: false });
vi.spyOn(window, 'matchMedia').mockReturnValue(<MediaQueryList>{ matches: false });
expect(isHoverableDevice()).toBeFalsy();
});
});
@@ -225,6 +229,7 @@ describe('sleep', () => {
it('should sleep', async () => {
const spy = vi
.spyOn(global, 'setTimeout')
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
.mockImplementation((func: () => unknown, _time?: number): any => {
func();
});
+1 -105
View File
@@ -1,10 +1,8 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { describe, expect, it } from 'vitest';
import {
getEntityIcon,
hasHAConnectionStateChanged,
parseStateChangeTrigger,
subscribeToTrigger,
} from '../../../src/utils/ha/index.js';
import { createHASS, createStateEntity } from '../../test-utils.js';
@@ -69,105 +67,3 @@ describe('getEntityIcon', () => {
expect(getEntityIcon(createHASS(), 'camera.test')).toBe('mdi:video');
});
});
describe('should subscribe to trigger', () => {
it('mqtt', async () => {
const hass = createHASS();
const callback = vi.fn();
await subscribeToTrigger(hass, callback, {
platform: 'mqtt',
topic: 'topic',
payload: 'payload',
valueTemplate: 'value_template',
});
expect(hass.connection.subscribeMessage).toBeCalledWith(callback, {
type: 'subscribe_trigger',
trigger: {
platform: 'mqtt',
topic: 'topic',
payload: 'payload',
value_template: 'value_template',
},
});
});
it('state and attributes', async () => {
const hass = createHASS();
const callback = vi.fn();
await subscribeToTrigger(hass, callback, {
platform: 'state',
entityID: 'camera.foo',
});
expect(hass.connection.subscribeMessage).toBeCalledWith(callback, {
type: 'subscribe_trigger',
trigger: {
platform: 'state',
entity_id: 'camera.foo',
},
});
});
it('state only', async () => {
const hass = createHASS();
const callback = vi.fn();
await subscribeToTrigger(hass, callback, {
platform: 'state',
entityID: 'camera.foo',
stateOnly: true,
});
expect(hass.connection.subscribeMessage).toBeCalledWith(callback, {
type: 'subscribe_trigger',
trigger: {
platform: 'state',
entity_id: 'camera.foo',
from: null,
to: null,
},
});
});
});
describe('should parse state change response', () => {
beforeEach(() => {
vi.restoreAllMocks();
});
it('malformed response', async () => {
const consoleSpy = vi.spyOn(global.console, 'warn').mockReturnValue(undefined);
expect(parseStateChangeTrigger('INVALID')).toBeNull();
expect(consoleSpy).toBeCalledWith('Ignoring unparseable HA state change', 'INVALID');
});
it('valid response', async () => {
const consoleSpy = vi.spyOn(global.console, 'warn').mockReturnValue(undefined);
const stateChange = {
from_state: {
entity_id: 'camera.foo',
state: 'off',
},
to_state: {
entity_id: 'camera.foo',
state: 'on',
},
};
expect(
parseStateChangeTrigger({
variables: {
trigger: stateChange,
},
}),
).toEqual(stateChange);
expect(consoleSpy).not.toBeCalled();
});
});