nexshop-web-contents
Version:
Nexshop Web Contents Project
373 lines (295 loc) • 13.6 kB
JavaScript
import React from 'react';
import {expect} from 'chai';
import {mount, shallow} from "enzyme";
import sinon from 'sinon';
import momentTimezone from 'moment-timezone';
import * as FileUtil from '../../../src/helpers/utility';
import * as ReactWrapper from '../../../src/wrapper/findDOMNodeWrapper';
import ContentsItemView from "../../../src/component/contents/contents-item-view";
describe('Contents Item View Spec', () => {
let contentsItem;
let playlistItem;
let thumbnailIsUndefind;
let wrapper;
let spyDelete;
let spyPreview;
let spyOnClick;
let spyOnDoubleClick;
let spyUpdateContentsItemAsync;
let spyOnContextMenu;
let spyUpdateContentsItemData;
let spySetSelectionRange;
beforeEach(() => {
contentsItem = {
id: 1,
name: 'first.file',
lastModifiedTimestamp: '2017-09-07T17:15:51.283Z',
type: 'image',
fileSizeBytes: 213674,
thumbnailUrls: {
thumbnail: 'first.thumbnail.file',
},
tags: [
{
id: 1,
name: 'tag name1'
},
{
id: 2,
name: 'tag name2'
}
]
};
playlistItem = {
id: 2,
name: 'first.file',
lastModifiedTimestamp: '2017-09-07T17:15:51.283Z',
type: 'playlist',
fileSizeBytes: 213674,
thumbnailUrls: {
thumbnail: 'first.thumbnail.file',
}
};
thumbnailIsUndefind = {
id: 3,
name: 'first.file',
lastModifiedTimestamp: '2017-09-07T17:15:51.283Z',
type: 'playlist',
fileSizeBytes: 213674,
thumbnailUrls: {
thumbnail: undefined,
}
};
momentTimezone.tz.setDefault('Asia/Seoul');
spyDelete = sinon.spy();
spyPreview = sinon.spy();
spyOnClick = sinon.spy();
spyOnDoubleClick = sinon.spy();
spyUpdateContentsItemAsync = sinon.spy();
spyOnContextMenu = sinon.spy();
spyUpdateContentsItemData = sinon.spy();
spySetSelectionRange = sinon.spy();
sinon.spy(FileUtil, "convertBytesToKilobytes");
sinon.stub(global, 'setTimeout');
wrapper = shallow(<ContentsItemView contentsItem={contentsItem} onDelete={spyDelete} onPreview={spyPreview}
onClick={spyOnClick} onDoubleClick={spyOnDoubleClick}
updateContentsItemAsync={spyUpdateContentsItemAsync}
onContextMenu={spyOnContextMenu}
updateContentsItemData={spyUpdateContentsItemData}
/>);
});
afterEach(() => {
FileUtil.convertBytesToKilobytes.restore();
global.setTimeout.restore();
momentTimezone.tz.setDefault();
spySetSelectionRange.reset();
});
describe('Component Will Unmount', () => {
it('does not called clearTimeout when timeOutID is undefined', () => {
const spyClearTimeout = sinon.spy(global, 'clearTimeout');
wrapper.instance().componentWillUnmount();
expect(spyClearTimeout.called).to.false;
global.clearTimeout.restore();
});
});
describe('Component Updated', () => {
let timeout;
let instance;
let stubQuerySelector;
beforeEach(() => {
stubQuerySelector = sinon.stub().returns('something hover');
sinon.stub(ReactWrapper, 'findDOMNode').returns({
querySelector: stubQuerySelector
});
instance = wrapper.instance();
instance.componentDidUpdate();
timeout = global.setTimeout.lastCall.args[0];
timeout();
});
afterEach(() => {
ReactWrapper.findDOMNode.restore();
});
it('sets timeout for 50 milliseconds', () => {
expect(global.setTimeout.calledWith(sinon.match.func, 50)).to.be.true;
});
it("finds it's dom node", () => {
expect(ReactWrapper.findDOMNode.calledWith(wrapper.instance())).to.be.true;
});
it('queries :hover node', () => {
expect(stubQuerySelector.calledWith(":hover")).to.be.true;
});
it('does not set isHover when it is not :hover', () => {
stubQuerySelector.returns(undefined);
wrapper.setState({isHover: false});
timeout();
expect(instance.state.isHover).to.be.false;
});
it('does not set isHover when it is not :hover', () => {
stubQuerySelector.returns(undefined);
wrapper.setState({isHover: false});
timeout();
expect(instance.state.isHover).to.be.false;
});
});
it('has contents-item class', () => {
expect(wrapper.find('.contents-item').length).to.equal(1);
});
it('has --selected modifier if status field is "new"', () => {
wrapper.setProps({
selectedContentsItemIds: [1]
});
expect(wrapper.find('.contents-item--selected').length).to.equal(1);
});
it('first column has thumbnail url', () => {
expect(wrapper.find('.contents-item__thumbnail').getNode().props.style.backgroundImage).to.equal('url(first.thumbnail.file)');
});
it('first column has black image when thumbnail is not extist', () => {
wrapper.setProps({
contentsItem: Object.assign({}, thumbnailIsUndefind, {status: 'selected'})
});
expect(wrapper.find('.contents-item__thumbnail').getNode().props.style.backgroundColor).to.equal('black');
});
it('second column has file name', () => {
expect(wrapper.find('.contents-item__name').text()).to.equal('first.file');
});
it('second column has file type icon', () => {
expect(wrapper.find('.contents-item__type--image').length).to.equal(1);
wrapper.setProps({contentsItem: Object.assign({}, contentsItem, {type: 'video'})});
expect(wrapper.find('.contents-item__type--video').length).to.equal(1);
});
it('6th column has shows "YYYY.MM.DD" formatted time according to timezone"', () => {
expect(wrapper.find('td').at(5).text()).to.equal('09-08-2017');
momentTimezone.tz.setDefault('Europe/London');
wrapper = shallow(<ContentsItemView contentsItem={contentsItem}/>);
expect(wrapper.find('td').at(5).text()).to.equal('09-07-2017');
});
it('7th column shows file size throught fileSizeHelper', () => {
expect(FileUtil.convertBytesToKilobytes.calledWith(213674)).to.be.true;
});
it('7th column has file size', () => {
expect(wrapper.find('td').at(6).text()).to.equal('208.7KB');
});
it('calls onPreview when preview is clicked', () => {
wrapper.setState({isHover: true});
wrapper.find('.contents-item-preview').simulate('click');
expect(spyPreview.called).to.be.true;
});
it('calls onClick when component is clicked', () => {
wrapper.find('.contents-item').simulate('click');
expect(spyOnClick.called).to.true;
});
it('calls onDoubleClick when component is double clicked', () => {
wrapper.find('.contents-item').simulate('doubleClick');
expect(spyOnDoubleClick.called).to.true;
});
it('highlight search keyword on name', () => {
expect(wrapper.find('.contents-item__name-highlight')).to.be.lengthOf(0);
wrapper.setProps({searchKeyword: 'first'});
expect(wrapper.find('.contents-item__name-highlight')).to.be.lengthOf(1);
});
describe('click trash can', () => {
beforeEach(() => {
wrapper.find(".contents-item").at(0).simulate('click');
wrapper.find('.contents-item__trash-can').simulate('click');
});
it('calls onDeleteItem with index', () => {
expect(spyDelete.called).to.be.true;
});
});
describe('input key & blur event', () => {
const newContentsItem = Object.freeze({
id: "someContentsItemId",
name: "someContentsItemName.jpg",
status: "new",
lastModifiedTimestamp: '2017-09-07T17:15:51.283Z',
type: 'image',
fileSizeBytes: 213674,
thumbnailUrls: {
thumbnail: 'first.thumbnail.file',
},
tags: [
{
id: 1,
name: 'tag name'
},
{
id: 2,
name: 'tag name'
}
]
});
beforeEach(() => {
//TODO: Please remove warning.
wrapper = mount(
<ContentsItemView contentsItem={newContentsItem} onDelete={spyDelete} onPreview={spyPreview}
onClick={spyOnClick} onDoubleClick={spyOnDoubleClick}
updateContentsItemAsync={spyUpdateContentsItemAsync}
onContextMenu={spyOnContextMenu} updateContentsItemData={spyUpdateContentsItemData}
/>
);
wrapper.instance().titleInput.setSelectionRange = spySetSelectionRange;
wrapper.instance().titleInput.value = 'new contents item name';
});
it('focus out when esc key down', () => {
expect(document.activeElement.classList.contains('contents-item__name--new')).to.be.true;
wrapper.find('.contents-item__name--new').simulate('keyup', {key: 'Escape'});
expect(document.activeElement.classList.contains('contents-item__name--new')).to.be.false;
});
it('focus out when esc key down', () => {
expect(document.activeElement.classList.contains('contents-item__name--new')).to.be.true;
wrapper.find('.contents-item__name--new').simulate('keyup', {key: 'Enter'});
expect(document.activeElement.classList.contains('contents-item__name--new')).to.be.false;
});
it('titleInput is focused and setSelectionRange is called when componentDidMount call', () => {
const focusTitleInputAndSelect = sinon.spy(wrapper.instance(), 'focusTitleInputAndSelect');
wrapper.instance().componentDidMount();
expect(document.activeElement.classList.contains('contents-item__name--new')).to.be.true;
expect(focusTitleInputAndSelect.called).to.true;
});
it('titleInput is focused and setSelectionRange is called when componentDidUpdate call', () => {
const focusTitleInputAndSelect = sinon.spy(wrapper.instance(), 'focusTitleInputAndSelect');
wrapper.instance().componentDidUpdate();
expect(document.activeElement.classList.contains('contents-item__name--new')).to.be.true;
expect(focusTitleInputAndSelect.called).to.true;
});
it('when focusTitleInputAndSelect then call setSelectionRange and set input value is "new contents item name"', () => {
wrapper.instance().focusTitleInputAndSelect();
expect(wrapper.instance().titleInput.value).to.equal('someContentsItemName.jpg');
expect(spySetSelectionRange.calledWith(0, 'someContentsItemName'.length)).to.true;
});
it('titleInput is not blured when keyup except in Escape or Enter key', () => {
expect(document.activeElement.classList.contains('contents-item__name--new')).to.be.true;
wrapper.find('.contents-item__name--new').simulate('keyup', {key: 'Space'});
expect(document.activeElement.classList.contains('contents-item__name--new')).to.be.true;
});
describe('contentsItemNameInputBlurred method test', () => {
it('call updateContentsItemAsync with contents item name when focus is out', () => {
wrapper.find('.contents-item__name--new').simulate('blur');
expect(spyUpdateContentsItemAsync.calledWith(newContentsItem, 'new contents item name')).to.be.true;
});
it('when input value and contents name is same', () => {
wrapper.instance().titleInput.value = 'someContentsItemName.jpg';
wrapper.find('.contents-item__name--new').simulate('blur');
expect(spyUpdateContentsItemData.called).to.true;
});
it('call getContentsItem with error state', () => {
expect(wrapper.instance().getContentsItem({status: 'error'}).status).to.equal('new');
expect(wrapper.instance().getContentsItem({status: 'new'})).to.not.have.property('status');
});
});
});
describe('render', () => {
it('selected background not exists when contentsItem is not selected', () => {
expect(wrapper.find('.contents-item--selected')).to.be.lengthOf(0);
});
it('show selected background when folder is selected', () => {
wrapper.setProps({
selectedContentsItemIds: [1]
});
expect(wrapper.find('.contents-item--selected')).to.be.lengthOf(1);
});
it('show tags info when content has some tags', () => {
expect(wrapper.find('.contents-item__tag').text()).to.equal('tag name1, tag name2');
});
});
});