UNPKG

nexshop-web-contents

Version:

Nexshop Web Contents Project

459 lines (355 loc) 20.7 kB
import React from 'react'; import {expect} from 'chai'; import {mount, shallow} from "enzyme"; import sinon from "sinon"; import {DropDown} from 'nexshop-web-elements'; import PlaylistEditorView from "../../../../src/component/playlist/playlist-editor/playlist-editor-view"; import * as TimeHelper from '../../../../src/helpers/time-helper'; import * as StringHelper from '../../../../src/helpers/string-helper'; import * as FindDOMNodeWrapper from '../../../../src/wrapper/findDOMNodeWrapper'; import {contentItemModel} from "nexshop-web-store"; describe('Playlist Editor View Spec', () => { let wrapper; let resolution; let contentItems; let spyOnDropDragContentsItem; let spyOnDeleteItem; let spyOnOrderChangeStart; let spyOnOrderChangeProcess; let spyOnOrderChangeEnd; let spyOnSelectPreviewItem; let spyOnUpdateContentItemTransition; let spyOnUpdateContentItemDuration; let spyOnUpdateContentItemFitMode; const imageContentItem = contentItemModel.createContentItem({ id: 1, name: 'media1', type: 'image', thumbnailUrls: { thumbnail: 'first.thumbnail.file', } }, undefined, undefined, 'cover'); const videoContentItem = contentItemModel.createContentItem({ id: 2, name: 'media2', type: 'video', thumbnailUrls: { thumbnail: 'second.thumbnail.file', }, durationSeconds: 52, }, 52); beforeEach(() => { resolution = { value: 'QHD', orientation: 'horizontal' }; contentItems = [imageContentItem, videoContentItem]; sinon.stub(FindDOMNodeWrapper, 'findDOMNode'); sinon.stub(global, 'setTimeout'); sinon.spy(TimeHelper, 'formatSeconds'); sinon.spy(StringHelper, 'leftPadZero'); spyOnDropDragContentsItem = sinon.spy(); spyOnDeleteItem = sinon.spy(); spyOnOrderChangeStart = sinon.spy(); spyOnOrderChangeProcess = sinon.spy(); spyOnOrderChangeEnd = sinon.spy(); spyOnSelectPreviewItem = sinon.spy(); spyOnUpdateContentItemTransition = sinon.spy(); spyOnUpdateContentItemDuration = sinon.spy(); spyOnUpdateContentItemFitMode = sinon.spy(); wrapper = shallow(<PlaylistEditorView resolution={resolution} contentItems={contentItems} onDropDragContentsItem={spyOnDropDragContentsItem} onDeleteItem={spyOnDeleteItem} onOrderChangeStart={spyOnOrderChangeStart} onOrderChangeProcess={spyOnOrderChangeProcess} onOrderChangeEnd={spyOnOrderChangeEnd} blankIndex={-1} onSelectPreviewItem={spyOnSelectPreviewItem} onUpdateContentItemTransition={spyOnUpdateContentItemTransition} onUpdateContentItemDuration={spyOnUpdateContentItemDuration} onUpdateContentItemFitMode={spyOnUpdateContentItemFitMode} />); }); afterEach(() => { TimeHelper.formatSeconds.restore(); StringHelper.leftPadZero.restore(); FindDOMNodeWrapper.findDOMNode.restore(); global.setTimeout.restore(); }); describe('rendering', () => { describe('top area', () => { it('has value of resolution with given by "createPlaylist"', () => { expect(wrapper.find('.playlist-resolution__value').text()).to.equal('QHD'); }); it('has "playlist-resolution__horizontal" className when resolution.orientation of props is horizontal', () => { expect(wrapper.find('.playlist-resolution__horizontal').length).to.equal(1); }); it('has "playlist-resolution__vertical" className when resolution.orientation of props is vertical', () => { wrapper.setProps({resolution: {orientation: 'vertical'}}); expect(wrapper.find('.playlist-resolution__vertical').length).to.equal(1); }); it('has total count', () => { expect(StringHelper.leftPadZero.calledWith(2)).to.be.true; expect(wrapper.find('.playlist-summary__value').at(0).text()).to.equal('02'); }); it('has total duration', () => { expect(TimeHelper.formatSeconds.calledWith(82, 'hh:mm:ss')).to.be.true; expect(wrapper.find('.playlist-summary__value').at(1).text()).to.equal('00:01:22'); }); }); describe('playlist item is empty', () => { it('has playlist-item__delete', () => { wrapper.setProps({contentItems: []}); expect(wrapper.find('.playlist-item-drag-placeholder').length).to.equal(1); }); }); describe('playlist items', () => { it('has "playlist-items"', () => { expect(wrapper.find('.playlist-items').length).to.equals(1); }); it('has "playlist-list" className', () => { expect(wrapper.find('.playlist-items').find('.playlist-item').length).to.equal(2); }); it('first column has thumbnail url', () => { expect(wrapper.find('.playlist-item__thumbnail').at(0).getNode().props.style.backgroundImage) .to.equal('url(first.thumbnail.file)'); expect(wrapper.find('.playlist-item__thumbnail').at(1).getNode().props.style.backgroundImage) .to.equal('url(second.thumbnail.file)'); }); it('second column has contents type', () => { expect(wrapper.find('.playlist-item').at(0).find('.playlist-item__type--image').length).to.equal(1); expect(wrapper.find('.playlist-item').at(1).find('.playlist-item__type--video').length).to.equal(1); }); it('third column has name', () => { expect(wrapper.find('.playlist-item__name').at(0).text()).to.equal('media1'); expect(wrapper.find('.playlist-item__name').at(1).text()).to.equal('media2'); }); it('4th column has drop down for duration', () => { const imageItemDuration = wrapper.find('.playlist-item__duration'); const videoItemDuration = wrapper.find('.playlist-item__duration__video'); expect(TimeHelper.formatSeconds.calledWith(52, 'mm:ss')).to.be.true; expect(imageItemDuration.find(DropDown).prop('selected')).to.deep.equal({value: 30, text: '00:30'}); expect(videoItemDuration.text()).to.equal("00:52"); }); it('4th column formats hh:mm:ss when duration is more than 1 hour', () => { wrapper.setProps({contentItems: [imageContentItem, Object.assign({}, videoContentItem, {durationSeconds: 3601})]}); expect(TimeHelper.formatSeconds.calledWith(3601, 'hh:mm:ss')).to.be.true; }); it('5th column has drop down for effect', () => { expect(wrapper.find('.playlist-item__effect').length).to.equal(contentItems.length); const effectItems = wrapper.find('.playlist-item__effect'); expect(effectItems.at(0).find(DropDown).prop('selected')).to.deep.equal({ value: 'none', text: 'No Effect' }); expect(effectItems.at(1).text()).to.equal("No Effect"); }); it('6th column has fitMode drop down', () => { expect(wrapper.find('.playlist-item__fitMode').exists()).to.true; expect(wrapper.find('.playlist-item__fitMode').find(DropDown).at(0).prop('selected')) .to.deep.equal({value: 'cover', text: 'Crop to fit', icon: 'crop-to-fit'}); expect(wrapper.find('.playlist-item__fitMode').find(DropDown).at(1).prop('selected')) .to.deep.equal({value: 'contain', text: 'Fit to screen', icon: 'fit-to-screen'}); }); it('draws placeholder at blank index', () => { wrapper.setProps({blankIndex: 1}); expect(wrapper.find('.playlist-items').childAt(1)).to.deep.equal(wrapper.find('.playlist-placeholder')); }); it('passes transition change listener with uuid', () => { expect(wrapper.find('.playlist-item__effect').at(0).find(DropDown).prop('onSelect').toString()) .to.equal(wrapper.instance().onTransitionEffectChange(imageContentItem.uuid).toString()); }); describe('Dragging Content', () => { let draggingContentItem; beforeEach(() => { expect(wrapper.find('.playlist-item-shadow').length).to.equal(0); wrapper.setState({draggingContentItem: imageContentItem}); draggingContentItem = wrapper.find('DraggingContentItem').dive(); }); it('draws dragging content item', () => { expect(draggingContentItem.length).to.equal(1); }); it('has background as thumbnail image', () => { const thumbnailNode = draggingContentItem.find('.playlist-item__thumbnail').getNode(); expect(thumbnailNode.props.style.backgroundImage).to.equal(`url(${imageContentItem.contents.thumbnailUrls.thumbnail})`); }); it('has class according to contentsItem type', () => { expect(draggingContentItem.find(`.playlist-item__type--${imageContentItem.contents.type}`)).to.exist; }); it('has contentsItem name', () => { expect(draggingContentItem.find('.playlist-item__name').text()).to.equal(imageContentItem.contents.name); }); it('has duration seconds', () => { expect(draggingContentItem.find('.playlist-item__duration').text()).to.equal('00:30'); }); it('has effect name', () => { expect(draggingContentItem.find('.playlist-item__effect').text()).to.equal('No Effect'); }); }); describe('Mouse Over & Click', () => { const firstItemIndex = 0; beforeEach(() => { wrapper.find('.playlist-item').at(firstItemIndex).simulate('mouseover'); }); it('sets mouseOverUUID state', () => { expect(wrapper.state('mouseOverUUID')).to.equal(imageContentItem.uuid); }); it('does not change mouseOverUUID when something is dragging', () => { wrapper.setState({isDragging: true, mouseOverUUID: ''}); wrapper.find('.playlist-item').at(firstItemIndex).simulate('mouseover'); expect(wrapper.state('mouseOverUUID')).to.equal(''); }); it('shows X button and hide when mouse leaves', () => { expect(wrapper.find('.playlist-item--hovered').find('.playlist-item__delete').length).to.equal(1); wrapper.find('.playlist-item-item--hovered').at(firstItemIndex).simulate('mouseleave'); expect(wrapper.find('.playlist-item').at(firstItemIndex).find('.playlist-item__delete').length).to.equal(0); }); it('calls props.onDelete with mouse entered item index', () => { wrapper.find('.playlist-item__delete').simulate('click'); expect(wrapper.instance().props.onDeleteItem.calledWith(firstItemIndex)).to.be.true; }); it('appears play icon on thumbnail', () => { expect(wrapper.find('.playlist-item-preview__play').length).to.equal(1); }); it('disappears play icon from thumbnail', () => { wrapper.find('.playlist-item').at(firstItemIndex).simulate('mouseleave'); expect(wrapper.find('.playlist-item__play').length).to.equal(0); }); it('has link div to move preview', () => { expect(wrapper.find('.playlist-item-preview-link').length).to.equal(1); }); it('calls onSelectPreviewItem when click play icon', () => { wrapper.find('.playlist-item-preview').simulate('click'); expect(spyOnSelectPreviewItem.calledWith(firstItemIndex)).to.be.true; }); }); describe('Delete Item', () => { const mouseOverIndex = 0; let timeout; beforeEach(() => { wrapper.find('.playlist-item').at(mouseOverIndex).simulate('mouseover'); wrapper.find('.playlist-item__delete').simulate('click'); timeout = global.setTimeout.lastCall.args[0]; }); it('calls onDeleteItem with index', () => { expect(spyOnDeleteItem.calledWith(mouseOverIndex)).to.be.true; }); it('sets timeout for async process', () => { expect(global.setTimeout.calledWith(sinon.match.func, 0)).to.be.true; }); it('replaces mouseOverUUID with playlist[index] after render is done', () => { wrapper.setProps({contentItems: [videoContentItem]}); timeout(); expect(wrapper.state('mouseOverUUID')).to.equal(videoContentItem.uuid); }); it('replaces mouseOverUUID with empty string when index >= playlist.length', () => { wrapper.setProps({contentItems: []}); timeout(); expect(wrapper.state('mouseOverUUID')).to.equal(''); }); }); describe('Mouse Drag Start & End', () => { let spySetDragImage; beforeEach(() => { wrapper = mount(<PlaylistEditorView resolution={resolution} contentItems={contentItems} onDropDragContentsItem={spyOnDropDragContentsItem} onDeleteItem={spyOnDeleteItem} onOrderChangeStart={spyOnOrderChangeStart} onOrderChangeProcess={spyOnOrderChangeProcess} onOrderChangeEnd={spyOnOrderChangeEnd} onSelectPreviewItem={spyOnSelectPreviewItem} onUpdateContentItemTransition={spyOnUpdateContentItemTransition} onUpdateContentItemDuration={spyOnUpdateContentItemDuration} onUpdateContentItemFitMode={spyOnUpdateContentItemFitMode} />); spySetDragImage = sinon.spy(); }); describe('Start', () => { beforeEach(() => { wrapper.find('.playlist-item').at(0).simulate('dragstart', {dataTransfer: {setDragImage: spySetDragImage}}); }); it('sets isDragging state as true', () => { expect(wrapper.state('isDragging')).to.be.true; }); it('sets draggingContentItem state with content at the index', () => { expect(wrapper.state('draggingContentItem')).to.deep.equal(imageContentItem); }); it('sets drag image with dragging element', () => { expect(spySetDragImage.calledWith(wrapper.find('.dragging').getNode())).to.be.true; }); it('calls props.onOrderChangeStart with selected index', () => { expect(spyOnOrderChangeStart.calledWith(0)).to.be.true; wrapper.find('.playlist-item').at(1).simulate('dragstart', {dataTransfer: {setDragImage: spySetDragImage}}); expect(spyOnOrderChangeStart.calledWith(1)).to.be.true; }); }); describe('End', () => { it('sets isDragging state as false', () => { wrapper.setState({isDragging: true}); wrapper.find('.playlist-item').at(0).simulate('dragend', {dataTransfer: {setDragImage: spySetDragImage}}); expect(wrapper.state('isDragging')).to.be.false; }); it('sets undefined for draggingContentItem state', () => { expect(wrapper.state('draggingContentItem')).to.be.null; }); it('calls props.onOrderChangeEnd', () => { wrapper.find('.playlist-item').at(0).simulate('dragend', {dataTransfer: {setDragImage: spySetDragImage}}); expect(spyOnOrderChangeEnd.called).to.be.true; }); }); }); describe('Mouse Drag Over', () => { let spyPreventDefault; let mockDragOver; beforeEach(() => { spyPreventDefault = sinon.spy(); mockDragOver = {preventDefault: spyPreventDefault}; wrapper.find('.playlist-item').at(0).simulate('dragover', mockDragOver); }); it('calls props.onOrderChangeProcess with selected index', () => { expect(spyOnOrderChangeProcess.calledWith(0)).to.be.true; wrapper.find('.playlist-item').at(1).simulate('dragover', mockDragOver); expect(spyOnOrderChangeProcess.calledWith(1)).to.be.true; }); it('prevents default event', () => { expect(spyPreventDefault.called).to.be.true; }); }); describe('Mouse Drag Drop', () => { it('calls props.onOrderChangeProcess with selected index', () => { wrapper.setProps({blankIndex: 1}); wrapper.find('.playlist-placeholder').simulate('drop', {}); expect(spyOnOrderChangeEnd.called).to.be.true; }); }); }); }); describe('drag event', () => { it('calls props.onDropDragContentsItem when onDragDrop is called', () => { wrapper.find('.playlist-editor-wrapper').simulate('drop'); expect(spyOnDropDragContentsItem.called).to.be.true; }); it('calls event.preventDefault when preventDefault is called', () => { let spyPreventDefault = sinon.spy(); let mockEvent = { preventDefault: spyPreventDefault }; wrapper.find('.playlist-editor-wrapper').simulate('dragover', mockEvent); expect(spyPreventDefault.called).to.be.true; }); }); it('onTransitionEffectChange calls onUpdateContentItemTransition with uuid, value', () => { wrapper.instance().onTransitionEffectChange('some uuid')({value: 'i am valuable'}); expect(spyOnUpdateContentItemTransition.calledWith('some uuid', 'i am valuable')).to.be.true; }); it('onDurationChange calls onUpdateContentItemDuration with uuid, value', () => { wrapper.instance().onDurationChange('some uuid')({value: 'i am valuable'}); expect(spyOnUpdateContentItemDuration.calledWith('some uuid', 'i am valuable')).to.be.true; }); it('onFitModeChange calls onUpdateContentItemFitMode with uuid, value', () => { wrapper.instance().onFitModeChange('some uuid')({value: 'i am valuable'}); expect(spyOnUpdateContentItemFitMode.calledWith('some uuid', 'i am valuable')).to.be.true; }); });