diff --git a/docs/components.json b/docs/components.json index 7cb6ad9b..f3a9623a 100644 --- a/docs/components.json +++ b/docs/components.json @@ -1425,7 +1425,7 @@ } } }, - "components/emoji-filter/index.jsx": { + "components/emoji-filter/component.jsx": { "description": "Used for displaying a list of commands", "displayName": "EmojiFilter", "methods": [ diff --git a/src/emoji-filter/index.jsx b/src/emoji-filter/component.jsx similarity index 96% rename from src/emoji-filter/index.jsx rename to src/emoji-filter/component.jsx index ea1347e6..4c15d2a9 100644 --- a/src/emoji-filter/index.jsx +++ b/src/emoji-filter/component.jsx @@ -1,9 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import Radium from 'radium'; -import compose from 'recompose/compose'; import _ from 'lodash'; -import onClickOutside from 'react-onclickoutside'; import emojione from 'emojione'; import htmlParser from 'html-react-parser'; import EventListener from 'react-event-listener'; @@ -11,7 +8,6 @@ import getStyles from './get-styles'; import styles from './styles'; import emoji from '../emoji-menu/emoji'; import EmojiModifiers from '../emoji-menu/emoji-modifiers'; -import themeable from '../themeable'; const propTypes = { /** Filter emoji based on input value */ @@ -284,10 +280,4 @@ EmojiFilter.displayName = 'EmojiFilter'; EmojiFilter.propTypes = propTypes; EmojiFilter.defaultProps = defaultProps; -const enhance = compose( - themeable(), - onClickOutside, - Radium -); - -export default enhance(EmojiFilter); +export default EmojiFilter; diff --git a/src/emoji-filter/get-styles.js b/src/emoji-filter/get-styles.js index 2f156a40..94336923 100644 --- a/src/emoji-filter/get-styles.js +++ b/src/emoji-filter/get-styles.js @@ -5,6 +5,7 @@ import colors from '../settings/colors'; const root = overrideStyle => combineStyles(styles.root, overrideStyle); const header = overrideStyle => combineStyles(styles.header, overrideStyle); const commands = overrideStyle => combineStyles(styles.commands, overrideStyle); + const emoji = (color = colors.theme, selected) => { let style = styles.emoji; @@ -14,6 +15,7 @@ const emoji = (color = colors.theme, selected) => { return style; }; + const title = overrideStyle => combineStyles(styles.title, overrideStyle); const description = overrideStyle => combineStyles(styles.description, overrideStyle); diff --git a/src/emoji-filter/index.js b/src/emoji-filter/index.js new file mode 100644 index 00000000..46ebecbd --- /dev/null +++ b/src/emoji-filter/index.js @@ -0,0 +1,13 @@ +import Radium from 'radium'; +import compose from 'recompose/compose'; +import onClickOutside from 'react-onclickoutside'; +import themeable from '../themeable'; +import EmojiFilter from './component'; + +const enhance = compose( + themeable(), + onClickOutside, + Radium +); + +export default enhance(EmojiFilter); diff --git a/test/emoji-filter/get-styles.test.js b/test/emoji-filter/get-styles.test.js new file mode 100644 index 00000000..8cf45dc2 --- /dev/null +++ b/test/emoji-filter/get-styles.test.js @@ -0,0 +1,98 @@ +/* eslint-env mocha */ +import { expect } from 'chai'; +import getStyles from '../../src/emoji-filter/get-styles'; +import styles from '../../src/emoji-filter/styles'; + +describe('EmojiFilter.getStyles', () => { + describe('root', () => { + it('should get styles', () => { + const style = getStyles.root(); + + expect(style).to.deep.equal(styles.root); + }); + + it('should combine styles', () => { + const style = getStyles.root({ color: 'red' }); + + expect(style).to.have.property('color', 'red'); + }); + }); + + describe('header', () => { + it('should get styles', () => { + const style = getStyles.header(); + + expect(style).to.deep.equal(styles.header); + }); + + it('should combine styles', () => { + const style = getStyles.header({ color: 'red' }); + + expect(style).to.have.property('color', 'red'); + }); + }); + + describe('commands', () => { + it('should get styles', () => { + const style = getStyles.commands(); + + expect(style).to.deep.equal(styles.commands); + }); + + it('should combine styles', () => { + const style = getStyles.commands({ color: 'red' }); + + expect(style).to.have.property('color', 'red'); + }); + }); + + describe('emoji', () => { + it('should get styles', () => { + const style = getStyles.emoji(); + + expect(style).to.deep.equal(styles.emoji); + }); + + it('should add selected styles', () => { + const style = getStyles.emoji(undefined, true); + + expect(style).to.have.property('backgroundColor', '#1BA6C4'); + expect(style).to.have.property('color', '#FEFEFE'); + }); + + it('should add theme color', () => { + const style = getStyles.emoji('HotPink', true); + + expect(style).to.have.property('backgroundColor', 'HotPink'); + expect(style).to.have.property('color', '#FEFEFE'); + }); + }); + + describe('title', () => { + it('should get styles', () => { + const style = getStyles.title(); + + expect(style).to.deep.equal(styles.title); + }); + + it('should combine styles', () => { + const style = getStyles.title({ color: 'red' }); + + expect(style).to.have.property('color', 'red'); + }); + }); + + describe('description', () => { + it('should get styles', () => { + const style = getStyles.description(); + + expect(style).to.deep.equal(styles.description); + }); + + it('should combine styles', () => { + const style = getStyles.description({ color: 'red' }); + + expect(style).to.have.property('color', 'red'); + }); + }); +}); diff --git a/test/emoji-filter/index.test.js b/test/emoji-filter/index.test.js new file mode 100644 index 00000000..24155b6b --- /dev/null +++ b/test/emoji-filter/index.test.js @@ -0,0 +1,105 @@ +/* eslint-env mocha */ +/* eslint react/jsx-filename-extension: [0] */ +import React from 'react'; +import chai, { expect } from 'chai'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import sinonChai from 'sinon-chai'; +import EventListener from 'react-event-listener'; +import EmojiFilter from '../../src/emoji-filter/component'; +import EmojiModifiers from '../../src/emoji-menu/emoji-modifiers'; +import getStyles from '../../src/emoji-filter/get-styles'; + +chai.use(sinonChai); + +describe('EmojiFilter', () => { + const props = { + value: '', + style: {}, + headerStyle: {}, + onSelect: () => {}, + onChange: () => {}, + color: '#1BA6C4' + }; + + beforeEach(() => { + global.navigator = { userAgent: 'all' }; + }); + + afterEach(() => { + global.navigator = undefined; + }); + + it('should render root elements', () => { + const component = shallow(); + + expect(component.find('section')).to.have.length(0); + expect(component.find(EmojiModifiers)).to.have.length(0); + expect(component.find(EventListener)).to.have.length(0); + + component.setState({ open: true }); + expect(component.find('section')).to.have.length(2); + expect(component.find(EmojiModifiers)).to.have.length(1); + expect(component.find(EventListener)).to.have.length(1); + }); + + it('should render emoji elements', () => { + const emoji = [ + { shortname: ':poop:' }, + { shortname: ':poodle:' } + ]; + const component = shallow(); + + component.setState({ open: true, emoji }); + expect(component.find('section > div')).to.have.length(2); + expect(component.find('section > div > img')).to.have.length(2); + }); + + it('should call onSelect', () => { + const emoji = [ + { shortname: ':poop:' } + ]; + const spy = sinon.spy(); + const component = shallow(); + + component.setProps({ onSelect: spy }); + component.setState({ open: true, emoji }); + component.find('section > div').simulate('click'); + expect(spy).to.have.callCount(1); + }); + + it('should get root styles', () => { + const spy = sinon.spy(getStyles, 'root'); + const component = shallow(); + + component.setState({ open: true }); + expect(spy).to.have.been.calledWith(props.style); + }); + + it('should get header styles', () => { + const spy = sinon.spy(getStyles, 'header'); + const component = shallow(); + + component.setState({ open: true }); + expect(spy).to.have.been.calledWith(props.headerStyle); + }); + + it('should get commands styles', () => { + const spy = sinon.spy(getStyles, 'commands'); + const component = shallow(); + + component.setState({ open: true }); + expect(spy).to.have.callCount(1); + }); + + it('should get emoji styles', () => { + const spy = sinon.spy(getStyles, 'emoji'); + const emoji = [ + { shortname: ':poop:' } + ]; + const component = shallow(); + + component.setState({ open: true, emoji }); + expect(spy).to.have.been.calledWith(props.color, false); + }); +});