Refactor views to support dynamic updates.

This commit is contained in:
Dermot Duffy committed 2024-07-26 19:15:38 -07:00
1 parent 33dee47205
commit d5c4e56c45
80 files changed
+3714 -4021

No files matched your search

@@ -0,0 +1,28 @@
import { ViewContext } from 'view';
import { expect, it } from 'vitest';
import { MergeContextViewModifier } from '../../../../src/card-controller/view/modifiers/merge-context';
import { createView } from '../../../test-utils';
it('should merge context', () => {
const context: ViewContext = {
timeline: {
window: {
start: new Date(),
end: new Date(),
},
},
};
const modifier = new MergeContextViewModifier(context);
const view = createView({
view: 'live',
camera: 'camera',
displayMode: 'grid',
});
expect(view.context).toBeNull();
modifier.modify(view);
expect(view.context).toEqual(context);
});
@@ -0,0 +1,25 @@
import { expect, it } from 'vitest';
import { createView } from '../../../test-utils';
import { RemoveContextPropertyViewModifier } from '../../../../src/card-controller/view/modifiers/remove-context-property';
it('should remove context property', () => {
const modifier = new RemoveContextPropertyViewModifier('timeline', 'window');
const view = createView({
view: 'live',
camera: 'camera',
displayMode: 'grid',
context: {
timeline: {
window: {
start: new Date(),
end: new Date(),
},
},
},
});
modifier.modify(view);
expect(view.context).toEqual({ timeline: {} });
});
@@ -0,0 +1,26 @@
import { expect, it } from 'vitest';
import { createView } from '../../../test-utils';
import { RemoveContextViewModifier } from '../../../../src/card-controller/view/modifiers/remove-context';
it('should remove context property', () => {
const modifier = new RemoveContextViewModifier(['timeline']);
const view = createView({
view: 'live',
camera: 'camera',
displayMode: 'grid',
context: {
timeline: {
window: {
start: new Date(),
end: new Date(),
},
},
},
});
modifier.modify(view);
expect(view.context).toEqual({});
});
@@ -0,0 +1,20 @@
import { expect, it } from 'vitest';
import { createView } from '../../../test-utils';
import { SubstreamOffViewModifier } from '../../../../src/card-controller/view/modifiers/substream-off';
import { hasSubstream, setSubstream } from '../../../../src/utils/substream';
it('should turn off substream', () => {
const view = createView({
view: 'live',
camera: 'camera',
displayMode: 'grid',
});
setSubstream(view, 'substream');
expect(hasSubstream(view)).toBe(true);
const modifier = new SubstreamOffViewModifier();
modifier.modify(view);
expect(hasSubstream(view)).toBe(false);
});
@@ -0,0 +1,101 @@
import { describe, expect, it, vi } from 'vitest';
import { CardController } from '../../../../src/card-controller/controller';
import { SubstreamOnViewModifier } from '../../../../src/card-controller/view/modifiers/substream-on';
import { RawFrigateCardConfig } from '../../../../src/config/types';
import { getStreamCameraID, hasSubstream, setSubstream } from '../../../../src/utils/substream';
import {
createCameraConfig,
createCameraManager,
createCapabilities,
createCardAPI,
createConfig,
createStore,
createView,
} from '../../../test-utils';
const createAPIWithSubstreams = (config?: RawFrigateCardConfig): CardController => {
const api = createCardAPI();
vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager());
vi.mocked(api.getCameraManager().getStore).mockReturnValue(
createStore([
{
cameraID: 'camera.office',
capabilities: createCapabilities({
live: true,
substream: true,
}),
config: createCameraConfig({
dependencies: {
all_cameras: true,
},
}),
},
{
cameraID: 'camera.kitchen',
capabilities: createCapabilities({
substream: true,
}),
},
]),
);
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(createConfig(config));
return api;
};
describe('should turn on substream', () => {
it('substream available', () => {
const view = createView({
view: 'live',
camera: 'camera.office',
});
expect(hasSubstream(view)).toBe(false);
const api = createAPIWithSubstreams();
const modifier = new SubstreamOnViewModifier(api);
modifier.modify(view);
expect(hasSubstream(view)).toBe(true);
expect(getStreamCameraID(view)).toBe('camera.kitchen');
modifier.modify(view);
expect(hasSubstream(view)).toBe(false);
expect(getStreamCameraID(view)).toBe('camera.office');
});
it('malformed substream', () => {
const view = createView({
view: 'live',
camera: 'camera.office',
});
const api = createAPIWithSubstreams();
setSubstream(view, 'NOT_A_REAL_CAMERA');
const modifier = new SubstreamOnViewModifier(api);
modifier.modify(view);
expect(hasSubstream(view)).toBe(false);
expect(getStreamCameraID(view)).toBe('camera.office');
});
it('substream unavailable', () => {
const view = createView({
view: 'live',
camera: 'camera.office',
});
expect(hasSubstream(view)).toBe(false);
const api = createCardAPI();
vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager());
const modifier = new SubstreamOnViewModifier(api);
modifier.modify(view);
expect(hasSubstream(view)).toBe(false);
});
});
@@ -0,0 +1,19 @@
import { expect, it } from 'vitest';
import { SubstreamSelectViewModifier } from '../../../../src/card-controller/view/modifiers/substream-select';
import { getStreamCameraID, hasSubstream } from '../../../../src/utils/substream';
import { createView } from '../../../test-utils';
it('should select substream', () => {
const view = createView({
view: 'live',
camera: 'camera.office',
});
expect(hasSubstream(view)).toBe(false);
const modifier = new SubstreamSelectViewModifier('substream');
modifier.modify(view);
expect(hasSubstream(view)).toBe(true);
expect(getStreamCameraID(view)).toBe('substream');
});