- Much improved API cleanliness and testability to allow further extensibility in future - Simplified code in `live` view This technically contains a small change in how overrides work in the `live` view. Since that change is _closer_ to the documentation, and since this is likely to be rarely used, this is not considered a breaking change. Previously, overrides for a given live camera would always render _as if_ that camera was selected, vs was actually selected. Now, overrides will only apply in the live view when the camera is _actually_ selected. If this is an issue for you in practice, lets discuss.
306 lines
7.4 KiB
TypeScript
306 lines
7.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { mock } from 'vitest-mock-extended';
|
|
import { z } from 'zod';
|
|
import { getOverriddenConfig } from '../../../src/card-controller/config/get-overridden-config';
|
|
import { ConditionsManagerReadonlyInterface } from '../../../src/conditions/types';
|
|
|
|
describe('getOverriddenConfig', () => {
|
|
const config = {
|
|
menu: {
|
|
style: 'none',
|
|
},
|
|
};
|
|
|
|
it('should not override without overrides', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(getOverriddenConfig(manager, config)).toBe(config);
|
|
});
|
|
|
|
it('should not override when conditions do not match', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: false });
|
|
|
|
expect(
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
merge: {
|
|
menu: {
|
|
style: 'hidden',
|
|
},
|
|
},
|
|
delete: ['menu.style'],
|
|
set: {
|
|
'menu.style': 'overlay',
|
|
},
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
).toBe(config);
|
|
});
|
|
|
|
describe('should merge', () => {
|
|
it('with path', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
merge: {
|
|
'live.controls.thumbnails': {
|
|
mode: 'none',
|
|
},
|
|
},
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
).toEqual({
|
|
menu: {
|
|
style: 'none',
|
|
},
|
|
live: {
|
|
controls: {
|
|
thumbnails: {
|
|
mode: 'none',
|
|
},
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it('without path', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
merge: {
|
|
menu: {
|
|
style: 'hidden',
|
|
},
|
|
},
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
).toEqual({
|
|
menu: {
|
|
style: 'hidden',
|
|
},
|
|
});
|
|
});
|
|
|
|
it('with invalid merge', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
merge: 6 as unknown as Record<string, unknown>,
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
).toEqual({
|
|
menu: {
|
|
style: 'none',
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('should set', () => {
|
|
it('leaf node', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
set: {
|
|
'menu.style': 'hidden',
|
|
},
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
).toEqual({
|
|
menu: {
|
|
style: 'hidden',
|
|
},
|
|
});
|
|
});
|
|
|
|
it('root node', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
set: {
|
|
menu: {
|
|
style: 'hidden',
|
|
},
|
|
},
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
).toEqual({
|
|
menu: {
|
|
style: 'hidden',
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('should delete', () => {
|
|
it('leaf node', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
delete: ['menu.style' as const],
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
).toEqual({
|
|
menu: {},
|
|
});
|
|
});
|
|
|
|
it('root node', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
delete: ['menu' as const],
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
).toEqual({});
|
|
});
|
|
});
|
|
|
|
describe('should validate schema', () => {
|
|
const testSchema = z.object({
|
|
menu: z.object({
|
|
style: z.enum(['none', 'hidden']),
|
|
}),
|
|
});
|
|
|
|
it('passing', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
set: {
|
|
'menu.style': 'hidden',
|
|
},
|
|
},
|
|
],
|
|
schema: testSchema,
|
|
}),
|
|
).toEqual({
|
|
menu: {
|
|
style: 'hidden',
|
|
},
|
|
});
|
|
});
|
|
|
|
it('failing', () => {
|
|
const manager = mock<ConditionsManagerReadonlyInterface>();
|
|
manager.getEvaluation.mockReturnValue({ result: true });
|
|
|
|
expect(() =>
|
|
getOverriddenConfig(manager, config, {
|
|
configOverrides: [
|
|
{
|
|
conditions: [
|
|
{
|
|
condition: 'fullscreen' as const,
|
|
fullscreen: true,
|
|
},
|
|
],
|
|
set: {
|
|
'menu.style': 'NOT_A_STYLE',
|
|
},
|
|
},
|
|
],
|
|
schema: testSchema,
|
|
}),
|
|
).toThrowError(/Invalid override configuration/);
|
|
});
|
|
});
|
|
});
|