140 lines
4.9 KiB
TypeScript
140 lines
4.9 KiB
TypeScript
import { assert, describe, expect, it } from 'vitest';
|
|
|
|
import {
|
|
applyConfigChanges,
|
|
computeConfigChanges,
|
|
computeDisplayedData,
|
|
} from '../../../src/components-lib/editor/form-data';
|
|
import {
|
|
deriveEditorMode,
|
|
getEditorMode,
|
|
} from '../../../src/components-lib/editor/mode';
|
|
import { getSimpleMenuForms } from '../../../src/components-lib/editor/schema/simple';
|
|
import { getConfigValue } from '../../../src/config/management';
|
|
import { configDefaults } from '../../../src/config/schema/types';
|
|
|
|
// The card type is in every configuration Home Assistant hands the editor.
|
|
const createConfig = (config: Record<string, unknown> = {}) => ({
|
|
type: 'custom:advanced-camera-card',
|
|
...config,
|
|
});
|
|
|
|
describe('deriveEditorMode', () => {
|
|
it('should choose the simple editor for a configuration that sets nothing', () => {
|
|
expect(deriveEditorMode(createConfig())).toBe('simple');
|
|
});
|
|
|
|
it('should choose the simple editor for the settings it shows', () => {
|
|
expect(
|
|
deriveEditorMode(
|
|
createConfig({
|
|
cameras: [
|
|
{ camera_entity: 'camera.office', live_provider: 'go2rtc' },
|
|
{ camera_entity: 'camera.kitchen', title: 'Kitchen', icon: 'mdi:cctv' },
|
|
],
|
|
menu: {
|
|
style: 'outside',
|
|
position: 'left',
|
|
buttons: { clips: { enabled: true } },
|
|
},
|
|
dimensions: { aspect_ratio_mode: 'static', aspect_ratio: '16:9' },
|
|
view: { default: 'clips' },
|
|
profiles: ['casting'],
|
|
}),
|
|
),
|
|
).toBe('simple');
|
|
});
|
|
|
|
it('should choose the full editor for a setting the simple editor does not show', () => {
|
|
expect(deriveEditorMode(createConfig({ view: { dim: true } }))).toBe('full');
|
|
});
|
|
|
|
it('should choose the full editor for a menu button property it does not show', () => {
|
|
expect(
|
|
deriveEditorMode(createConfig({ menu: { buttons: { clips: { priority: 5 } } } })),
|
|
).toBe('full');
|
|
});
|
|
|
|
it.each([
|
|
[{ live: { preload: true } }],
|
|
[{ timeline: { window_seconds: 7200 } }],
|
|
[{ folders: [{ type: 'ha' }] }],
|
|
[{ cameras: [{ camera_entity: 'camera.office', engine: 'frigate' }] }],
|
|
])('should choose the full editor for %j', (config) => {
|
|
expect(deriveEditorMode(createConfig(config))).toBe('full');
|
|
});
|
|
|
|
it.each([
|
|
// Not a setting of the card at all.
|
|
[{ fake: true }],
|
|
|
|
// Settings the full editor does not show either, so sending the user there
|
|
// would show them nothing more.
|
|
[{ debug: { logging: true } }],
|
|
[{ card_mod: { style: 'body {}' } }],
|
|
[{ cameras_global: { live_provider: 'go2rtc' } }],
|
|
[{ elements: [{ type: 'custom:foo' }] }],
|
|
[{ automations: [{ conditions: [{ condition: 'fullscreen' }] }] }],
|
|
[{ overrides: [{ merge: { menu: { style: 'none' } } }] }],
|
|
[{ cameras: [{ camera_entity: 'camera.office', ptz: { presets: {} } }] }],
|
|
])('should choose the simple editor for %j', (config) => {
|
|
expect(deriveEditorMode(createConfig(config))).toBe('simple');
|
|
});
|
|
|
|
it('should disregard a section that sets nothing', () => {
|
|
expect(deriveEditorMode(createConfig({ live: {}, folders: [{}] }))).toBe('simple');
|
|
});
|
|
|
|
it('should disregard the editor mode itself', () => {
|
|
expect(deriveEditorMode(createConfig({ editor: { mode: 'full' } }))).toBe('simple');
|
|
});
|
|
});
|
|
|
|
describe('getEditorMode', () => {
|
|
it.each([['simple' as const], ['full' as const]])(
|
|
'should use the configured %s mode',
|
|
(mode) => {
|
|
// A configuration the derivation would send to the other editor, so that
|
|
// the configured mode is what the result comes from.
|
|
const config = createConfig({
|
|
editor: { mode },
|
|
...(mode === 'simple' ? { view: { dim: true } } : {}),
|
|
});
|
|
expect(getEditorMode(config)).toBe(mode);
|
|
},
|
|
);
|
|
|
|
it('should derive the mode when the configuration does not say', () => {
|
|
expect(getEditorMode(createConfig())).toBe('simple');
|
|
expect(getEditorMode(createConfig({ view: { dim: true } }))).toBe('full');
|
|
});
|
|
|
|
it('should derive the mode when the configured one is not an editor', () => {
|
|
expect(getEditorMode(createConfig({ editor: { mode: 'simpel' } }))).toBe('simple');
|
|
});
|
|
|
|
it('should still choose the simple editor after an edit made in it', () => {
|
|
const config = createConfig({ cameras: [{ camera_entity: 'camera.office' }] });
|
|
expect(getEditorMode(config)).toBe('simple');
|
|
|
|
// A menu style chosen in the simple editor, written the way the editor
|
|
// writes it.
|
|
const [form] = getSimpleMenuForms();
|
|
const displayed = computeDisplayedData(form, config, configDefaults);
|
|
const edited = applyConfigChanges(
|
|
config,
|
|
computeConfigChanges(
|
|
form,
|
|
displayed,
|
|
{ ...displayed, menu_style: 'outside' },
|
|
config,
|
|
configDefaults,
|
|
),
|
|
);
|
|
assert(edited);
|
|
|
|
expect(getConfigValue(edited, 'menu.style')).toBe('outside');
|
|
expect(getEditorMode(edited)).toBe('simple');
|
|
});
|
|
});
|