You've already forked homehub
Release 1.3.0
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {Button, Modal} from 'src/components';
|
||||
import * as AboutModal from 'src/main/components/AboutModal';
|
||||
|
||||
describe('src/main/components/AboutModal', () => {
|
||||
describe('AboutModal', () => {
|
||||
it('configures and renders the about modal', () => {
|
||||
// Given
|
||||
const mockOnClose = jasmine.createSpy();
|
||||
const component = shallow(
|
||||
<AboutModal.AboutModal
|
||||
build={123}
|
||||
show={true}
|
||||
version='1.0'
|
||||
onClose={mockOnClose}
|
||||
/>
|
||||
);
|
||||
|
||||
// Then
|
||||
const modal = component.find(Modal);
|
||||
expect(modal.exists()).toBe(true);
|
||||
expect(modal.prop('show')).toBe(true);
|
||||
expect(modal.prop('onClose')).toEqual(mockOnClose);
|
||||
|
||||
const versionLine = component.find('p.text-muted');
|
||||
expect(versionLine.text()).toMatch('v1.0-123');
|
||||
|
||||
const button = component.find(Button).at(0);
|
||||
expect(button.exists()).toBe(true);
|
||||
expect(button.prop('onClick')).toEqual(mockOnClose);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,123 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {Button, Form, Modal} from 'src/components';
|
||||
import * as AddDashboardModal from 'src/main/components/AddDashboardModal';
|
||||
|
||||
describe('src/main/components/AddDashboardModal', () => {
|
||||
describe('AddDashboardModal', () => {
|
||||
let mockOnClose = null;
|
||||
let mockOnSave = null;
|
||||
|
||||
beforeEach(() => {
|
||||
mockOnClose = jasmine.createSpy();
|
||||
mockOnSave = jasmine.createSpy();
|
||||
});
|
||||
|
||||
it('closes the modal when it hides', async () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AddDashboardModal.AddDashboardModal
|
||||
show={true}
|
||||
onClose={mockOnClose}
|
||||
onSave={mockOnSave}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Form.Control).at(0).simulate(
|
||||
'change', {target: {value: 'spam'}}
|
||||
);
|
||||
|
||||
const modal = component.find(Modal).at(0);
|
||||
await modal.invoke('onHide')();
|
||||
|
||||
// Then
|
||||
expect(component.find(Form.Control).at(0).prop('value')).toEqual('');
|
||||
expect(mockOnClose).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('configures and renders the name input', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AddDashboardModal.AddDashboardModal
|
||||
show={true}
|
||||
onClose={mockOnClose}
|
||||
onSave={mockOnSave}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const nameInput = component.find(Form.Control).at(0);
|
||||
|
||||
// Then
|
||||
expect(nameInput.exists()).toBe(true);
|
||||
expect(nameInput.prop('value')).toEqual('');
|
||||
});
|
||||
|
||||
it('updates the state when name input changes', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AddDashboardModal.AddDashboardModal
|
||||
show={true}
|
||||
onClose={mockOnClose}
|
||||
onSave={mockOnSave}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Form.Control).at(0).simulate(
|
||||
'change', {target: {value: 'spam'}}
|
||||
);
|
||||
|
||||
// Then
|
||||
const nameInput = component.find(Form.Control).at(0);
|
||||
expect(nameInput.prop('value')).toEqual('spam');
|
||||
});
|
||||
|
||||
it('closes the modal when cancel button is clicked', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AddDashboardModal.AddDashboardModal
|
||||
show={true}
|
||||
onClose={mockOnClose}
|
||||
onSave={mockOnSave}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Form.Control).at(0).simulate(
|
||||
'change', {target: {value: 'spam'}}
|
||||
);
|
||||
component.find(Button).at(0).simulate('click');
|
||||
|
||||
// Then
|
||||
const nameInput = component.find(Form.Control).at(0);
|
||||
expect(nameInput.prop('value')).toEqual('');
|
||||
expect(mockOnClose).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('saves and closes the modal when the save button is clicked', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AddDashboardModal.AddDashboardModal
|
||||
show={true}
|
||||
onClose={mockOnClose}
|
||||
onSave={mockOnSave}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Form.Control).at(0).simulate(
|
||||
'change', {target: {value: 'spam'}}
|
||||
);
|
||||
component.find(Button).at(1).simulate('click');
|
||||
|
||||
// Then
|
||||
const nameInput = component.find(Form.Control).at(0);
|
||||
expect(nameInput.prop('value')).toEqual('');
|
||||
expect(mockOnSave).toHaveBeenCalledWith('spam');
|
||||
expect(mockOnClose).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
18
packages/homehub_app/tests/main/components/AppLoader.spec.js
Normal file
18
packages/homehub_app/tests/main/components/AppLoader.spec.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import * as AppLoader from 'src/main/components/AppLoader';
|
||||
|
||||
describe('src/main/components/AppLoader', () => {
|
||||
describe('AppLoader', () => {
|
||||
it('allows passing an arbitrary class name', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AppLoader.AppLoader className="test" />
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.hasClass('test')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
55
packages/homehub_app/tests/main/components/Dashboard.spec.js
Normal file
55
packages/homehub_app/tests/main/components/Dashboard.spec.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {DynamicGridLayout} from 'src/components';
|
||||
import * as Dashboard from 'src/main/components/Dashboard';
|
||||
|
||||
describe('src/main/components/Dashboard', () => {
|
||||
describe('Dashboard', () => {
|
||||
let layout = null;
|
||||
let mockOnGridLayoutChange = null;
|
||||
|
||||
beforeEach(() => {
|
||||
layout = [{i: 'test', x: 0, y: 0, w: 1, h: 1}];
|
||||
mockOnGridLayoutChange = jasmine.createSpy();
|
||||
});
|
||||
|
||||
it('configures and renders the DynamicGridLayout', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<Dashboard.Dashboard
|
||||
layout={layout}
|
||||
onGridLayoutChange={mockOnGridLayoutChange}
|
||||
>
|
||||
<span key="test">It works!</span>
|
||||
</Dashboard.Dashboard>
|
||||
);
|
||||
|
||||
// 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
|
||||
);
|
||||
});
|
||||
|
||||
it('renders the children', () => {
|
||||
// Given
|
||||
const children = <span key="test">It works!</span>;
|
||||
const component = shallow(
|
||||
<Dashboard.Dashboard
|
||||
layout={layout}
|
||||
onGridLayoutChange={mockOnGridLayoutChange}
|
||||
>
|
||||
{children}
|
||||
</Dashboard.Dashboard>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.contains(children)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
531
packages/homehub_app/tests/main/components/DashboardItem.spec.js
Normal file
531
packages/homehub_app/tests/main/components/DashboardItem.spec.js
Normal file
@@ -0,0 +1,531 @@
|
||||
import Popup from '@bthlabs/react-custom-popup';
|
||||
import {shallow} from 'enzyme';
|
||||
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', () => {
|
||||
let fakeServiceState = null;
|
||||
let mockOnAppearancePopupColorChange = null;
|
||||
let mockOnServiceRestartButtonClick = null;
|
||||
let mockOnSettingsButtonClick = null;
|
||||
let mockOnSettingsModalClose = null;
|
||||
let mockOnSettingsModalNukeButtonClick = null;
|
||||
let mockOnSettingsModalSaveButtonClick = null;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeServiceState = jasmine.createSpyObj('ServiceState', ['isLoading']);
|
||||
fakeServiceState.isLoading.and.returnValue(false);
|
||||
mockOnAppearancePopupColorChange = jasmine.createSpy();
|
||||
mockOnServiceRestartButtonClick = jasmine.createSpy();
|
||||
mockOnSettingsButtonClick = jasmine.createSpy();
|
||||
mockOnSettingsModalClose = jasmine.createSpy();
|
||||
mockOnSettingsModalNukeButtonClick = jasmine.createSpy();
|
||||
mockOnSettingsModalSaveButtonClick = jasmine.createSpy();
|
||||
});
|
||||
|
||||
it('renders the children', () => {
|
||||
// Given
|
||||
const children = <span>It works!</span>;
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
{children}
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.contains(children)).toBe(true);
|
||||
});
|
||||
|
||||
it('renders the draggable handle', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('.draggable-handle').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('does not render the restart toolbar item if serviceState is null', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={null}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('WidgetToolbarItem[_hint="Restart"]').exists()).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('does not render the restart toolbar item if service state is loading', () => {
|
||||
// Given
|
||||
fakeServiceState.isLoading.and.returnValue(true);
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('WidgetToolbarItem[_hint="Restart"]').exists()).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('configures and renders the restart toolbar item', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
const restartItem = component.find('WidgetToolbarItem[_hint="Restart"]');
|
||||
|
||||
// Then
|
||||
expect(restartItem.exists()).toBe(true);
|
||||
expect(restartItem.prop('onClick')).toEqual(
|
||||
mockOnServiceRestartButtonClick
|
||||
);
|
||||
});
|
||||
|
||||
it('configures and renders the appearance toolbar item', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
const appearanceItem = component.find(
|
||||
'WidgetToolbarItem[_hint="Appearance"]'
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(appearanceItem.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('displays the appearance popup when appearance toolbar item is clicked', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('WidgetToolbarItem[_hint="Appearance"]').simulate(
|
||||
'click'
|
||||
);
|
||||
|
||||
// Then
|
||||
const popup = component.find(Popup).at(0);
|
||||
expect(popup.prop('visible')).toBe(true);
|
||||
});
|
||||
|
||||
it('does not render the settings toolbar item if hasSettingsView is false', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('WidgetToolbarItem[_hint="Settings"]').exists()).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('configures and renders the settings toolbar item', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={true}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={<span>Settings</span>}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
const settingsItem = component.find(
|
||||
'WidgetToolbarItem[_hint="Settings"]'
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(settingsItem.exists()).toBe(true);
|
||||
expect(settingsItem.prop('onClick')).toEqual(mockOnSettingsButtonClick);
|
||||
});
|
||||
|
||||
it('does not render the delete toolbar item if hasSettingsView is true', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={true}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={<span>Settings</span>}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('WidgetToolbarItem[_hint="Delete"]').exists()).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('configures and renders the delete toolbar item', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
const deleteItem = component.find(
|
||||
'WidgetToolbarItem[_hint="Delete"]'
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(deleteItem.exists()).toBe(true);
|
||||
expect(deleteItem.prop('onClick')).toEqual(
|
||||
mockOnSettingsModalNukeButtonClick
|
||||
);
|
||||
});
|
||||
|
||||
it('does not render the WidgetSettingsModal if hasSettingsView is false', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={false}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={null}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgetSettingsModal = component.find(WidgetSettingsModal).at(0);
|
||||
|
||||
// Then
|
||||
expect(widgetSettingsModal.exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('configures and renders the WidgetSettingsModal', () => {
|
||||
// Given
|
||||
const settingsView = <span>Settings</span>;
|
||||
const settingsViewProps = {spam: true};
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={true}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={settingsView}
|
||||
settingsViewProps={settingsViewProps}
|
||||
showSettingsModal={true}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgetSettingsModal = component.find(WidgetSettingsModal).at(0);
|
||||
|
||||
// Then
|
||||
expect(widgetSettingsModal.exists()).toBe(true);
|
||||
expect(widgetSettingsModal.prop('buttons').length).toEqual(1);
|
||||
expect(widgetSettingsModal.prop('settingsView')).toEqual(settingsView);
|
||||
expect(widgetSettingsModal.prop('settingsViewProps')).toEqual(
|
||||
settingsViewProps
|
||||
);
|
||||
expect(widgetSettingsModal.prop('show')).toBe(true);
|
||||
expect(widgetSettingsModal.prop('onClose')).toEqual(
|
||||
mockOnSettingsModalClose
|
||||
);
|
||||
expect(widgetSettingsModal.prop('onCancelButtonClick')).toEqual(
|
||||
mockOnSettingsModalClose
|
||||
);
|
||||
expect(widgetSettingsModal.prop('onSaveButtonClick')).toEqual(
|
||||
mockOnSettingsModalSaveButtonClick
|
||||
);
|
||||
|
||||
const nukeButtonComponent = shallow(
|
||||
widgetSettingsModal.prop('buttons')[0]
|
||||
);
|
||||
|
||||
expect(nukeButtonComponent.isEmptyRender()).toBe(false);
|
||||
expect(nukeButtonComponent.prop('onClick')).toEqual(
|
||||
mockOnSettingsModalNukeButtonClick
|
||||
);
|
||||
});
|
||||
|
||||
it('configures and renders the appearance popup wrapper', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={true}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={<span>Settings</span>}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
const popup = component.find(Popup).at(0);
|
||||
|
||||
// Then
|
||||
expect(popup.exists()).toBe(true);
|
||||
expect(popup.prop('visible')).toBe(false);
|
||||
});
|
||||
|
||||
it('hides the appearance popup wrapper when the overlay is clicked', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={true}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={<span>Settings</span>}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('WidgetToolbarItem[_hint="Appearance"]').simulate(
|
||||
'click'
|
||||
);
|
||||
component.find(Popup).at(0).invoke('onOverlayClick')();
|
||||
|
||||
// Then
|
||||
const popup = component.find(Popup).at(0);
|
||||
expect(popup.prop('visible')).toBe(false);
|
||||
});
|
||||
|
||||
it('configures and renders the appearance popup view', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={true}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={<span>Settings</span>}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
const popupView = component.find(AppearancePopup).at(0);
|
||||
|
||||
// Then
|
||||
expect(popupView.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('handles the AppearancePopup color change', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<DashboardItem.DashboardItem
|
||||
hasSettingsView={true}
|
||||
serviceState={fakeServiceState}
|
||||
settingsView={<span>Settings</span>}
|
||||
settingsViewProps={{}}
|
||||
showSettingsModal={false}
|
||||
onAppearancePopupColorChange={mockOnAppearancePopupColorChange}
|
||||
onServiceRestartButtonClick={mockOnServiceRestartButtonClick}
|
||||
onSettingsButtonClick={mockOnSettingsButtonClick}
|
||||
onSettingsModalClose={mockOnSettingsModalClose}
|
||||
onSettingsModalNukeButtonClick={mockOnSettingsModalNukeButtonClick}
|
||||
onSettingsModalSaveButtonClick={mockOnSettingsModalSaveButtonClick}
|
||||
>
|
||||
<span>It works!</span>
|
||||
</DashboardItem.DashboardItem>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('WidgetToolbarItem[_hint="Appearance"]').simulate(
|
||||
'click'
|
||||
);
|
||||
component.find(AppearancePopup).at(0).invoke('onColorChange')('red');
|
||||
|
||||
// Then
|
||||
expect(component.find(Popup).at(0).prop('visible')).toBe(false);
|
||||
expect(mockOnAppearancePopupColorChange).toHaveBeenCalledWith('red');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import * as DummyWidget from 'src/main/components/DummyWidget';
|
||||
import {UptimeService} from 'src/services/uptime';
|
||||
|
||||
describe('src/main/components/DummyWidget', () => {
|
||||
describe('DummyWidget', () => {
|
||||
it('renders the service information', () => {
|
||||
// Given
|
||||
const service = new UptimeService({instance: 'testing'});
|
||||
const component = shallow(
|
||||
<DummyWidget.DummyWidget service={service} />
|
||||
);
|
||||
|
||||
// When
|
||||
const code = component.find('code').at(0);
|
||||
|
||||
// Then
|
||||
expect(code.text()).toEqual(`${service.widget} (${service.instance})`);
|
||||
});
|
||||
});
|
||||
});
|
||||
544
packages/homehub_app/tests/main/components/StartMenu.spec.js
Normal file
544
packages/homehub_app/tests/main/components/StartMenu.spec.js
Normal file
@@ -0,0 +1,544 @@
|
||||
import {
|
||||
kServiceOfflineWeather, kServiceTime, kServiceUptime, kServiceWeather,
|
||||
kWidgetUptime, kWidgetWeather,
|
||||
} from '@bthlabs/homehub-core';
|
||||
import {Icon, IconBasicGear} from '@bthlabs/homehub-icons';
|
||||
import Popup from '@bthlabs/react-custom-popup';
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {AboutModal} from 'src/main/components/AboutModal';
|
||||
import * as StartMenu from 'src/main/components/StartMenu';
|
||||
import {SERVICES} from 'src/services';
|
||||
import {WIDGETS} from 'src/widgets';
|
||||
|
||||
import {SettingsFactory} from 'tests/__fixtures__/settings';
|
||||
|
||||
describe('src/main/components/StartMenu', () => {
|
||||
describe('ControlledStartMenu', () => {
|
||||
let mockOnAddDashboard = null;
|
||||
let mockOnAddService = null;
|
||||
let fakeSettings = null;
|
||||
|
||||
beforeEach(() => {
|
||||
mockOnAddService = jasmine.createSpy();
|
||||
mockOnAddDashboard = jasmine.createSpy();
|
||||
fakeSettings = SettingsFactory();
|
||||
});
|
||||
|
||||
it('renders the start button', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const startButton = component.find('a[_hint="StartButton"]').at(0);
|
||||
|
||||
// Then
|
||||
expect(startButton.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('displays the start menu popup when the start button is clicked', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('a[_hint="StartButton"]').at(0).simulate('click');
|
||||
|
||||
// Then
|
||||
const popup = component.find(Popup).at(0);
|
||||
expect(popup.prop('visible')).toBe(true);
|
||||
});
|
||||
|
||||
it('configures and renders the start menu popup', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const popup = component.find(Popup).at(0);
|
||||
|
||||
// Then
|
||||
expect(popup.exists()).toBe(true);
|
||||
expect(popup.prop('visible')).toBe(false);
|
||||
});
|
||||
|
||||
it('hides the start menu popup when the overlay is clicked', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('a[_hint="StartButton"]').at(0).simulate('click');
|
||||
component.find(Popup).at(0).invoke('onOverlayClick')();
|
||||
|
||||
// Then
|
||||
const popup = component.find(Popup).at(0);
|
||||
expect(popup.prop('visible')).toBe(false);
|
||||
});
|
||||
|
||||
it('renders the start menu view', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const startMenu = component.find('div[_hint="StartMenu"]').at(0);
|
||||
|
||||
// Then
|
||||
expect(startMenu.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('hides the start menu popup when the start menu is clicked', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('a[_hint="StartButton"]').at(0).simulate('click');
|
||||
component.find('div[_hint="StartMenu"]').at(0).simulate('click');
|
||||
|
||||
// Then
|
||||
const popup = component.find(Popup).at(0);
|
||||
expect(popup.prop('visible')).toBe(false);
|
||||
});
|
||||
|
||||
it('renders the about toolbar item', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const aboutItem = component.find('div[_hint="About"]').at(0);
|
||||
|
||||
// Then
|
||||
expect(aboutItem.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('displays the about modal when the about toolbar item is clicked', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('div[_hint="About"]').at(0).simulate('click');
|
||||
|
||||
// Then
|
||||
const aboutModal = component.find(AboutModal).at(0);
|
||||
expect(aboutModal.prop('show')).toBe(true);
|
||||
});
|
||||
|
||||
it('configures and renders the add dashboard toolbar item', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const addDashboardItem = component.find('div[_hint="AddDashboard"]').at(0);
|
||||
|
||||
// Then
|
||||
expect(addDashboardItem.exists()).toBe(true);
|
||||
expect(addDashboardItem.prop('onClick')).toEqual(mockOnAddDashboard);
|
||||
});
|
||||
|
||||
it('renders the reload toolbar item', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const addDashboardItem = component.find('div[_hint="Reload"]').at(0);
|
||||
|
||||
// Then
|
||||
expect(addDashboardItem.exists()).toBe(true);
|
||||
});
|
||||
|
||||
xit('reloads the page when the reload button is clicked', () => {
|
||||
// Given
|
||||
spyOn(window.location, 'reload');
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('div[_hint="Reload"]').at(0).simulate('click');
|
||||
|
||||
// Then
|
||||
expect(window.location.reload).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('Widgets', () => {
|
||||
let fakeServices = null;
|
||||
let fakeWidgets = null;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeServices = {
|
||||
[kServiceOfflineWeather]: SERVICES.kServiceOfflineWeather,
|
||||
[kServiceTime]: SERVICES.kServiceTime,
|
||||
[kServiceUptime]: SERVICES.kServiceUptime,
|
||||
[kServiceWeather]: SERVICES.kServiceWeather,
|
||||
};
|
||||
fakeWidgets = {
|
||||
[kWidgetUptime]: WIDGETS.kWidgetUptime,
|
||||
[kWidgetWeather]: WIDGETS.kWidgetWeather,
|
||||
};
|
||||
});
|
||||
|
||||
it('renders the list of widgets available in online mode', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={fakeServices}
|
||||
settings={fakeSettings}
|
||||
widgets={fakeWidgets}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgets = component.find('div[_hint="Widgets"]').at(0);
|
||||
|
||||
// Then
|
||||
const serviceKeys = widgets.find('div[_hint="Widget"]').map((wrapper) => {
|
||||
return wrapper.prop('data-service');
|
||||
});
|
||||
expect(serviceKeys.length).toEqual(3);
|
||||
expect(serviceKeys).not.toContain(kServiceOfflineWeather);
|
||||
expect(serviceKeys).toContain(kServiceTime);
|
||||
expect(serviceKeys).toContain(kServiceUptime);
|
||||
expect(serviceKeys).toContain(kServiceWeather);
|
||||
});
|
||||
|
||||
it('renders the list of widgets available in offline mode', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={true}
|
||||
services={fakeServices}
|
||||
settings={fakeSettings}
|
||||
widgets={fakeWidgets}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgets = component.find('div[_hint="Widgets"]').at(0);
|
||||
|
||||
// Then
|
||||
const serviceKeys = widgets.find('div[_hint="Widget"]').map((wrapper) => {
|
||||
return wrapper.prop('data-service');
|
||||
});
|
||||
expect(serviceKeys.length).toEqual(2);
|
||||
expect(serviceKeys).toContain(kServiceOfflineWeather);
|
||||
expect(serviceKeys).toContain(kServiceTime);
|
||||
expect(serviceKeys).not.toContain(kServiceUptime);
|
||||
expect(serviceKeys).not.toContain(kServiceWeather);
|
||||
});
|
||||
|
||||
it('configures and renders a widget item for a known widget', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={fakeServices}
|
||||
settings={fakeSettings}
|
||||
widgets={fakeWidgets}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgetItem = component.find(
|
||||
`div[data-service="${kServiceWeather}"]`
|
||||
).at(
|
||||
0
|
||||
);
|
||||
const icon = widgetItem.find(Icon).at(0);
|
||||
const title = widgetItem.find('p').at(0);
|
||||
|
||||
// Then
|
||||
expect(widgetItem.hasClass('disabled')).toBe(false);
|
||||
expect(icon.prop('icon')).toEqual(fakeWidgets[kWidgetWeather].icon);
|
||||
expect(title.text()).toEqual(fakeWidgets[kWidgetWeather].title);
|
||||
});
|
||||
|
||||
it('configures and renders a widget item for an unknown widget', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={fakeServices}
|
||||
settings={fakeSettings}
|
||||
widgets={fakeWidgets}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgetItem = component.find(
|
||||
`div[data-service="${kServiceTime}"]`
|
||||
).at(
|
||||
0
|
||||
);
|
||||
const icon = widgetItem.find(Icon).at(0);
|
||||
const title = widgetItem.find('p').at(0);
|
||||
|
||||
// Then
|
||||
expect(icon.prop('icon')).toEqual(IconBasicGear);
|
||||
expect(title.text()).toEqual('Unnamed Widget');
|
||||
});
|
||||
|
||||
it('renders widgets as disabled if it has no dashboards', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={false}
|
||||
offlineMode={false}
|
||||
services={fakeServices}
|
||||
settings={fakeSettings}
|
||||
widgets={fakeWidgets}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgetItem = component.find(
|
||||
`div[data-service="${kServiceWeather}"]`
|
||||
).at(
|
||||
0
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(widgetItem.hasClass('disabled')).toBe(true);
|
||||
});
|
||||
|
||||
it('handles a widget item click', () => {
|
||||
// Given
|
||||
const mockEventPreventDefault = jasmine.createSpy();
|
||||
const mockEventStopPropagation = jasmine.createSpy();
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={fakeServices}
|
||||
settings={fakeSettings}
|
||||
widgets={fakeWidgets}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgetItem = component.find(
|
||||
`div[data-service="${kServiceTime}"]`
|
||||
).at(
|
||||
0
|
||||
);
|
||||
widgetItem.simulate('click', {
|
||||
currentTarget: {
|
||||
dataset: {service: kServiceTime},
|
||||
},
|
||||
preventDefault: mockEventPreventDefault,
|
||||
stopPropagation: mockEventStopPropagation,
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(mockOnAddService).toHaveBeenCalledWith(kServiceTime);
|
||||
expect(mockEventPreventDefault).not.toHaveBeenCalled();
|
||||
expect(mockEventStopPropagation).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('cancels the event when it does not have dashboards', () => {
|
||||
// Given
|
||||
const mockEventPreventDefault = jasmine.createSpy();
|
||||
const mockEventStopPropagation = jasmine.createSpy();
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={false}
|
||||
offlineMode={false}
|
||||
services={fakeServices}
|
||||
settings={fakeSettings}
|
||||
widgets={fakeWidgets}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgetItem = component.find(
|
||||
`div[data-service="${kServiceTime}"]`
|
||||
).at(
|
||||
0
|
||||
);
|
||||
widgetItem.simulate('click', {
|
||||
currentTarget: {
|
||||
dataset: {service: kServiceTime},
|
||||
},
|
||||
preventDefault: mockEventPreventDefault,
|
||||
stopPropagation: mockEventStopPropagation,
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(mockOnAddService).not.toHaveBeenCalled();
|
||||
expect(mockEventPreventDefault).toHaveBeenCalled();
|
||||
expect(mockEventStopPropagation).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('configures and renders the about modal', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const aboutModal = component.find(AboutModal).at(0);
|
||||
|
||||
// Then
|
||||
expect(aboutModal.exists()).toBe(true);
|
||||
expect(aboutModal.prop('build')).toEqual(123);
|
||||
expect(aboutModal.prop('show')).toBe(false);
|
||||
expect(aboutModal.prop('version')).toEqual('1.0');
|
||||
});
|
||||
|
||||
it('displays the about modal when it closes', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<StartMenu.ControlledStartMenu
|
||||
hasDashboards={true}
|
||||
offlineMode={false}
|
||||
services={SERVICES}
|
||||
settings={fakeSettings}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('div[_hint="About"]').at(0).simulate('click');
|
||||
component.find(AboutModal).at(0).invoke('onClose')();
|
||||
|
||||
// Then
|
||||
const aboutModal = component.find(AboutModal).at(0);
|
||||
expect(aboutModal.prop('show')).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
273
packages/homehub_app/tests/main/components/Taskbar.spec.js
Normal file
273
packages/homehub_app/tests/main/components/Taskbar.spec.js
Normal file
@@ -0,0 +1,273 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {StartMenu} from 'src/main/components/StartMenu';
|
||||
import * as Taskbar from 'src/main/components/Taskbar';
|
||||
import {SERVICES} from 'src/services';
|
||||
import {WIDGETS} from 'src/widgets';
|
||||
|
||||
import {DashboardsFactory} from 'tests/__fixtures__/dashboards';
|
||||
|
||||
describe('src/main/components/Taskbar', () => {
|
||||
describe('Taskbar', () => {
|
||||
let mockOnAddDashboard = null;
|
||||
let mockOnAddService = null;
|
||||
let mockOnSelectDashboard = null;
|
||||
let fakeDashboards = null;
|
||||
let fakeSavingState = null;
|
||||
let fakeWebSocketState = null;
|
||||
|
||||
beforeEach(() => {
|
||||
mockOnAddDashboard = jasmine.createSpy();
|
||||
mockOnAddService = jasmine.createSpy();
|
||||
mockOnSelectDashboard = jasmine.createSpy();
|
||||
fakeDashboards = DashboardsFactory();
|
||||
fakeSavingState = {
|
||||
isSaving: false,
|
||||
lastSaveError: null,
|
||||
lastSaveTimestamp: new Date(1987, 9, 3, 8, 0, 0),
|
||||
};
|
||||
fakeWebSocketState = {
|
||||
isWebSocketConnected: true,
|
||||
};
|
||||
});
|
||||
|
||||
it('configures and renders the start menu', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<Taskbar.Taskbar
|
||||
currentDashboardId="testing"
|
||||
dashboards={fakeDashboards}
|
||||
offlineMode={false}
|
||||
savingState={fakeSavingState}
|
||||
services={SERVICES}
|
||||
webSocketState={fakeWebSocketState}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const startMenu = component.find(StartMenu).at(0);
|
||||
|
||||
// Then
|
||||
expect(startMenu.exists()).toBe(true);
|
||||
expect(startMenu.prop('offlineMode')).toBe(false);
|
||||
expect(startMenu.prop('services')).toEqual(SERVICES);
|
||||
expect(startMenu.prop('widgets')).toEqual(WIDGETS);
|
||||
expect(startMenu.prop('onAddDashboard')).toEqual(mockOnAddDashboard);
|
||||
expect(startMenu.prop('onAddService')).toEqual(mockOnAddService);
|
||||
});
|
||||
|
||||
it('configures renders the dashboard buttons', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<Taskbar.Taskbar
|
||||
currentDashboardId="testing"
|
||||
dashboards={fakeDashboards}
|
||||
offlineMode={false}
|
||||
savingState={fakeSavingState}
|
||||
services={SERVICES}
|
||||
webSocketState={fakeWebSocketState}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const dashboardButtons = component.find('a[_hint="Dashboard"]');
|
||||
|
||||
// Then
|
||||
expect(dashboardButtons.length).toEqual(2);
|
||||
|
||||
const dashboardButton = dashboardButtons.at(0);
|
||||
expect(dashboardButton.hasClass('active')).toBe(true);
|
||||
expect(dashboardButton.prop('data-dashboard')).toEqual(
|
||||
fakeDashboards[0].id
|
||||
);
|
||||
expect(dashboardButton.text()).toEqual(fakeDashboards[0].name);
|
||||
|
||||
expect(dashboardButtons.at(1).hasClass('active')).toBe(false);
|
||||
});
|
||||
|
||||
it('selects a dashboard when its button is clicked', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<Taskbar.Taskbar
|
||||
currentDashboardId="testing"
|
||||
dashboards={fakeDashboards}
|
||||
offlineMode={false}
|
||||
savingState={fakeSavingState}
|
||||
services={SERVICES}
|
||||
webSocketState={fakeWebSocketState}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
onSelectDashboard={mockOnSelectDashboard}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find('a[_hint="Dashboard"]').at(0).simulate('click', {
|
||||
currentTarget: {
|
||||
dataset: {dashboard: fakeDashboards[0].id},
|
||||
},
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(mockOnSelectDashboard).toHaveBeenCalledWith(fakeDashboards[0].id);
|
||||
});
|
||||
|
||||
it('does not render websocket status in offline mode', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<Taskbar.Taskbar
|
||||
currentDashboardId="testing"
|
||||
dashboards={fakeDashboards}
|
||||
offlineMode={true}
|
||||
savingState={fakeSavingState}
|
||||
services={SERVICES}
|
||||
webSocketState={fakeWebSocketState}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
onSelectDashboard={mockOnSelectDashboard}
|
||||
/>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('Icon[_hint="WebSocketConnected"]').exists()).toBe(
|
||||
false
|
||||
);
|
||||
expect(component.find('Icon[_hint="WebSocketNotConnected"]').exists()).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('renders the websocket connection status when websocket is connected', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<Taskbar.Taskbar
|
||||
currentDashboardId="testing"
|
||||
dashboards={fakeDashboards}
|
||||
offlineMode={false}
|
||||
savingState={fakeSavingState}
|
||||
services={SERVICES}
|
||||
webSocketState={fakeWebSocketState}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
onSelectDashboard={mockOnSelectDashboard}
|
||||
/>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('Icon[_hint="WebSocketConnected"]').exists()).toBe(
|
||||
true
|
||||
);
|
||||
expect(component.find('Icon[_hint="WebSocketNotConnected"]').exists()).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('renders the websocket connection status when websocket is not connected', () => {
|
||||
// Given
|
||||
fakeWebSocketState.isWebSocketConnected = false;
|
||||
const component = shallow(
|
||||
<Taskbar.Taskbar
|
||||
currentDashboardId="testing"
|
||||
dashboards={fakeDashboards}
|
||||
offlineMode={false}
|
||||
savingState={fakeSavingState}
|
||||
services={SERVICES}
|
||||
webSocketState={fakeWebSocketState}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
onSelectDashboard={mockOnSelectDashboard}
|
||||
/>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('Icon[_hint="WebSocketConnected"]').exists()).toBe(
|
||||
false
|
||||
);
|
||||
expect(component.find('Icon[_hint="WebSocketNotConnected"]').exists()).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it('renders the saving status when it is saving', () => {
|
||||
// Given
|
||||
fakeSavingState.isSaving = true;
|
||||
const component = shallow(
|
||||
<Taskbar.Taskbar
|
||||
currentDashboardId="testing"
|
||||
dashboards={fakeDashboards}
|
||||
offlineMode={false}
|
||||
savingState={fakeSavingState}
|
||||
services={SERVICES}
|
||||
webSocketState={fakeWebSocketState}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
onSelectDashboard={mockOnSelectDashboard}
|
||||
/>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('Icon[_hint="IsSaving"]').exists()).toBe(true);
|
||||
expect(component.find('Icon[_hint="SaveError"]').exists()).toBe(false);
|
||||
expect(component.find('Icon[_hint="SaveOK"]').exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('renders the saving status when last save was an error', () => {
|
||||
// Given
|
||||
fakeSavingState.lastSaveError = 'FIAL';
|
||||
const component = shallow(
|
||||
<Taskbar.Taskbar
|
||||
currentDashboardId="testing"
|
||||
dashboards={fakeDashboards}
|
||||
offlineMode={false}
|
||||
savingState={fakeSavingState}
|
||||
services={SERVICES}
|
||||
webSocketState={fakeWebSocketState}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
onSelectDashboard={mockOnSelectDashboard}
|
||||
/>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('Icon[_hint="IsSaving"]').exists()).toBe(false);
|
||||
expect(component.find('Icon[_hint="SaveError"]').exists()).toBe(true);
|
||||
expect(component.find('Icon[_hint="SaveOK"]').exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('renders the saving status when last save was OK', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<Taskbar.Taskbar
|
||||
currentDashboardId="testing"
|
||||
dashboards={fakeDashboards}
|
||||
offlineMode={false}
|
||||
savingState={fakeSavingState}
|
||||
services={SERVICES}
|
||||
webSocketState={fakeWebSocketState}
|
||||
widgets={WIDGETS}
|
||||
onAddDashboard={mockOnAddDashboard}
|
||||
onAddService={mockOnAddService}
|
||||
onSelectDashboard={mockOnSelectDashboard}
|
||||
/>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.find('Icon[_hint="IsSaving"]').exists()).toBe(false);
|
||||
expect(component.find('Icon[_hint="SaveError"]').exists()).toBe(false);
|
||||
expect(component.find('Icon[_hint="SaveOK"]').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,133 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {Button, Modal} from 'src/components';
|
||||
import * as WidgetSettingsModal from 'src/main/components/WidgetSettingsModal';
|
||||
|
||||
describe('src/main/components/WidgetSettingsModal', () => {
|
||||
describe('WidgetSettingsModal', () => {
|
||||
let mockOnCancelButtonClick = null;
|
||||
let mockOnClose = null;
|
||||
let mockOnSaveButtonClick = null;
|
||||
let fakeSettingsView = null;
|
||||
let fakeSettingsViewProps = null;
|
||||
|
||||
beforeEach(() => {
|
||||
mockOnCancelButtonClick = jasmine.createSpy();
|
||||
mockOnClose = jasmine.createSpy();
|
||||
mockOnSaveButtonClick = jasmine.createSpy();
|
||||
fakeSettingsView = jasmine.createSpy().and.returnValue(
|
||||
<span>Settings</span>
|
||||
);
|
||||
fakeSettingsView.displayName = 'FakeSettingsView';
|
||||
fakeSettingsViewProps = {spam: true};
|
||||
});
|
||||
|
||||
it('configures and renders the modal', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<WidgetSettingsModal.WidgetSettingsModal
|
||||
buttons={[]}
|
||||
settingsView={fakeSettingsView}
|
||||
settingsViewProps={fakeSettingsViewProps}
|
||||
show={false}
|
||||
onCancelButtonClick={mockOnCancelButtonClick}
|
||||
onClose={mockOnClose}
|
||||
onSaveButtonClick={mockOnSaveButtonClick}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const modal = component.find(Modal).at(0);
|
||||
|
||||
// Then
|
||||
expect(modal.exists()).toBe(true);
|
||||
expect(modal.prop('show')).toBe(false);
|
||||
expect(modal.prop('onHide')).toEqual(mockOnClose);
|
||||
});
|
||||
|
||||
it('configures and renders the settings view', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<WidgetSettingsModal.WidgetSettingsModal
|
||||
buttons={[]}
|
||||
settingsView={fakeSettingsView}
|
||||
settingsViewProps={fakeSettingsViewProps}
|
||||
show={false}
|
||||
onCancelButtonClick={mockOnCancelButtonClick}
|
||||
onClose={mockOnClose}
|
||||
onSaveButtonClick={mockOnSaveButtonClick}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const settingsView = component.find(fakeSettingsView).at(0);
|
||||
|
||||
// Then
|
||||
expect(settingsView.props()).toEqual(fakeSettingsViewProps);
|
||||
});
|
||||
|
||||
it('renders the additional buttons', () => {
|
||||
// Given
|
||||
const button = <Button key="testing">Test</Button>;
|
||||
const component = shallow(
|
||||
<WidgetSettingsModal.WidgetSettingsModal
|
||||
buttons={[button]}
|
||||
settingsView={fakeSettingsView}
|
||||
settingsViewProps={fakeSettingsViewProps}
|
||||
show={false}
|
||||
onCancelButtonClick={mockOnCancelButtonClick}
|
||||
onClose={mockOnClose}
|
||||
onSaveButtonClick={mockOnSaveButtonClick}
|
||||
/>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.contains(button)).toBe(true);
|
||||
});
|
||||
|
||||
it('configures and renders the cancel button', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<WidgetSettingsModal.WidgetSettingsModal
|
||||
buttons={[]}
|
||||
settingsView={fakeSettingsView}
|
||||
settingsViewProps={fakeSettingsViewProps}
|
||||
show={false}
|
||||
onCancelButtonClick={mockOnCancelButtonClick}
|
||||
onClose={mockOnClose}
|
||||
onSaveButtonClick={mockOnSaveButtonClick}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const button = component.find('Button[_hint="Cancel"]').at(0);
|
||||
|
||||
// Then
|
||||
expect(button.exists()).toBe(true);
|
||||
expect(button.prop('onClick')).toEqual(mockOnCancelButtonClick);
|
||||
});
|
||||
|
||||
it('configures and renders the save button', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<WidgetSettingsModal.WidgetSettingsModal
|
||||
buttons={[]}
|
||||
settingsView={fakeSettingsView}
|
||||
settingsViewProps={fakeSettingsViewProps}
|
||||
show={false}
|
||||
onCancelButtonClick={mockOnCancelButtonClick}
|
||||
onClose={mockOnClose}
|
||||
onSaveButtonClick={mockOnSaveButtonClick}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const button = component.find('Button[_hint="Save"]').at(0);
|
||||
|
||||
// Then
|
||||
expect(button.exists()).toBe(true);
|
||||
expect(button.prop('onClick')).toEqual(mockOnSaveButtonClick);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,98 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import * as WidgetToolbar from 'src/main/components/WidgetToolbar';
|
||||
|
||||
describe('src/main/components/WidgetToolbar', () => {
|
||||
describe('WidgetToolbar', () => {
|
||||
it('allows passing an arbitrary class name', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<WidgetToolbar.WidgetToolbar className="test">
|
||||
<span>It works!</span>
|
||||
</WidgetToolbar.WidgetToolbar>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.hasClass('test')).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a right-side toolbar', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<WidgetToolbar.WidgetToolbar right>
|
||||
<span>It works!</span>
|
||||
</WidgetToolbar.WidgetToolbar>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.hasClass('left')).toBe(false);
|
||||
expect(component.hasClass('right')).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a left-side toolbar', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<WidgetToolbar.WidgetToolbar>
|
||||
<span>It works!</span>
|
||||
</WidgetToolbar.WidgetToolbar>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.hasClass('left')).toBe(true);
|
||||
expect(component.hasClass('right')).toBe(false);
|
||||
});
|
||||
|
||||
it('renders the children', () => {
|
||||
// Given
|
||||
const children = <span>It works!</span>;
|
||||
const component = shallow(
|
||||
<WidgetToolbar.WidgetToolbar right>
|
||||
{children}
|
||||
</WidgetToolbar.WidgetToolbar>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.contains(children)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('WidgetToolbar.Item', () => {
|
||||
it('allows passing an arbitrary class name', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<WidgetToolbar.WidgetToolbar.Item className="test">
|
||||
<span>It works!</span>
|
||||
</WidgetToolbar.WidgetToolbar.Item>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.hasClass('test')).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a danger item', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<WidgetToolbar.WidgetToolbar.Item danger>
|
||||
<span>It works!</span>
|
||||
</WidgetToolbar.WidgetToolbar.Item>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.hasClass('danger')).toBe(true);
|
||||
});
|
||||
|
||||
it('renders the children', () => {
|
||||
// Given
|
||||
const children = <span>It works!</span>;
|
||||
const component = shallow(
|
||||
<WidgetToolbar.WidgetToolbar.Item>
|
||||
{children}
|
||||
</WidgetToolbar.WidgetToolbar.Item>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.contains(children)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,170 @@
|
||||
import {
|
||||
DashboardsContext, ServiceContainer, ServiceState,
|
||||
} from '@bthlabs/homehub-core';
|
||||
import {mount} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {Dashboard, DashboardItem, DummyWidget} from 'src/main/components';
|
||||
import * as DashboardContainer from 'src/main/containers/DashboardContainer';
|
||||
|
||||
import {DashboardsContextFactory} from 'tests/__fixtures__/dashboardsContext';
|
||||
import {FakeWidget} from 'tests/__fixtures__/services';
|
||||
import {SettingsFactory} from 'tests/__fixtures__/settings';
|
||||
|
||||
describe('src/main/containers/DashboardContainer', () => {
|
||||
describe('ControlledDashboardContainer', () => {
|
||||
let fakeDashboardsContext = null;
|
||||
let fakeSettings = null;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeDashboardsContext = DashboardsContextFactory();
|
||||
fakeSettings = SettingsFactory();
|
||||
});
|
||||
|
||||
it('handles grid layout change', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<DashboardContainer.ControlledDashboardContainer
|
||||
settings={fakeSettings}
|
||||
/>
|
||||
</DashboardsContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
const dashboard = component.find(Dashboard).at(0);
|
||||
dashboard.invoke('onGridLayoutChange')([
|
||||
{i: 'fake_instance', x: 0, y: 0, w: 1, h: 1},
|
||||
{i: 'other_fake_instance', x: 1, y: 1, w: 1, h: 1},
|
||||
]);
|
||||
|
||||
// Then
|
||||
expect(fakeDashboardsContext.saveServiceLayout).toHaveBeenCalledWith(
|
||||
'fake_instance', {x: 0, y: 0, w: 1, h: 1}
|
||||
);
|
||||
expect(fakeDashboardsContext.saveServiceLayout).toHaveBeenCalledWith(
|
||||
'other_fake_instance', {x: 1, y: 1, w: 1, h: 1}
|
||||
);
|
||||
});
|
||||
|
||||
it('configures and renders the dashboard', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<DashboardContainer.ControlledDashboardContainer
|
||||
settings={fakeSettings}
|
||||
/>
|
||||
</DashboardsContext.Provider>
|
||||
);
|
||||
|
||||
const expectedLayout = [
|
||||
{i: 'fake_instance', x: 0, y: 0, w: 1, h: 1, minW: 1, minH: 1},
|
||||
{i: 'other_fake_instance', x: 0, y: 1, w: 1, h: 1},
|
||||
];
|
||||
|
||||
// When
|
||||
const dashboard = component.find(Dashboard).at(0);
|
||||
|
||||
// Then
|
||||
expect(dashboard.exists()).toBe(true);
|
||||
expect(dashboard.prop('layout')).toEqual(expectedLayout);
|
||||
});
|
||||
|
||||
it('configures and render a ServiceContainer for services', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<DashboardContainer.ControlledDashboardContainer
|
||||
settings={fakeSettings}
|
||||
/>
|
||||
</DashboardsContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
const serviceContainers = component.find(ServiceContainer);
|
||||
|
||||
// Then
|
||||
expect(serviceContainers.length).toEqual(2);
|
||||
|
||||
const serviceContainer = serviceContainers.at(0);
|
||||
expect(serviceContainer.prop('instance')).toEqual(
|
||||
fakeDashboardsContext.dashboards[0].services[0].instance
|
||||
);
|
||||
expect(serviceContainer.prop('kind')).toEqual(
|
||||
fakeDashboardsContext.dashboards[0].services[0].kind
|
||||
);
|
||||
});
|
||||
|
||||
it('configures and renders a DashboardItem for services', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<DashboardContainer.ControlledDashboardContainer
|
||||
settings={fakeSettings}
|
||||
/>
|
||||
</DashboardsContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
const dashboardItems = component.find(DashboardItem);
|
||||
|
||||
// Then
|
||||
expect(dashboardItems.length).toEqual(2);
|
||||
|
||||
const dashboardItem = dashboardItems.at(0);
|
||||
expect(dashboardItem.prop('settingsView')).toEqual(
|
||||
FakeWidget.settingsView
|
||||
);
|
||||
expect(dashboardItem.prop('settingsViewProps').settings).toEqual(
|
||||
fakeSettings
|
||||
);
|
||||
|
||||
expect(dashboardItems.at(1).prop('settingsView')).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('configures and renders a widget for services', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<DashboardContainer.ControlledDashboardContainer
|
||||
settings={fakeSettings}
|
||||
/>
|
||||
</DashboardsContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
const widget = component.find(FakeWidget).at(0);
|
||||
|
||||
// Then
|
||||
expect(widget.exists()).toBe(true);
|
||||
expect(widget.prop('appearance')).toEqual(
|
||||
fakeDashboardsContext.dashboards[0].services[0].characteristics.appearance
|
||||
);
|
||||
expect(widget.prop('service')).toEqual(
|
||||
fakeDashboardsContext.dashboards[0].services[0]
|
||||
);
|
||||
expect(widget.prop('serviceState')).toBeInstanceOf(ServiceState);
|
||||
expect(widget.prop('setServiceState')).toBeDefined();
|
||||
});
|
||||
|
||||
it('renders a DummyWidget for service with unknown widget', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<DashboardContainer.ControlledDashboardContainer
|
||||
settings={fakeSettings}
|
||||
/>
|
||||
</DashboardsContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
const widget = component.find(DummyWidget).at(0);
|
||||
|
||||
// Then
|
||||
expect(widget.exists()).toBe(true);
|
||||
expect(widget.prop('service')).toEqual(
|
||||
fakeDashboardsContext.dashboards[0].services[1]
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,270 @@
|
||||
import {DashboardsContext} from '@bthlabs/homehub-core';
|
||||
import {RangoAppContext} from '@bthlabs/rango';
|
||||
import {mount} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
AddDashboardModal, Taskbar, WidgetSettingsModal,
|
||||
} from 'src/main/components';
|
||||
import * as TaskbarContainer from 'src/main/containers/TaskbarContainer';
|
||||
|
||||
import {DashboardsContextFactory} from 'tests/__fixtures__/dashboardsContext';
|
||||
import {
|
||||
FakeService, FakeServiceWithoutSettings, FakeWidget,
|
||||
} from 'tests/__fixtures__/services';
|
||||
import {SettingsFactory} from 'tests/__fixtures__/settings';
|
||||
|
||||
describe('src/main/containers/TaskbarContainer', () => {
|
||||
describe('TaskbarContainer', () => {
|
||||
let fakeDashboardsContext = null;
|
||||
let fakeSettings = null;
|
||||
let fakeRangoAppContext = null;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeDashboardsContext = DashboardsContextFactory();
|
||||
fakeSettings = SettingsFactory();
|
||||
fakeRangoAppContext = {settings: fakeSettings};
|
||||
});
|
||||
|
||||
it('configures the WidgetSettingsModal to show settings view for added service', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Taskbar).at(0).invoke('onAddService')(FakeService.kind);
|
||||
component.setProps({});
|
||||
|
||||
// Then
|
||||
const widgetSettingsModal = component.find(WidgetSettingsModal).at(0);
|
||||
expect(widgetSettingsModal.prop('settingsView')).toEqual(
|
||||
FakeWidget.settingsView
|
||||
);
|
||||
expect(widgetSettingsModal.prop('settingsViewProps')).toEqual({
|
||||
nextCharacteristics: FakeService.emptyCharacteristics(),
|
||||
settings: fakeSettings,
|
||||
setNextCharacteristics: jasmine.any(Function),
|
||||
});
|
||||
expect(fakeDashboardsContext.addService).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('immediately adds a service that does not use settings view', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Taskbar).at(0).invoke('onAddService')(
|
||||
FakeServiceWithoutSettings.kind
|
||||
);
|
||||
component.setProps({});
|
||||
|
||||
// Then
|
||||
expect(fakeDashboardsContext.addService).toHaveBeenCalledWith(
|
||||
FakeServiceWithoutSettings.kind,
|
||||
FakeServiceWithoutSettings.emptyCharacteristics()
|
||||
);
|
||||
});
|
||||
|
||||
it('handles the WidgetSettingsModal being closed', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Taskbar).at(0).invoke('onAddService')(FakeService.kind);
|
||||
component.setProps({});
|
||||
|
||||
component.find(WidgetSettingsModal).at(0).invoke('onClose')();
|
||||
component.setProps({});
|
||||
|
||||
// Then
|
||||
const widgetSettingsModal = component.find(WidgetSettingsModal).at(0);
|
||||
expect(widgetSettingsModal.prop('settingsView')).toBe(null);
|
||||
expect(widgetSettingsModal.prop('settingsViewProps')).toEqual({});
|
||||
});
|
||||
|
||||
it('handles the WidgetSettingsModal save button click', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Taskbar).at(0).invoke('onAddService')(FakeService.kind);
|
||||
component.setProps({});
|
||||
|
||||
component.find(WidgetSettingsModal).at(0).invoke('onSaveButtonClick')();
|
||||
component.setProps({});
|
||||
|
||||
// Then
|
||||
expect(fakeDashboardsContext.addService).toHaveBeenCalledWith(
|
||||
FakeService.kind,
|
||||
FakeService.emptyCharacteristics()
|
||||
);
|
||||
});
|
||||
|
||||
it('displays the AddDashboardModal when add dashboard button is clicked', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Taskbar).at(0).invoke('onAddDashboard')();
|
||||
|
||||
// Then
|
||||
const addDashboardModal = component.find(AddDashboardModal).at(0);
|
||||
expect(addDashboardModal.prop('show')).toBe(true);
|
||||
});
|
||||
|
||||
it('hides the AddDashboardModal when it is closed', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Taskbar).at(0).invoke('onAddDashboard')();
|
||||
component.find(AddDashboardModal).at(0).invoke('onClose')();
|
||||
|
||||
// Then
|
||||
const addDashboardModal = component.find(AddDashboardModal).at(0);
|
||||
expect(addDashboardModal.prop('show')).toBe(false);
|
||||
});
|
||||
|
||||
it('handles the AddDashboardModal save button click', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(AddDashboardModal).at(0).invoke('onSave')('Testing2');
|
||||
|
||||
// Then
|
||||
expect(fakeDashboardsContext.addDashboard).toHaveBeenCalledWith(
|
||||
'Testing2'
|
||||
);
|
||||
});
|
||||
|
||||
it('sets a selected dashboard as current', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
component.find(Taskbar).at(0).invoke('onSelectDashboard')('testing2');
|
||||
|
||||
// Then
|
||||
expect(fakeDashboardsContext.setCurrentDashboardId).toHaveBeenCalledWith(
|
||||
'testing2'
|
||||
);
|
||||
});
|
||||
|
||||
it('configures and renders the Taskbar', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
const taskbar = component.find(Taskbar).at(0);
|
||||
|
||||
// Then
|
||||
expect(taskbar.exists()).toBe(true);
|
||||
expect(taskbar.prop('currentDashboardId')).toEqual(
|
||||
fakeDashboardsContext.currentDashboardId
|
||||
);
|
||||
expect(taskbar.prop('dashboards')).toEqual(
|
||||
fakeDashboardsContext.dashboards
|
||||
);
|
||||
expect(taskbar.prop('offlineMode')).toEqual(fakeSettings.OFFLINE_MODE);
|
||||
expect(taskbar.prop('savingState')).toEqual({
|
||||
isSaving: false,
|
||||
lastSaveError: null,
|
||||
lastSaveTimestamp: null,
|
||||
});
|
||||
expect(taskbar.prop('services')).toEqual(fakeSettings.SERVICES);
|
||||
expect(taskbar.prop('webSocketState')).toEqual({
|
||||
isWebSocketConnected: false,
|
||||
});
|
||||
expect(taskbar.prop('widgets')).toEqual(fakeSettings.WIDGETS);
|
||||
});
|
||||
|
||||
it('configures and renders the WidgetSettingsModal', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
const widgetSettingsModal = component.find(WidgetSettingsModal).at(0);
|
||||
|
||||
// Then
|
||||
expect(widgetSettingsModal.exists()).toBe(true);
|
||||
expect(widgetSettingsModal.prop('show')).toBe(true);
|
||||
});
|
||||
|
||||
it('configures and renders the AddDashboardModal', () => {
|
||||
// Given
|
||||
const component = mount(
|
||||
<RangoAppContext.Provider value={fakeRangoAppContext}>
|
||||
<DashboardsContext.Provider value={fakeDashboardsContext}>
|
||||
<TaskbarContainer.TaskbarContainer />
|
||||
</DashboardsContext.Provider>
|
||||
</RangoAppContext.Provider>
|
||||
);
|
||||
|
||||
// When
|
||||
const addDashboardModal = component.find(AddDashboardModal).at(0);
|
||||
|
||||
// Then
|
||||
expect(addDashboardModal.exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,147 @@
|
||||
import * as HomeHubCore from '@bthlabs/homehub-core';
|
||||
|
||||
import * as StateDataSource from 'src/main/dataSources/StateDataSource';
|
||||
|
||||
describe('src/lib/main/dataSources/StateDataSource', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(HomeHubCore.API.State, 'get');
|
||||
spyOn(HomeHubCore.API.State, 'save');
|
||||
spyOn(HomeHubCore.LocalStorage, 'getItem');
|
||||
spyOn(HomeHubCore.LocalStorage, 'setItem');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
StateDataSource.setOfflineMode(false);
|
||||
});
|
||||
|
||||
describe('loadState', () => {
|
||||
it('throws an error if API call in online mode returns an error', async () => {
|
||||
// Given
|
||||
StateDataSource.setOfflineMode(false);
|
||||
HomeHubCore.API.State.get.and.resolveTo({
|
||||
error: 'FIAL',
|
||||
});
|
||||
|
||||
// When
|
||||
let result = null;
|
||||
try {
|
||||
await StateDataSource.loadState();
|
||||
} catch (error) {
|
||||
result = error;
|
||||
}
|
||||
|
||||
// Then
|
||||
expect(result).toEqual('FIAL');
|
||||
});
|
||||
|
||||
it('returns state loaded from the API in online mode', async () => {
|
||||
// Given
|
||||
StateDataSource.setOfflineMode(false);
|
||||
const data = {dashboards: []};
|
||||
HomeHubCore.API.State.get.and.resolveTo({
|
||||
data: data,
|
||||
});
|
||||
|
||||
// When
|
||||
const result = await StateDataSource.loadState();
|
||||
|
||||
// Then
|
||||
expect(result).toEqual(data);
|
||||
expect(HomeHubCore.API.State.get).toHaveBeenCalled();
|
||||
expect(HomeHubCore.LocalStorage.getItem).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns state loaded from local storage in offline mode', async () => {
|
||||
// Given
|
||||
StateDataSource.setOfflineMode(true);
|
||||
const data = {dashboards: []};
|
||||
HomeHubCore.LocalStorage.getItem.and.returnValue(JSON.stringify(data));
|
||||
|
||||
// When
|
||||
const result = await StateDataSource.loadState();
|
||||
|
||||
// Then
|
||||
expect(result).toEqual(data);
|
||||
expect(HomeHubCore.API.State.get).not.toHaveBeenCalled();
|
||||
expect(HomeHubCore.LocalStorage.getItem).toHaveBeenCalledWith('state');
|
||||
});
|
||||
|
||||
it('returns initial state if it is missing in local storage in offline mode', async () => {
|
||||
// Given
|
||||
StateDataSource.setOfflineMode(true);
|
||||
HomeHubCore.LocalStorage.getItem.and.returnValue(null);
|
||||
|
||||
// When
|
||||
const result = await StateDataSource.loadState();
|
||||
|
||||
// Then
|
||||
expect(result.dashboards.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('doSaveState', () => {
|
||||
let fakeState = null;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeState = {
|
||||
dashboards: [
|
||||
{
|
||||
id: 'testing',
|
||||
name: 'Testing',
|
||||
services: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
it('throws an error if API call in online mode returns an error', async () => {
|
||||
// Given
|
||||
StateDataSource.setOfflineMode(false);
|
||||
HomeHubCore.API.State.save.and.resolveTo({
|
||||
error: 'FIAL',
|
||||
});
|
||||
|
||||
// When
|
||||
let result = null;
|
||||
try {
|
||||
result = await StateDataSource.doSaveState(fakeState);
|
||||
} catch (error) {
|
||||
result = error;
|
||||
}
|
||||
|
||||
// Then
|
||||
expect(result).toEqual('FIAL');
|
||||
});
|
||||
|
||||
it('returns the result of the API call in online mode', async () => {
|
||||
// Given
|
||||
StateDataSource.setOfflineMode(false);
|
||||
HomeHubCore.API.State.save.and.resolveTo({
|
||||
data: true,
|
||||
});
|
||||
|
||||
// When
|
||||
const result = await StateDataSource.doSaveState(fakeState);
|
||||
|
||||
// Then
|
||||
expect(result).toBe(true);
|
||||
expect(HomeHubCore.API.State.save).toHaveBeenCalledWith(fakeState);
|
||||
expect(HomeHubCore.LocalStorage.setItem).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns the result of local storage save operation in offline mode', async () => {
|
||||
// Given
|
||||
StateDataSource.setOfflineMode(true);
|
||||
|
||||
// When
|
||||
const result = await StateDataSource.doSaveState(fakeState);
|
||||
|
||||
// Then
|
||||
expect(result).toBe(true);
|
||||
expect(HomeHubCore.API.State.save).not.toHaveBeenCalled();
|
||||
expect(HomeHubCore.LocalStorage.setItem).toHaveBeenCalledWith(
|
||||
'state', JSON.stringify(fakeState)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
101
packages/homehub_app/tests/main/views/AppView.spec.js
Normal file
101
packages/homehub_app/tests/main/views/AppView.spec.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import {DashboardsProvider} from '@bthlabs/homehub-core';
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {DashboardContainer, TaskbarContainer} from 'src/main/containers';
|
||||
import {StateDataSource} from 'src/main/dataSources';
|
||||
import * as AppView from 'src/main/views/AppView';
|
||||
|
||||
import {SettingsFactory} from 'tests/__fixtures__/settings';
|
||||
|
||||
describe('src/main/views/AppView', () => {
|
||||
describe('AppView', () => {
|
||||
let fakeActions = null;
|
||||
let fakeSetings = null;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeActions = {
|
||||
setDocumentTitle: jasmine.createSpy(),
|
||||
};
|
||||
fakeSetings = SettingsFactory();
|
||||
});
|
||||
|
||||
describe('componentDidMount', () => {
|
||||
it('calls the setDocumentTitle action', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AppView.AppView
|
||||
actions={fakeActions}
|
||||
settings={fakeSetings}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
component.instance().componentDidMount();
|
||||
|
||||
// Then
|
||||
expect(fakeActions.setDocumentTitle).toHaveBeenCalledWith(
|
||||
jasmine.any(String)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('render', () => {
|
||||
it('configures and renders the DashboardsProvider', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AppView.AppView
|
||||
actions={fakeActions}
|
||||
settings={fakeSetings}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const dashboardsProvider = component.find(DashboardsProvider).at(0);
|
||||
|
||||
// Then
|
||||
expect(dashboardsProvider.exists()).toBe(true);
|
||||
expect(dashboardsProvider.prop('loader')).toBeDefined();
|
||||
expect(dashboardsProvider.prop('loadDashboards')).toEqual(
|
||||
StateDataSource.loadState
|
||||
);
|
||||
expect(dashboardsProvider.prop('saveDashboards')).toEqual(
|
||||
StateDataSource.saveState
|
||||
);
|
||||
expect(dashboardsProvider.prop('settings')).toEqual(fakeSetings);
|
||||
});
|
||||
|
||||
it('configures and renders the DashboardContainer', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AppView.AppView
|
||||
actions={fakeActions}
|
||||
settings={fakeSetings}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const dashboardContainer = component.find(DashboardContainer).at(0);
|
||||
|
||||
// Then
|
||||
expect(dashboardContainer.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('configures and renders the TaskbarContainer', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<AppView.AppView
|
||||
actions={fakeActions}
|
||||
settings={fakeSetings}
|
||||
/>
|
||||
);
|
||||
|
||||
// When
|
||||
const taskbarContainer = component.find(TaskbarContainer).at(0);
|
||||
|
||||
// Then
|
||||
expect(taskbarContainer.exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,86 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import * as ErrorBoundaryView from 'src/main/views/ErrorBoundaryView';
|
||||
|
||||
describe('src/main/views/ErrorBoundaryView', () => {
|
||||
describe('ErrorBoundaryView', () => {
|
||||
let fakeError = null;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeError = new Error('FIAL');
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
it('initializes the state', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<ErrorBoundaryView.ErrorBoundaryView>
|
||||
<span>It works!</span>
|
||||
</ErrorBoundaryView.ErrorBoundaryView>
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(component.state('error')).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('componentDidCatch', () => {
|
||||
it('updates the state with error', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<ErrorBoundaryView.ErrorBoundaryView>
|
||||
<span>It works!</span>
|
||||
</ErrorBoundaryView.ErrorBoundaryView>
|
||||
);
|
||||
|
||||
// When
|
||||
component.instance().componentDidCatch(fakeError);
|
||||
|
||||
// Then
|
||||
expect(component.state('error')).toEqual(fakeError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('render', () => {
|
||||
let fakeChildren = null;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeChildren = <span>It works!</span>;
|
||||
});
|
||||
|
||||
it('renders the children when error is null', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<ErrorBoundaryView.ErrorBoundaryView>
|
||||
{fakeChildren}
|
||||
</ErrorBoundaryView.ErrorBoundaryView>
|
||||
);
|
||||
|
||||
// When
|
||||
component.setState({error: null});
|
||||
|
||||
// Then
|
||||
expect(component.contains(fakeChildren)).toBe(true);
|
||||
expect(component.contains('.ErrorBoundaryView')).toBe(false);
|
||||
});
|
||||
|
||||
it('renders the error view when error is not null', () => {
|
||||
// Given
|
||||
const component = shallow(
|
||||
<ErrorBoundaryView.ErrorBoundaryView>
|
||||
{fakeChildren}
|
||||
</ErrorBoundaryView.ErrorBoundaryView>
|
||||
);
|
||||
|
||||
// When
|
||||
component.setState({error: fakeError});
|
||||
|
||||
// Then
|
||||
expect(component.contains(fakeChildren)).toBe(false);
|
||||
expect(component.hasClass('ErrorBoundaryView')).toBe(true);
|
||||
expect(component.find('p').at(1).text()).toMatch(fakeError.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user