feat: Allow user generated notifications (#2401)
This commit is contained in:
@@ -28,7 +28,7 @@ describe('InfoAction', () => {
|
||||
|
||||
await action.execute(api);
|
||||
|
||||
expect(api.getOverlayMessageManager().setMessage).toBeCalled();
|
||||
expect(api.getNotificationManager().setNotification).toBeCalled();
|
||||
});
|
||||
|
||||
it('should not handle info action without media', async () => {
|
||||
@@ -45,6 +45,6 @@ describe('InfoAction', () => {
|
||||
|
||||
await action.execute(api);
|
||||
|
||||
expect(api.getOverlayMessageManager().setMessage).not.toBeCalled();
|
||||
expect(api.getNotificationManager().setNotification).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { NotificationAction } from '../../../../src/card-controller/actions/actions/notification';
|
||||
import { createCardAPI } from '../../../test-utils';
|
||||
|
||||
describe('NotificationAction', () => {
|
||||
it('should set notification on manager', async () => {
|
||||
const api = createCardAPI();
|
||||
const notification = {
|
||||
heading: { text: 'Test Heading' },
|
||||
text: 'Test text',
|
||||
};
|
||||
|
||||
const action = new NotificationAction(
|
||||
{},
|
||||
{
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'notification',
|
||||
notification,
|
||||
},
|
||||
);
|
||||
|
||||
await action.execute(api);
|
||||
|
||||
expect(api.getNotificationManager().setNotification).toHaveBeenCalledWith(
|
||||
notification,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -22,9 +22,10 @@ import { MoreInfoAction } from '../../../src/card-controller/actions/actions/mor
|
||||
import { MuteAction } from '../../../src/card-controller/actions/actions/mute';
|
||||
import { NavigateAction } from '../../../src/card-controller/actions/actions/navigate';
|
||||
import { NoneAction } from '../../../src/card-controller/actions/actions/none';
|
||||
import { NotificationAction } from '../../../src/card-controller/actions/actions/notification';
|
||||
import { PauseAction } from '../../../src/card-controller/actions/actions/pause';
|
||||
import { PIPAction } from '../../../src/card-controller/actions/actions/pip';
|
||||
import { PerformActionAction } from '../../../src/card-controller/actions/actions/perform-action';
|
||||
import { PIPAction } from '../../../src/card-controller/actions/actions/pip';
|
||||
import { PlayAction } from '../../../src/card-controller/actions/actions/play';
|
||||
import { PTZAction } from '../../../src/card-controller/actions/actions/ptz';
|
||||
import { PTZControlsAction } from '../../../src/card-controller/actions/actions/ptz-controls';
|
||||
@@ -126,6 +127,13 @@ describe('ActionFactory', () => {
|
||||
},
|
||||
LogAction,
|
||||
],
|
||||
[
|
||||
{
|
||||
advanced_camera_card_action: 'notification' as const,
|
||||
notification: { text: 'test' },
|
||||
},
|
||||
NotificationAction,
|
||||
],
|
||||
[
|
||||
{
|
||||
advanced_camera_card_action: 'media_player' as const,
|
||||
|
||||
@@ -121,6 +121,27 @@ describe('ConfigManager', () => {
|
||||
expect(manager.getConfig()).toBeNull();
|
||||
expect(manager.getNonOverriddenConfig()).toBeNull();
|
||||
expect(manager.getRawConfig()).toBeNull();
|
||||
expect(manager.isUpgradeable()).toBe(false);
|
||||
});
|
||||
|
||||
describe('isUpgradeable', () => {
|
||||
it('should return true for upgradeable config', () => {
|
||||
const manager = new ConfigManager(createCardAPI());
|
||||
manager.setConfig({
|
||||
type: 'custom:frigate-card',
|
||||
cameras: [TEST_CAMERAS.OFFICE],
|
||||
});
|
||||
expect(manager.isUpgradeable()).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for non-upgradeable config', () => {
|
||||
const manager = new ConfigManager(createCardAPI());
|
||||
manager.setConfig({
|
||||
type: 'custom:advanced-camera-card',
|
||||
cameras: [TEST_CAMERAS.OFFICE],
|
||||
});
|
||||
expect(manager.isUpgradeable()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('should successfully parse basic config', () => {
|
||||
|
||||
@@ -21,7 +21,7 @@ import { MediaLoadedInfoManager } from '../../src/card-controller/media-info-man
|
||||
import { MediaPlayerManager } from '../../src/card-controller/media-player-manager';
|
||||
import { MessageManager } from '../../src/card-controller/message-manager';
|
||||
import { MicrophoneManager } from '../../src/card-controller/microphone-manager';
|
||||
import { OverlayMessageManager } from '../../src/card-controller/overlay-message-manager';
|
||||
import { NotificationManager } from '../../src/card-controller/notification-manager';
|
||||
import { PIPManager } from '../../src/card-controller/pip-manager';
|
||||
import { QueryStringManager } from '../../src/card-controller/query-string-manager';
|
||||
import { StatusBarItemManager } from '../../src/card-controller/status-bar-item-manager';
|
||||
@@ -54,7 +54,7 @@ vi.mock('../../src/card-controller/media-info-manager');
|
||||
vi.mock('../../src/card-controller/media-player-manager');
|
||||
vi.mock('../../src/card-controller/message-manager');
|
||||
vi.mock('../../src/card-controller/microphone-manager');
|
||||
vi.mock('../../src/card-controller/overlay-message-manager');
|
||||
vi.mock('../../src/card-controller/notification-manager');
|
||||
vi.mock('../../src/card-controller/pip-manager');
|
||||
vi.mock('../../src/card-controller/query-string-manager');
|
||||
vi.mock('../../src/card-controller/status-bar-item-manager');
|
||||
@@ -226,9 +226,9 @@ describe('CardController', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('getOverlayMessageManager', () => {
|
||||
expect(createController().getOverlayMessageManager()).toBe(
|
||||
vi.mocked(OverlayMessageManager).mock.instances[0],
|
||||
it('getNotificationManager', () => {
|
||||
expect(createController().getNotificationManager()).toBe(
|
||||
vi.mocked(NotificationManager).mock.instances[0],
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import { CardElementManager } from '../../src/card-controller/card-element-manager';
|
||||
import { NotificationManager } from '../../src/card-controller/notification-manager';
|
||||
import { CardNotificationAPI } from '../../src/card-controller/types';
|
||||
|
||||
describe('NotificationManager', () => {
|
||||
const cardElementManager = mock<CardElementManager>();
|
||||
const api = mock<CardNotificationAPI>();
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
api.getCardElementManager.mockReturnValue(cardElementManager);
|
||||
});
|
||||
|
||||
it('should be constructed', () => {
|
||||
const manager = new NotificationManager(api);
|
||||
expect(manager).toBeDefined();
|
||||
expect(manager.getNotification()).toBeNull();
|
||||
expect(manager.hasNotification()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should set and get notification', () => {
|
||||
const manager = new NotificationManager(api);
|
||||
const notification = { text: 'foo' };
|
||||
manager.setNotification(notification);
|
||||
|
||||
expect(manager.getNotification()).toBe(notification);
|
||||
expect(manager.hasNotification()).toBeTruthy();
|
||||
expect(cardElementManager.update).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should reset notification', () => {
|
||||
const manager = new NotificationManager(api);
|
||||
manager.setNotification({ text: 'foo' });
|
||||
vi.clearAllMocks();
|
||||
|
||||
manager.reset();
|
||||
|
||||
expect(manager.getNotification()).toBeNull();
|
||||
expect(manager.hasNotification()).toBeFalsy();
|
||||
expect(cardElementManager.update).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not update if reset is called with no notification', () => {
|
||||
const manager = new NotificationManager(api);
|
||||
manager.reset();
|
||||
|
||||
expect(cardElementManager.update).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,51 +0,0 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import { CardElementManager } from '../../src/card-controller/card-element-manager';
|
||||
import { OverlayMessageManager } from '../../src/card-controller/overlay-message-manager';
|
||||
import { CardOverlayMessageAPI } from '../../src/card-controller/types';
|
||||
|
||||
describe('OverlayMessageManager', () => {
|
||||
const cardElementManager = mock<CardElementManager>();
|
||||
const api = mock<CardOverlayMessageAPI>();
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
api.getCardElementManager.mockReturnValue(cardElementManager);
|
||||
});
|
||||
|
||||
it('should be constructed', () => {
|
||||
const manager = new OverlayMessageManager(api);
|
||||
expect(manager).toBeDefined();
|
||||
expect(manager.getMessage()).toBeNull();
|
||||
expect(manager.hasMessage()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should set and get message', () => {
|
||||
const manager = new OverlayMessageManager(api);
|
||||
const message = { text: 'foo' };
|
||||
manager.setMessage(message);
|
||||
|
||||
expect(manager.getMessage()).toBe(message);
|
||||
expect(manager.hasMessage()).toBeTruthy();
|
||||
expect(cardElementManager.update).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should reset message', () => {
|
||||
const manager = new OverlayMessageManager(api);
|
||||
manager.setMessage({ text: 'foo' });
|
||||
vi.clearAllMocks();
|
||||
|
||||
manager.reset();
|
||||
|
||||
expect(manager.getMessage()).toBeNull();
|
||||
expect(manager.hasMessage()).toBeFalsy();
|
||||
expect(cardElementManager.update).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not update if reset is called with no message', () => {
|
||||
const manager = new OverlayMessageManager(api);
|
||||
manager.reset();
|
||||
|
||||
expect(cardElementManager.update).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -241,6 +241,56 @@ describe('StatusBarItemManager', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('upgrade', () => {
|
||||
it('should show upgrade item when upgradeable', () => {
|
||||
const manager = new StatusBarItemManager(createCardAPI());
|
||||
|
||||
const items = manager.calculateItems({
|
||||
isUpgradeable: true,
|
||||
});
|
||||
|
||||
expect(items).toContainEqual(
|
||||
expect.objectContaining({
|
||||
type: 'custom:advanced-camera-card-status-bar-icon' as const,
|
||||
icon: 'mdi:update',
|
||||
severity: 'medium',
|
||||
actions: expect.objectContaining({
|
||||
tap_action: expect.objectContaining({
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'notification',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not show upgrade item when not upgradeable', () => {
|
||||
const manager = new StatusBarItemManager(createCardAPI());
|
||||
|
||||
const items = manager.calculateItems({
|
||||
isUpgradeable: false,
|
||||
});
|
||||
|
||||
expect(items).not.toContainEqual(
|
||||
expect.objectContaining({
|
||||
icon: 'mdi:update',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not show upgrade item by default', () => {
|
||||
const manager = new StatusBarItemManager(createCardAPI());
|
||||
|
||||
const items = manager.calculateItems();
|
||||
|
||||
expect(items).not.toContainEqual(
|
||||
expect.objectContaining({
|
||||
icon: 'mdi:update',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('severity', () => {
|
||||
it('should have severity in a viewer view', () => {
|
||||
const manager = new StatusBarItemManager(createCardAPI());
|
||||
|
||||
Reference in New Issue
Block a user