Allow camera capabilities to be configured.
This commit is contained in:
@@ -3,6 +3,7 @@ import startOfDay from 'date-fns/startOfDay';
|
||||
import sub from 'date-fns/sub';
|
||||
import { LitElement } from 'lit';
|
||||
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { Capabilities } from '../../src/camera-manager/capabilities';
|
||||
import { CameraManagerStore } from '../../src/camera-manager/store';
|
||||
import { QueryType } from '../../src/camera-manager/types';
|
||||
import {
|
||||
@@ -10,21 +11,21 @@ import {
|
||||
MediaFilterCoreDefaults,
|
||||
MediaFilterCoreFavoriteSelection,
|
||||
MediaFilterCoreWhen,
|
||||
MediaFilterMediaType
|
||||
MediaFilterMediaType,
|
||||
} from '../../src/components-lib/media-filter-controller';
|
||||
import { executeMediaQueryForViewWithErrorDispatching } from '../../src/utils/media-to-view';
|
||||
import {
|
||||
EventMediaQueries,
|
||||
MediaQueries,
|
||||
RecordingMediaQueries
|
||||
RecordingMediaQueries,
|
||||
} from '../../src/view/media-queries';
|
||||
import {
|
||||
createAggregateCameraCapabilities,
|
||||
createCameraConfig,
|
||||
createCameraManager,
|
||||
createCapabilities,
|
||||
createPerformanceConfig,
|
||||
createStore,
|
||||
createView
|
||||
createView,
|
||||
} from '../test-utils';
|
||||
|
||||
vi.mock('../../src/utils/media-to-view');
|
||||
@@ -35,13 +36,22 @@ const createHost = (): LitElement => {
|
||||
return host;
|
||||
};
|
||||
|
||||
const createCameraStore = (): CameraManagerStore => {
|
||||
const createCameraStore = (options?: {
|
||||
capabilities: Capabilities;
|
||||
}): CameraManagerStore => {
|
||||
return createStore([
|
||||
{
|
||||
cameraID: 'camera.kitchen',
|
||||
config: createCameraConfig({
|
||||
camera_entity: 'camera.kitchen',
|
||||
}),
|
||||
capabilities:
|
||||
options?.capabilities ??
|
||||
new Capabilities({
|
||||
clips: true,
|
||||
snapshots: true,
|
||||
recordings: true,
|
||||
}),
|
||||
},
|
||||
]);
|
||||
};
|
||||
@@ -152,6 +162,27 @@ describe('MediaFilterController', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('with camera that does not support media', () => {
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager.getCameraMetadata).mockReturnValue({
|
||||
title: 'Kitchen Camera',
|
||||
icon: 'mdi:camera',
|
||||
});
|
||||
vi.mocked(cameraManager.getStore).mockReturnValue(
|
||||
createCameraStore({
|
||||
capabilities: new Capabilities({
|
||||
clips: false,
|
||||
snapshots: false,
|
||||
recordings: false,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
const controller = new MediaFilterController(createHost());
|
||||
controller.computeCameraOptions(cameraManager);
|
||||
expect(controller.getCameraOptions()).toEqual([]);
|
||||
});
|
||||
|
||||
it('without camera metadata', () => {
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager.getCameraMetadata).mockReturnValue(null);
|
||||
@@ -297,7 +328,7 @@ describe('MediaFilterController', () => {
|
||||
const view = createView({ query: new EventMediaQueries() });
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager.getAggregateCameraCapabilities).mockReturnValue(
|
||||
createAggregateCameraCapabilities({ canFavoriteEvents: true }),
|
||||
createCapabilities({ 'favorite-events': true }),
|
||||
);
|
||||
|
||||
const controller = new MediaFilterController(createHost());
|
||||
@@ -310,7 +341,7 @@ describe('MediaFilterController', () => {
|
||||
const view = createView({ query: new RecordingMediaQueries() });
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager.getAggregateCameraCapabilities).mockReturnValue(
|
||||
createAggregateCameraCapabilities({ canFavoriteRecordings: true }),
|
||||
createCapabilities({ 'favorite-recordings': true }),
|
||||
);
|
||||
|
||||
const controller = new MediaFilterController(createHost());
|
||||
@@ -915,7 +946,7 @@ describe('MediaFilterController', () => {
|
||||
},
|
||||
]),
|
||||
{
|
||||
mediaType: MediaFilterMediaType.Recordings
|
||||
mediaType: MediaFilterMediaType.Recordings,
|
||||
},
|
||||
],
|
||||
])(
|
||||
|
||||
@@ -18,7 +18,7 @@ import { ViewMedia } from '../../src/view/media';
|
||||
import { MediaQueriesResults } from '../../src/view/media-queries-results';
|
||||
import { View } from '../../src/view/view';
|
||||
import {
|
||||
createCameraCapabilities,
|
||||
createCapabilities,
|
||||
createCameraConfig,
|
||||
createCameraManager,
|
||||
createCardAPI,
|
||||
@@ -108,7 +108,11 @@ describe('MenuButtonController', () => {
|
||||
it('with multiple cameras', () => {
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager.getStore).mockReturnValue(
|
||||
createStore([{ cameraID: 'camera-1' }, { cameraID: 'camera-2' }]),
|
||||
createStore([
|
||||
{ cameraID: 'camera-1', capabilities: createCapabilities({ menu: true }) },
|
||||
{ cameraID: 'camera-2', capabilities: createCapabilities({ menu: true }) },
|
||||
{ cameraID: 'camera-3', capabilities: createCapabilities({ menu: false }) },
|
||||
]),
|
||||
);
|
||||
vi.mocked(cameraManager).getCameraMetadata.mockReturnValue({
|
||||
title: 'title',
|
||||
@@ -181,7 +185,10 @@ describe('MenuButtonController', () => {
|
||||
cameraID: 'camera-1',
|
||||
config: createCameraConfig({ dependencies: { cameras: ['camera-2'] } }),
|
||||
},
|
||||
{ cameraID: 'camera-2' },
|
||||
{
|
||||
cameraID: 'camera-2',
|
||||
capabilities: createCapabilities({ substream: true }),
|
||||
},
|
||||
]),
|
||||
);
|
||||
const buttons = calculateButtons(controller, { cameraManager: cameraManager });
|
||||
@@ -208,7 +215,10 @@ describe('MenuButtonController', () => {
|
||||
cameraID: 'camera-1',
|
||||
config: createCameraConfig({ dependencies: { cameras: ['camera-2'] } }),
|
||||
},
|
||||
{ cameraID: 'camera-2' },
|
||||
{
|
||||
cameraID: 'camera-2',
|
||||
capabilities: createCapabilities({ substream: true }),
|
||||
},
|
||||
]),
|
||||
);
|
||||
const view = createView({
|
||||
@@ -248,18 +258,21 @@ describe('MenuButtonController', () => {
|
||||
camera_entity: 'camera.1',
|
||||
dependencies: { cameras: ['camera-2', 'camera-3'] },
|
||||
}),
|
||||
capabilities: createCapabilities({ substream: true }),
|
||||
},
|
||||
{
|
||||
cameraID: 'camera-2',
|
||||
config: createCameraConfig({
|
||||
camera_entity: 'camera.2',
|
||||
}),
|
||||
capabilities: createCapabilities({ substream: true }),
|
||||
},
|
||||
{
|
||||
cameraID: 'camera-3',
|
||||
config: createCameraConfig({
|
||||
camera_entity: 'camera.3',
|
||||
}),
|
||||
capabilities: createCapabilities({ substream: true }),
|
||||
},
|
||||
]),
|
||||
);
|
||||
@@ -340,18 +353,21 @@ describe('MenuButtonController', () => {
|
||||
camera_entity: 'camera.1',
|
||||
dependencies: { cameras: ['camera-2', 'camera-3'] },
|
||||
}),
|
||||
capabilities: createCapabilities({ substream: true }),
|
||||
},
|
||||
{
|
||||
cameraID: 'camera-2',
|
||||
config: createCameraConfig({
|
||||
camera_entity: 'camera.2',
|
||||
}),
|
||||
capabilities: createCapabilities({ substream: true }),
|
||||
},
|
||||
{
|
||||
cameraID: 'camera-3',
|
||||
config: createCameraConfig({
|
||||
camera_entity: 'camera.3',
|
||||
}),
|
||||
capabilities: createCapabilities({ substream: true }),
|
||||
},
|
||||
]),
|
||||
);
|
||||
@@ -1207,10 +1223,17 @@ describe('MenuButtonController', () => {
|
||||
it.each([['single' as const], ['grid' as const]])(
|
||||
'%s',
|
||||
(displayMode: ViewDisplayMode) => {
|
||||
const view = createView({ view: 'live', displayMode: displayMode });
|
||||
const view = createView({
|
||||
camera: 'camera-1',
|
||||
view: 'live',
|
||||
displayMode: displayMode,
|
||||
});
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager.getStore).mockReturnValue(
|
||||
createStore([{ cameraID: 'camera-1' }, { cameraID: 'camera-2' }]),
|
||||
createStore([
|
||||
{ cameraID: 'camera-1', capabilities: createCapabilities({ live: true }) },
|
||||
{ cameraID: 'camera-2', capabilities: createCapabilities({ live: true }) },
|
||||
]),
|
||||
);
|
||||
|
||||
expect(
|
||||
@@ -1239,7 +1262,7 @@ describe('MenuButtonController', () => {
|
||||
it('when the selected camera is not PTZ enabled', () => {
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager.getCameraCapabilities).mockReturnValue(
|
||||
createCameraCapabilities(),
|
||||
createCapabilities(),
|
||||
);
|
||||
|
||||
const buttons = calculateButtons(controller, { cameraManager: cameraManager });
|
||||
@@ -1264,7 +1287,7 @@ describe('MenuButtonController', () => {
|
||||
it('when the selected camera is PTZ enabled', () => {
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager.getCameraCapabilities).mockReturnValue(
|
||||
createCameraCapabilities({ ptz: {} }),
|
||||
createCapabilities({ ptz: { panTilt: ['relative'] } }),
|
||||
);
|
||||
const buttons = calculateButtons(controller, { cameraManager: cameraManager });
|
||||
|
||||
@@ -1288,7 +1311,7 @@ describe('MenuButtonController', () => {
|
||||
it('when the context has PTZ visiblity turned off', () => {
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager.getCameraCapabilities).mockReturnValue(
|
||||
createCameraCapabilities({ ptz: {} }),
|
||||
createCapabilities({ ptz: { panTilt: ['relative'] } }),
|
||||
);
|
||||
const view = createView({
|
||||
camera: 'camera-1',
|
||||
@@ -1328,9 +1351,9 @@ describe('MenuButtonController', () => {
|
||||
vi.mocked(cameraManager.getCameraCapabilities).mockImplementation(
|
||||
(cameraID: string) => {
|
||||
if (cameraID === 'camera-2') {
|
||||
return createCameraCapabilities({ ptz: {} });
|
||||
return createCapabilities({ ptz: { panTilt: ['relative'] } });
|
||||
}
|
||||
return createCameraCapabilities();
|
||||
return createCapabilities();
|
||||
},
|
||||
);
|
||||
const view = createView({
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
getActionConfigGivenAction,
|
||||
} from '../../src/utils/action.js';
|
||||
import {
|
||||
createCameraCapabilities,
|
||||
createCapabilities,
|
||||
createCameraManager,
|
||||
createHASS,
|
||||
} from '../test-utils';
|
||||
@@ -145,7 +145,7 @@ describe('PTZController', () => {
|
||||
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager).getCameraCapabilities.mockReturnValue(
|
||||
createCameraCapabilities({
|
||||
createCapabilities({
|
||||
ptz: {
|
||||
panTilt: ['continuous'],
|
||||
zoom: ['continuous'],
|
||||
@@ -185,7 +185,7 @@ describe('PTZController', () => {
|
||||
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager).getCameraCapabilities.mockReturnValue(
|
||||
createCameraCapabilities({
|
||||
createCapabilities({
|
||||
ptz: {
|
||||
panTilt: ['relative'],
|
||||
zoom: ['relative'],
|
||||
@@ -210,7 +210,7 @@ describe('PTZController', () => {
|
||||
|
||||
const cameraManager = createCameraManager();
|
||||
vi.mocked(cameraManager).getCameraCapabilities.mockReturnValue(
|
||||
createCameraCapabilities({
|
||||
createCapabilities({
|
||||
ptz: {
|
||||
presets: ['preset-foo'],
|
||||
},
|
||||
@@ -237,7 +237,7 @@ describe('PTZController', () => {
|
||||
['down' as const],
|
||||
['zoom_in' as const],
|
||||
['zoom_out' as const],
|
||||
])('%s', (actionName: PTZControlAction) => {
|
||||
])('configured %s', (actionName: PTZControlAction) => {
|
||||
const controller = new PTZController(document.createElement('div'));
|
||||
controller.setConfig(
|
||||
createConfig({
|
||||
@@ -253,7 +253,7 @@ describe('PTZController', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('home', () => {
|
||||
it('configured home', () => {
|
||||
const controller = new PTZController(document.createElement('div'));
|
||||
controller.setConfig(
|
||||
createConfig({
|
||||
|
||||
Reference in New Issue
Block a user