feat: Add support for config and initialized conditions (#1894)
These conditions are probably not hugely useful for most card users, but allows the inbuilt automation systems to be used for card internal operations. [skip ci]
This commit is contained in:
1 parent
7fb710d45d
commit
da79664a67
10 files changed
+313
-35
No files matched your search
@@ -349,6 +349,8 @@ describe('ConfigManager', () => {
|
||||
it('should initialize background items', async () => {
|
||||
const api = createCardAPI();
|
||||
const stateManager = new ConditionStateManager();
|
||||
const listener = vi.fn();
|
||||
stateManager.addListener(listener);
|
||||
vi.mocked(api.getConditionStateManager).mockReturnValue(stateManager);
|
||||
|
||||
const manager = new ConfigManager(api);
|
||||
@@ -371,13 +373,24 @@ describe('ConfigManager', () => {
|
||||
|
||||
expect(api.getDefaultManager().initializeIfNecessary).toBeCalledTimes(1);
|
||||
expect(api.getMediaPlayerManager().initializeIfNecessary).toBeCalledTimes(1);
|
||||
expect(listener).not.toBeCalledWith(
|
||||
expect.objectContaining({ change: { config: expect.anything() } }),
|
||||
);
|
||||
|
||||
vi.mocked(api.getInitializationManager().isInitializedMandatory).mockReturnValue(
|
||||
true,
|
||||
);
|
||||
stateManager.setState({ fullscreen: true });
|
||||
|
||||
await flushPromises();
|
||||
|
||||
expect(api.getDefaultManager().initializeIfNecessary).toBeCalledTimes(2);
|
||||
expect(api.getMediaPlayerManager().initializeIfNecessary).toBeCalledTimes(2);
|
||||
|
||||
// Should set the config condition state.
|
||||
expect(listener).toBeCalledWith(
|
||||
expect.objectContaining({ change: { config: expect.anything() } }),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
InitializationAspect,
|
||||
InitializationManager,
|
||||
} from '../../src/card-controller/initialization-manager';
|
||||
import { ConditionStateManager } from '../../src/conditions/state-manager';
|
||||
import { loadLanguages } from '../../src/localize/localize';
|
||||
import { sideLoadHomeAssistantElements } from '../../src/utils/ha';
|
||||
import { Initializer } from '../../src/utils/initializer/initializer';
|
||||
@@ -67,9 +68,15 @@ describe('InitializationManager', () => {
|
||||
});
|
||||
|
||||
it('successfully', async () => {
|
||||
const stateListener = vi.fn();
|
||||
const stateMananger = new ConditionStateManager();
|
||||
stateMananger.addListener(stateListener);
|
||||
|
||||
const api = createCardAPI();
|
||||
vi.mocked(api.getConditionStateManager).mockReturnValue(stateMananger);
|
||||
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(createHASS());
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(createConfig());
|
||||
const config = createConfig();
|
||||
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(config);
|
||||
vi.mocked(api.getMessageManager().hasMessage).mockReturnValue(false);
|
||||
vi.mocked(api.getQueryStringManager().hasViewRelatedActionsToRun).mockReturnValue(
|
||||
false,
|
||||
@@ -93,6 +100,15 @@ describe('InitializationManager', () => {
|
||||
expect(api.getCardElementManager().update).toBeCalled();
|
||||
|
||||
expect(manager.wasEverInitialized()).toBeTruthy();
|
||||
|
||||
expect(stateListener).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
change: {
|
||||
initialized: true,
|
||||
config,
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('successfully with microphone if configured', async () => {
|
||||
|
||||
@@ -2,7 +2,12 @@ import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
import { MicrophoneState } from '../../src/card-controller/types';
|
||||
import { ConditionsManager } from '../../src/conditions/conditions-manager';
|
||||
import { ConditionStateManager } from '../../src/conditions/state-manager';
|
||||
import { createMediaLoadedInfo, createStateEntity, createUser } from '../test-utils';
|
||||
import {
|
||||
createConfig,
|
||||
createMediaLoadedInfo,
|
||||
createStateEntity,
|
||||
createUser,
|
||||
} from '../test-utils';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
describe('ConditionsManager', () => {
|
||||
@@ -841,6 +846,146 @@ describe('ConditionsManager', () => {
|
||||
expect(manager.getEvaluation().result).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with config condition', () => {
|
||||
const config_1 = createConfig({
|
||||
// Default is:
|
||||
//
|
||||
// view: {
|
||||
// default: live,
|
||||
// },
|
||||
});
|
||||
const config_2 = createConfig({
|
||||
view: {
|
||||
default: 'clips',
|
||||
},
|
||||
});
|
||||
const config_3 = createConfig({
|
||||
view: {
|
||||
default: 'clips',
|
||||
default_cycle_camera: true,
|
||||
},
|
||||
});
|
||||
const config_4 = createConfig({
|
||||
view: {
|
||||
default: 'clips',
|
||||
default_cycle_camera: true,
|
||||
dim: true,
|
||||
},
|
||||
});
|
||||
|
||||
it('should match any config change', () => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const manager = new ConditionsManager(
|
||||
[{ condition: 'config' as const }],
|
||||
stateManager,
|
||||
);
|
||||
|
||||
const listener = vi.fn();
|
||||
manager.addListener(listener);
|
||||
|
||||
stateManager.setState({ config: config_1 });
|
||||
expect(listener).toHaveBeenLastCalledWith({
|
||||
result: true,
|
||||
data: {
|
||||
config: {
|
||||
to: config_1,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
stateManager.setState({ config: config_2 });
|
||||
expect(listener).toHaveBeenLastCalledWith({
|
||||
result: true,
|
||||
data: {
|
||||
config: {
|
||||
from: config_1,
|
||||
to: config_2,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(listener).toBeCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should match specific config change', () => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const manager = new ConditionsManager(
|
||||
[{ condition: 'config' as const, paths: ['view.default'] }],
|
||||
stateManager,
|
||||
);
|
||||
|
||||
expect(manager.getEvaluation().result).toBeFalsy();
|
||||
stateManager.setState({ config: config_1 });
|
||||
expect(manager.getEvaluation().result).toBeTruthy();
|
||||
stateManager.setState({ config: config_2 });
|
||||
expect(manager.getEvaluation().result).toBeTruthy();
|
||||
stateManager.setState({ config: config_3 });
|
||||
expect(manager.getEvaluation().result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should match multiple config change', () => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const manager = new ConditionsManager(
|
||||
[
|
||||
{
|
||||
condition: 'config' as const,
|
||||
paths: ['view.default', 'view.default_cycle_camera'],
|
||||
},
|
||||
],
|
||||
stateManager,
|
||||
);
|
||||
|
||||
expect(manager.getEvaluation().result).toBeFalsy();
|
||||
stateManager.setState({ config: config_1 });
|
||||
expect(manager.getEvaluation().result).toBeTruthy();
|
||||
stateManager.setState({ config: config_2 });
|
||||
expect(manager.getEvaluation().result).toBeTruthy();
|
||||
stateManager.setState({ config: config_3 });
|
||||
expect(manager.getEvaluation().result).toBeTruthy();
|
||||
stateManager.setState({ config: config_4 });
|
||||
expect(manager.getEvaluation().result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not match unrelated changes', () => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const manager = new ConditionsManager(
|
||||
[{ condition: 'config' as const }],
|
||||
stateManager,
|
||||
);
|
||||
|
||||
const listener = vi.fn();
|
||||
manager.addListener(listener);
|
||||
|
||||
stateManager.setState({ config: config_1 });
|
||||
expect(listener).toBeCalledTimes(1);
|
||||
|
||||
// On the next state set, the condition won't match anymore (as the
|
||||
// config is the same), the listener will still be called to indicate
|
||||
// the condition evaluation has changed.
|
||||
stateManager.setState({ expand: true });
|
||||
expect(listener).toBeCalledTimes(2);
|
||||
expect(listener).toHaveBeenLastCalledWith({ result: false });
|
||||
|
||||
// Future unrelated state changes won't call the listener.
|
||||
stateManager.setState({ fullscreen: true });
|
||||
expect(listener).toBeCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('with initialized condition', () => {
|
||||
const stateManager = new ConditionStateManager();
|
||||
const manager = new ConditionsManager(
|
||||
[{ condition: 'initialized' as const }],
|
||||
stateManager,
|
||||
);
|
||||
|
||||
expect(manager.getEvaluation().result).toBeFalsy();
|
||||
stateManager.setState({ initialized: true });
|
||||
expect(manager.getEvaluation().result).toBeTruthy();
|
||||
stateManager.setState({ initialized: false });
|
||||
expect(manager.getEvaluation().result).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('should handle listeners correctly', () => {
|
||||
|
||||
Reference in new issue
Block a user