fix: Confirmations should apply to all actions (#1959)
This also refactors how generic HA actions are handled, and improves typing of actions. [skip ci]
This commit is contained in:
+19
-40
@@ -1,9 +1,7 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import { actionSchema, INTERNAL_CALLBACK_ACTION } from '../../src/config/types.js';
|
||||
import { hasAction as customCardHasAction } from '../../src/ha/has-action.js';
|
||||
import { ActionConfig, INTERNAL_CALLBACK_ACTION } from '../../src/config/types.js';
|
||||
import {
|
||||
convertActionToCardCustomAction,
|
||||
createCameraAction,
|
||||
createDisplayModeAction,
|
||||
createGeneralAction,
|
||||
@@ -21,30 +19,6 @@ import {
|
||||
stopEventFromActivatingCardWideActions,
|
||||
} from '../../src/utils/action.js';
|
||||
|
||||
vi.mock('../../src/ha/has-action.js');
|
||||
|
||||
describe('convertActionToAdvancedCameraCardCustomAction', () => {
|
||||
it('should skip null action', () => {
|
||||
expect(convertActionToCardCustomAction(null)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should parse valid', () => {
|
||||
expect(
|
||||
convertActionToCardCustomAction({
|
||||
action: 'custom:advanced-camera-card-action',
|
||||
advanced_camera_card_action: 'download',
|
||||
}),
|
||||
).toEqual({
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'download',
|
||||
});
|
||||
});
|
||||
|
||||
it('should not parse invalid', () => {
|
||||
expect(convertActionToCardCustomAction('this is garbage')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('createGeneralAction', () => {
|
||||
it('should create general action', () => {
|
||||
expect(
|
||||
@@ -293,10 +267,7 @@ describe('createPerformAction', () => {
|
||||
});
|
||||
|
||||
describe('getActionConfigGivenAction', () => {
|
||||
const action = actionSchema.parse({
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'clips',
|
||||
});
|
||||
const action = createViewAction('clips');
|
||||
|
||||
it('should not handle undefined arguments', () => {
|
||||
expect(getActionConfigGivenAction()).toBeNull();
|
||||
@@ -348,21 +319,29 @@ describe('getActionConfigGivenAction', () => {
|
||||
});
|
||||
|
||||
describe('hasAction', () => {
|
||||
const action = actionSchema.parse({
|
||||
action: 'toggle',
|
||||
});
|
||||
const realAction = createViewAction('clips');
|
||||
const noneAction: ActionConfig = {
|
||||
action: 'none',
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should handle non-array case', () => {
|
||||
expect(hasAction(action)).toBeFalsy();
|
||||
expect(customCardHasAction).toBeCalledTimes(1);
|
||||
it('should return true for real action', () => {
|
||||
expect(hasAction(realAction)).toBeTruthy();
|
||||
});
|
||||
it('should handle array case', () => {
|
||||
expect(hasAction([action, action, action])).toBeFalsy();
|
||||
expect(customCardHasAction).toBeCalledTimes(3);
|
||||
|
||||
it('should return false for none action', () => {
|
||||
expect(hasAction(noneAction)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true with an array of actions some real', () => {
|
||||
expect(hasAction([noneAction, noneAction, realAction])).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false with an array of actions none real', () => {
|
||||
expect(hasAction([noneAction, noneAction, noneAction])).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ describe('arrayify', () => {
|
||||
const data = [1, 2, 3];
|
||||
expect(arrayify(data)).toBe(data);
|
||||
});
|
||||
it('should handle undefined', () => {
|
||||
expect(arrayify()).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setify', () => {
|
||||
|
||||
@@ -18,13 +18,13 @@ const media = new ViewMedia('clip', 'camera.office');
|
||||
describe('downloadURL', () => {
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
global.window.location = mock<Location>();
|
||||
});
|
||||
|
||||
it('should download same origin via link', () => {
|
||||
const location: Location & { origin: string } = mock<Location>();
|
||||
location.origin = 'http://foo';
|
||||
global.window.location = location;
|
||||
|
||||
vi.spyOn(window, 'location', 'get').mockReturnValue(location);
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.click = vi.fn();
|
||||
@@ -55,7 +55,8 @@ describe('downloadURL', () => {
|
||||
// Set the origin to the same.
|
||||
const location: Location & { origin: string } = mock<Location>();
|
||||
location.origin = 'http://foo';
|
||||
global.window.location = location;
|
||||
|
||||
vi.spyOn(window, 'location', 'get').mockReturnValue(location);
|
||||
|
||||
const windowSpy = vi.spyOn(window, 'open').mockReturnValue(null);
|
||||
|
||||
@@ -66,8 +67,13 @@ describe('downloadURL', () => {
|
||||
|
||||
describe('downloadMedia', () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(window, 'location', 'get').mockReturnValue(
|
||||
mock<Location>({ origin: 'https://foo' }),
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
global.window.location = mock<Location>({ origin: 'https://foo' });
|
||||
});
|
||||
|
||||
it('should throw error when no media', () => {
|
||||
|
||||
Reference in New Issue
Block a user