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 as read-only', () => {
// Given
fakeSettings.READ_ONLY = true;
// When
const component = shallow(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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(
);
// 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);
});
});
});