Release 1.4.0

This commit is contained in:
2022-08-13 10:20:06 +02:00
parent 9bb72f0207
commit 5452306c72
162 changed files with 10015 additions and 4419 deletions

View File

@@ -25,5 +25,6 @@ export const SettingsFactory = () => {
url: 'ws://127.0.0.1:3010/backend/websocket',
},
OFFLINE_MODE: false,
READ_ONLY: false,
};
};

View File

@@ -1,51 +1,116 @@
import {shallow} from 'enzyme';
import React from 'react';
import {Responsive} from 'react-grid-layout';
import {DynamicGridLayout} from 'src/components';
import * as Dashboard from 'src/main/components/Dashboard';
describe('src/main/components/Dashboard', () => {
describe('Dashboard', () => {
describe('ControlledDashboard', () => {
let layout = null;
let mockOnGridLayoutChange = null;
beforeEach(() => {
layout = [{i: 'test', x: 0, y: 0, w: 1, h: 1}];
layout = [
{i: 'test2', x: 1, y: 0, w: 1, h: 1},
{i: 'test', x: 0, y: 0, w: 1, h: 3},
];
mockOnGridLayoutChange = jasmine.createSpy();
});
it('configures and renders the DynamicGridLayout', () => {
it('configures and renders the Responsive grid', () => {
// Given
const component = shallow(
<Dashboard.Dashboard
<Dashboard.ControlledDashboard
layout={layout}
width={1024}
onGridLayoutChange={mockOnGridLayoutChange}
>
<span key="test">It works!</span>
</Dashboard.Dashboard>
</Dashboard.ControlledDashboard>
);
const expectedLayouts = {
lg: layout,
md: [
{i: 'test', x: 0, y: 0, w: 12, h: 3},
{i: 'test2', x: 0, y: 3, w: 12, h: 1},
],
};
// Then
const responsiveGrid = component.find(Responsive).at(0);
expect(responsiveGrid.exists()).toBe(true);
expect(responsiveGrid.prop('breakpoints')).toEqual({lg: 1023, md: 0});
expect(responsiveGrid.prop('cols')).toEqual({lg: 12, md: 12});
expect(responsiveGrid.prop('containerPadding')).toEqual({
lg: [10, 10],
md: [10, 10],
});
expect(responsiveGrid.prop('draggableHandle')).toEqual(
'.draggable-handle',
);
expect(responsiveGrid.prop('isDraggable')).toBe(true);
expect(responsiveGrid.prop('isResizable')).toBe(true);
expect(responsiveGrid.prop('layouts')).toEqual(expectedLayouts);
expect(responsiveGrid.prop('rowHeight')).toEqual(30);
expect(responsiveGrid.prop('width')).toEqual(1024);
expect(responsiveGrid.prop('onLayoutChange')).toEqual(
mockOnGridLayoutChange
);
});
it('renders as read-only on non-desktop screens', () => {
// Given
const component = shallow(
<Dashboard.ControlledDashboard
layout={layout}
width={1023}
onGridLayoutChange={mockOnGridLayoutChange}
>
<span key="test">It works!</span>
</Dashboard.ControlledDashboard>
);
// Then
const dynamicGridLayout = component.find(DynamicGridLayout).at(0);
expect(dynamicGridLayout.exists()).toBe(true);
expect(dynamicGridLayout.prop('cols')).toEqual(12);
expect(dynamicGridLayout.prop('layout')).toEqual(layout);
expect(dynamicGridLayout.prop('rowHeight')).toEqual(30);
expect(dynamicGridLayout.prop('onLayoutChange')).toEqual(
mockOnGridLayoutChange
expect(component.hasClass('read-only')).toBe(true);
const responsiveGrid = component.find(Responsive).at(0);
expect(responsiveGrid.prop('isDraggable')).toBe(false);
expect(responsiveGrid.prop('isResizable')).toBe(false);
});
it('renders as read-only', () => {
// Given
const component = shallow(
<Dashboard.ControlledDashboard
layout={layout}
readOnly={true}
width={1024}
onGridLayoutChange={mockOnGridLayoutChange}
>
<span key="test">It works!</span>
</Dashboard.ControlledDashboard>
);
// Then
expect(component.hasClass('read-only')).toBe(true);
const responsiveGrid = component.find(Responsive).at(0);
expect(responsiveGrid.prop('isDraggable')).toBe(false);
expect(responsiveGrid.prop('isResizable')).toBe(false);
});
it('renders the children', () => {
// Given
const children = <span key="test">It works!</span>;
const component = shallow(
<Dashboard.Dashboard
<Dashboard.ControlledDashboard
layout={layout}
width={1024}
onGridLayoutChange={mockOnGridLayoutChange}
>
{children}
</Dashboard.Dashboard>
</Dashboard.ControlledDashboard>
);
// Then

View File

@@ -5,9 +5,12 @@ import React from 'react';
import {AppearancePopup, WidgetSettingsModal} from 'src/main/components';
import * as DashboardItem from 'src/main/components/DashboardItem';
describe('src/main/components/DashboardItem', () => {
describe('DashboardItem', () => {
import {SettingsFactory} from 'tests/__fixtures__/settings';
describe('src/main/components/ControlledDashboardItem', () => {
describe('ControlledDashboardItem', () => {
let fakeServiceState = null;
let fakeSettings = null;
let mockOnAppearancePopupColorChange = null;
let mockOnServiceRestartButtonClick = null;
let mockOnSettingsButtonClick = null;
@@ -18,6 +21,7 @@ describe('src/main/components/DashboardItem', () => {
beforeEach(() => {
fakeServiceState = jasmine.createSpyObj('ServiceState', ['isLoading']);
fakeServiceState.isLoading.and.returnValue(false);
fakeSettings = SettingsFactory();
mockOnAppearancePopupColorChange = jasmine.createSpy();
mockOnServiceRestartButtonClick = jasmine.createSpy();
mockOnSettingsButtonClick = jasmine.createSpy();
@@ -30,9 +34,10 @@ describe('src/main/components/DashboardItem', () => {
// Given
const children = <span>It works!</span>;
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -44,19 +49,108 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
{children}
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// Then
expect(component.contains(children)).toBe(true);
});
it('renders as read-only', () => {
// Given
fakeSettings.READ_ONLY = true;
const children = <span>It works!</span>;
const component = shallow(
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
onSettingsButtonClick={mockOnSettingsButtonClick}
onSettingsModalClose={mockOnSettingsModalClose}
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
{children}
</DashboardItem.ControlledDashboardItem>
);
// Then
expect(component.contains(children)).toBe(true);
expect(component.find('.draggable-handle').exists()).toBe(false);
expect(component.find('WidgetToolbarItem[_hint="Restart"]').exists()).toBe(
false
);
expect(component.find('WidgetToolbarItem[_hint="Appearance"]').exists()).toBe(
false
);
expect(component.find('WidgetToolbarItem[_hint="Settings"]').exists()).toBe(
false
);
expect(component.find('WidgetToolbarItem[_hint="Delete"]').exists()).toBe(
false
);
expect(component.find(WidgetSettingsModal).exists()).toBe(false);
expect(component.find(AppearancePopup).exists()).toBe(false);
});
it('renders as read-only if hasSettingsView is true', () => {
// Given
fakeSettings.READ_ONLY = true;
const children = <span>It works!</span>;
const component = shallow(
<DashboardItem.ControlledDashboardItem
hasSettingsView={true}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={<span>Settings</span>}
settingsViewProps={{}}
showSettingsModal={false}
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
onSettingsButtonClick={mockOnSettingsButtonClick}
onSettingsModalClose={mockOnSettingsModalClose}
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
{children}
</DashboardItem.ControlledDashboardItem>
);
// Then
expect(component.contains(children)).toBe(true);
expect(component.find('.draggable-handle').exists()).toBe(false);
expect(component.find('WidgetToolbarItem[_hint="Restart"]').exists()).toBe(
false
);
expect(component.find('WidgetToolbarItem[_hint="Appearance"]').exists()).toBe(
false
);
expect(component.find('WidgetToolbarItem[_hint="Settings"]').exists()).toBe(
false
);
expect(component.find('WidgetToolbarItem[_hint="Delete"]').exists()).toBe(
false
);
expect(component.find(WidgetSettingsModal).exists()).toBe(false);
expect(component.find(AppearancePopup).exists()).toBe(false);
});
it('renders the draggable handle', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -68,7 +162,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// Then
@@ -78,9 +172,10 @@ describe('src/main/components/DashboardItem', () => {
it('does not render the restart toolbar item if serviceState is null', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={null}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -92,7 +187,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// Then
@@ -105,9 +200,10 @@ describe('src/main/components/DashboardItem', () => {
// Given
fakeServiceState.isLoading.and.returnValue(true);
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -119,7 +215,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// Then
@@ -131,9 +227,10 @@ describe('src/main/components/DashboardItem', () => {
it('configures and renders the restart toolbar item', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -145,7 +242,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -161,9 +258,10 @@ describe('src/main/components/DashboardItem', () => {
it('configures and renders the appearance toolbar item', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -175,7 +273,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -190,9 +288,10 @@ describe('src/main/components/DashboardItem', () => {
it('displays the appearance popup when appearance toolbar item is clicked', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -204,7 +303,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -220,9 +319,10 @@ describe('src/main/components/DashboardItem', () => {
it('does not render the settings toolbar item if hasSettingsView is false', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -234,7 +334,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// Then
@@ -246,9 +346,10 @@ describe('src/main/components/DashboardItem', () => {
it('configures and renders the settings toolbar item', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={true}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={<span>Settings</span>}
settingsViewProps={{}}
showSettingsModal={false}
@@ -260,7 +361,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -276,9 +377,10 @@ describe('src/main/components/DashboardItem', () => {
it('does not render the delete toolbar item if hasSettingsView is true', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={true}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={<span>Settings</span>}
settingsViewProps={{}}
showSettingsModal={false}
@@ -290,7 +392,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// Then
@@ -302,9 +404,10 @@ describe('src/main/components/DashboardItem', () => {
it('configures and renders the delete toolbar item', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -316,7 +419,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -334,9 +437,10 @@ describe('src/main/components/DashboardItem', () => {
it('does not render the WidgetSettingsModal if hasSettingsView is false', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={false}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={null}
settingsViewProps={{}}
showSettingsModal={false}
@@ -348,7 +452,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -363,9 +467,10 @@ describe('src/main/components/DashboardItem', () => {
const settingsView = <span>Settings</span>;
const settingsViewProps = {spam: true};
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={true}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={settingsView}
settingsViewProps={settingsViewProps}
showSettingsModal={true}
@@ -377,7 +482,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -414,9 +519,10 @@ describe('src/main/components/DashboardItem', () => {
it('configures and renders the appearance popup wrapper', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={true}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={<span>Settings</span>}
settingsViewProps={{}}
showSettingsModal={false}
@@ -428,7 +534,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -442,9 +548,10 @@ describe('src/main/components/DashboardItem', () => {
it('hides the appearance popup wrapper when the overlay is clicked', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={true}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={<span>Settings</span>}
settingsViewProps={{}}
showSettingsModal={false}
@@ -456,7 +563,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -473,9 +580,10 @@ describe('src/main/components/DashboardItem', () => {
it('configures and renders the appearance popup view', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={true}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={<span>Settings</span>}
settingsViewProps={{}}
showSettingsModal={false}
@@ -487,7 +595,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When
@@ -500,9 +608,10 @@ describe('src/main/components/DashboardItem', () => {
it('handles the AppearancePopup color change', () => {
// Given
const component = shallow(
<DashboardItem.DashboardItem
<DashboardItem.ControlledDashboardItem
hasSettingsView={true}
serviceState={fakeServiceState}
settings={fakeSettings}
settingsView={<span>Settings</span>}
settingsViewProps={{}}
showSettingsModal={false}
@@ -514,7 +623,7 @@ describe('src/main/components/DashboardItem', () => {
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
>
<span>It works!</span>
</DashboardItem.DashboardItem>
</DashboardItem.ControlledDashboardItem>
);
// When

View File

@@ -26,6 +26,29 @@ describe('src/main/components/StartMenu', () => {
fakeSettings = SettingsFactory();
});
it('renders as read-only', () => {
// Given
fakeSettings.READ_ONLY = true;
// When
const component = shallow(
<StartMenu.ControlledStartMenu
hasDashboards={true}
offlineMode={false}
services={SERVICES}
settings={fakeSettings}
widgets={WIDGETS}
onAddDashboard={mockOnAddDashboard}
onAddService={mockOnAddService}
/>
);
// Then
expect(component.find('div[_hint="StartMenu"]').hasClass('read-only')).toBe(true);
expect(component.find('div[_hint="AddDashboard"]').exists()).toBe(false);
expect(component.find('div[_hint="Widgets"]').exists()).toBe(false);
});
it('renders the start button', () => {
// Given
const component = shallow(

View File

@@ -67,10 +67,31 @@ describe('src/main/containers/DashboardContainer', () => {
// Then
expect(dashboard.exists()).toBe(true);
expect(dashboard.prop('readOnly')).toBe(false);
expect(dashboard.prop('layout')).toEqual(expectedLayout);
});
it('configures and render a ServiceContainer for services', () => {
it('configures and renders the dashboard as read-only', () => {
// Given
fakeSettings.READ_ONLY = true;
const component = mount(
<DashboardsContext.Provider value={fakeDashboardsContext}>
<DashboardContainer.ControlledDashboardContainer
settings={fakeSettings}
/>
</DashboardsContext.Provider>
);
// When
const dashboard = component.find(Dashboard).at(0);
// Then
expect(dashboard.exists()).toBe(true);
expect(dashboard.prop('readOnly')).toBe(true);
});
it('configures and renders a ServiceContainer for services', () => {
// Given
const component = mount(
<DashboardsContext.Provider value={fakeDashboardsContext}>
@@ -93,6 +114,27 @@ describe('src/main/containers/DashboardContainer', () => {
expect(serviceContainer.prop('kind')).toEqual(
fakeDashboardsContext.dashboards[0].services[0].kind
);
expect(serviceContainer.prop('readOnly')).toBe(false);
});
it('configures and renders ServiceContainers as read-oniy', () => {
// Given
fakeSettings.READ_ONLY = true;
const component = mount(
<DashboardsContext.Provider value={fakeDashboardsContext}>
<DashboardContainer.ControlledDashboardContainer
settings={fakeSettings}
/>
</DashboardsContext.Provider>
);
// When
const serviceContainers = component.find(ServiceContainer);
const serviceContainer = serviceContainers.at(0);
// Then
expect(serviceContainer.prop('readOnly')).toBe(true);
});
it('configures and renders a DashboardItem for services', () => {