fix: Various editor / diagnostic improvements (#2363)

- Closes: #2360 
 - Closes: #2328
This commit is contained in:
Dermot Duffy
2026-02-21 09:31:10 -08:00
committed by GitHub
parent 6d5a76ac0a
commit df3614f793
13 changed files with 313 additions and 58 deletions
@@ -1,13 +1,14 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
import { afterEach, assert, describe, expect, it, vi } from 'vitest';
import { mock } from 'vitest-mock-extended';
import { CardElementManager } from '../../src/card-controller/card-element-manager';
import { StateWatcher } from '../../src/card-controller/hass/state-watcher';
import { QueryResults } from '../../src/view/query-results';
import { View } from '../../src/view/view';
import {
callStateWatcherCallback,
createCardAPI,
createCardHTMLElement,
createConfig,
createLitElement,
createStateEntity,
createView,
TestViewMedia,
@@ -20,7 +21,7 @@ describe('CardElementManager', () => {
});
it('should get element', () => {
const element = createLitElement();
const element = createCardHTMLElement();
const manager = new CardElementManager(
createCardAPI(),
element,
@@ -35,7 +36,7 @@ describe('CardElementManager', () => {
const callback = vi.fn();
const manager = new CardElementManager(
createCardAPI(),
createLitElement(),
createCardHTMLElement(),
callback,
() => undefined,
);
@@ -49,7 +50,7 @@ describe('CardElementManager', () => {
const callback = vi.fn();
const manager = new CardElementManager(
createCardAPI(),
createLitElement(),
createCardHTMLElement(),
() => undefined,
callback,
);
@@ -60,7 +61,7 @@ describe('CardElementManager', () => {
});
it('should update', () => {
const element = createLitElement();
const element = createCardHTMLElement();
const manager = new CardElementManager(
createCardAPI(),
element,
@@ -73,7 +74,7 @@ describe('CardElementManager', () => {
});
it('should get hasUpdated', () => {
const element = createLitElement();
const element = createCardHTMLElement();
element.hasUpdated = true;
const manager = new CardElementManager(
createCardAPI(),
@@ -89,7 +90,7 @@ describe('CardElementManager', () => {
const windowAddEventListener = vi.spyOn(global.window, 'addEventListener');
const addEventListener = vi.fn();
const element = createLitElement();
const element = createCardHTMLElement();
element.addEventListener = addEventListener;
const api = createCardAPI();
@@ -132,6 +133,10 @@ describe('CardElementManager', () => {
);
expect(windowAddEventListener).toBeCalledWith('location-changed', expect.anything());
expect(windowAddEventListener).toBeCalledWith('popstate', expect.anything());
expect(windowAddEventListener).toBeCalledWith(
'advanced-camera-card:editor:diagnostics',
expect.anything(),
);
expect(api.getInteractionManager().initialize).toBeCalled();
expect(api.getFullscreenManager().initialize).toBeCalled();
@@ -143,7 +148,7 @@ describe('CardElementManager', () => {
it('should disconnect', () => {
const windowRemoveEventListener = vi.spyOn(global.window, 'removeEventListener');
const element = createLitElement();
const element = createCardHTMLElement();
element.setAttribute('panel', '');
element.setAttribute('casted', '');
@@ -195,6 +200,10 @@ describe('CardElementManager', () => {
expect.anything(),
);
expect(windowRemoveEventListener).toBeCalledWith('popstate', expect.anything());
expect(windowRemoveEventListener).toBeCalledWith(
'advanced-camera-card:editor:diagnostics',
expect.anything(),
);
expect(api.getMediaLoadedInfoManager().clear).toBeCalled();
expect(api.getFullscreenManager().disconnect).toBeCalled();
@@ -217,7 +226,7 @@ describe('CardElementManager', () => {
const stateWatcher = mock<StateWatcher>();
vi.mocked(api.getHASSManager().getStateWatcher).mockReturnValue(stateWatcher);
const element = createLitElement();
const element = createCardHTMLElement();
const manager = new CardElementManager(
api,
element,
@@ -245,7 +254,7 @@ describe('CardElementManager', () => {
const stateWatcher = mock<StateWatcher>();
vi.mocked(api.getHASSManager().getStateWatcher).mockReturnValue(stateWatcher);
const element = createLitElement();
const element = createCardHTMLElement();
const manager = new CardElementManager(
api,
element,
@@ -275,7 +284,7 @@ describe('CardElementManager', () => {
vi.mocked(api.getViewManager().getView).mockReturnValue(view);
const element = createLitElement();
const element = createCardHTMLElement();
const manager = new CardElementManager(
api,
element,
@@ -310,7 +319,7 @@ describe('CardElementManager', () => {
vi.mocked(api.getViewManager().getView).mockReturnValue(view);
const element = createLitElement();
const element = createCardHTMLElement();
const manager = new CardElementManager(
api,
element,
@@ -334,4 +343,95 @@ describe('CardElementManager', () => {
expect(element.requestUpdate).not.toBeCalled();
});
});
describe('should handle diagnostics', () => {
afterEach(() => {
vi.clearAllMocks();
});
const createDialogWithCard = (element: HTMLElement) => {
const dialog = document.createElement('hui-dialog-edit-card');
dialog.attachShadow({ mode: 'open' });
assert(dialog.shadowRoot);
dialog.shadowRoot.append(element);
return dialog;
};
const fireFromDialog = (dialog: HTMLElement) => {
const editorDiv = document.createElement('div');
assert(dialog.shadowRoot);
dialog.shadowRoot.append(editorDiv);
editorDiv.dispatchEvent(
new CustomEvent('advanced-camera-card:editor:diagnostics', {
bubbles: true,
composed: true,
}),
);
};
it('sets view to diagnostics if card is in editor', () => {
const api = createCardAPI();
const element = createCardHTMLElement();
const manager = new CardElementManager(
api,
element,
() => undefined,
() => undefined,
);
const dialog = createDialogWithCard(element);
document.body.append(dialog);
manager.elementConnected();
fireFromDialog(dialog);
expect(api.getViewManager().setViewByParameters).toBeCalledWith({
params: { view: 'diagnostics' },
});
});
it('resets to default view if already in diagnostics view', () => {
const api = createCardAPI();
const element = createCardHTMLElement();
const manager = new CardElementManager(
api,
element,
() => undefined,
() => undefined,
);
vi.mocked(api.getViewManager().getView).mockReturnValue(
new View({ view: 'diagnostics' }),
);
const dialog = createDialogWithCard(element);
document.body.append(dialog);
manager.elementConnected();
fireFromDialog(dialog);
expect(api.getViewManager().setViewDefault).toBeCalled();
});
it('does not set view to diagnostics if card is not in editor', () => {
const api = createCardAPI();
const element = createCardHTMLElement();
const manager = new CardElementManager(
api,
element,
() => undefined,
() => undefined,
);
manager.elementConnected();
// Event fired from a different dialog that does not contain the card
const otherDialog = document.createElement('hui-dialog-edit-card');
otherDialog.attachShadow({ mode: 'open' });
document.body.append(otherDialog);
fireFromDialog(otherDialog);
expect(api.getViewManager().setViewByParameters).not.toBeCalled();
});
});
});