Treat camera unavailability in a more friendly way.

Also creates a `components-lib` directory for major webcomponent support code.
This commit is contained in:
Dermot Duffy
2023-10-05 21:18:03 -07:00
parent 95e42ab767
commit d895c43e67
23 changed files with 207 additions and 89 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
import { ReactiveControllerHost } from 'lit';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { mock } from 'vitest-mock-extended';
import { CachedValueController } from '../src/cached-value-controller';
import { CachedValueController } from '../src/components-lib/cached-value-controller';
// @vitest-environment jsdom
describe('CachedValueController', () => {
@@ -5,7 +5,7 @@ import { MediaLoadedInfo } from '../../src/types';
import {
MediaGridConstructorOptions,
MediaGridController,
} from '../../src/utils/media-grid-controller';
} from '../../src/components-lib/media-grid-controller';
import { dispatchExistingMediaLoadedInfoAsEvent } from '../../src/utils/media-info';
import {
MutationObserverMock,
@@ -4,15 +4,15 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
import { mock } from 'vitest-mock-extended';
import { CameraManager } from '../../src/camera-manager/manager';
import { CameraManagerCameraMetadata } from '../../src/camera-manager/types';
import { FrigateCardConfig, MenuItem, ViewDisplayMode } from '../../src/config/types';
import { FrigateCardMediaPlayer } from '../../src/types';
import { createFrigateCardCustomAction } from '../../src/utils/action';
import { MediaPlayerManager } from '../../src/card-controller/media-player-manager';
import { MicrophoneManager } from '../../src/card-controller/microphone-manager';
import {
MenuButtonController,
MenuButtonControllerOptions,
} from '../../src/utils/menu-controller';
} from '../../src/components-lib/menu-controller';
import { FrigateCardConfig, MenuItem, ViewDisplayMode } from '../../src/config/types';
import { FrigateCardMediaPlayer } from '../../src/types';
import { createFrigateCardCustomAction } from '../../src/utils/action';
import { ViewMedia } from '../../src/view/media';
import { MediaQueriesResults } from '../../src/view/media-queries-results';
import { View } from '../../src/view/view';
@@ -1,8 +1,7 @@
import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
import { Zoom } from '../../src/utils/zoom/zoom';
import { PanzoomObject, PanzoomEventDetail } from '@dermotduffy/panzoom';
import Panzoom from '@dermotduffy/panzoom';
import Panzoom, { PanzoomEventDetail, PanzoomObject } from '@dermotduffy/panzoom';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { mock } from 'vitest-mock-extended';
import { ZoomController } from '../../src/components-lib/zoom-controller';
vi.mock('@dermotduffy/panzoom');
@@ -10,7 +9,7 @@ vi.mock('@dermotduffy/panzoom');
(window as any).PointerEvent = MouseEvent;
// @vitest-environment jsdom
describe('Zoom', () => {
describe('ZoomController', () => {
const mediaMediSpy = vi.spyOn(window, 'matchMedia');
const createMockPanZoom = (): PanzoomObject => {
@@ -19,8 +18,8 @@ describe('Zoom', () => {
return panzoom;
};
const createAndRegisterZoom = (element: HTMLElement): Zoom => {
const zoom = new Zoom(element);
const createAndRegisterZoom = (element: HTMLElement): ZoomController => {
const zoom = new ZoomController(element);
zoom.activate();
return zoom;
};
@@ -52,7 +51,7 @@ describe('Zoom', () => {
it('should be creatable', () => {
const element = document.createElement('div');
const zoom = new Zoom(element);
const zoom = new ZoomController(element);
expect(zoom).toBeTruthy();
});
+72
View File
@@ -0,0 +1,72 @@
import { describe, expect, it, vi } from 'vitest';
import { createCameraConfig, createHASS, createStateEntity } from '../test-utils';
import { getStateObjOrDispatchError } from '../../src/utils/get-state-obj';
// @vitest-environment jsdom
describe('getStateObjOrDispatchError', () => {
it('should retrieve valid state object', () => {
const messageHandler = vi.fn();
const element = document.createElement('div');
element.addEventListener('frigate-card:message', messageHandler);
const state = createStateEntity();
expect(
getStateObjOrDispatchError(
element,
createHASS({
'camera.test': state,
}),
createCameraConfig({
camera_entity: 'camera.test',
}),
),
).toBe(state);
expect(messageHandler).not.toBeCalled();
});
it('should dispatch unspecified entity', () => {
const messageHandler = vi.fn();
const element = document.createElement('div');
element.addEventListener('frigate-card:message', messageHandler);
expect(
getStateObjOrDispatchError(element, createHASS(), createCameraConfig()),
).toBeNull();
expect(messageHandler).toBeCalledWith(
expect.objectContaining({
detail: expect.objectContaining({
message:
'The camera_entity parameter must be set and valid for this live provider',
type: 'error',
}),
}),
);
});
it('should dispatch not found state', () => {
const messageHandler = vi.fn();
const element = document.createElement('div');
element.addEventListener('frigate-card:message', messageHandler);
expect(
getStateObjOrDispatchError(
element,
createHASS(),
createCameraConfig({
camera_entity: 'camera.will-not-be-found',
}),
),
).toBeNull();
expect(messageHandler).toBeCalledWith(
expect.objectContaining({
detail: expect.objectContaining({
message: 'The configured camera_entity was not found',
type: 'error',
}),
}),
);
});
});