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); }); }); });