From 39ea5c0e2e9bdf2c6e3bd0797e6fb422e6117aa2 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Fri, 2 Jun 2017 00:27:15 +0900 Subject: Improve tests for JavaScript (#3496) - Upgrade dependencies - chai (3.5.0 -> 4.0.1) - chai-enzyme (0.6.1 -> 0.7.1) - sinon (2.2.0 -> 2.3.2) - Change extensions from .jsx to .js - Don't assign `React` to `global` - Check code format using ESLint --- spec/javascript/components/dropdown_menu.test.js | 97 ++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 spec/javascript/components/dropdown_menu.test.js (limited to 'spec/javascript/components/dropdown_menu.test.js') diff --git a/spec/javascript/components/dropdown_menu.test.js b/spec/javascript/components/dropdown_menu.test.js new file mode 100644 index 000000000..54cdcabf0 --- /dev/null +++ b/spec/javascript/components/dropdown_menu.test.js @@ -0,0 +1,97 @@ +import { expect } from 'chai'; +import { shallow, mount } from 'enzyme'; +import sinon from 'sinon'; +import React from 'react'; +import DropdownMenu from '../../../app/javascript/mastodon/components/dropdown_menu'; +import Dropdown, { DropdownTrigger, DropdownContent } from 'react-simple-dropdown'; + +describe('', () => { + const icon = 'my-icon'; + const size = 123; + const action = sinon.spy(); + + const items = [ + { text: 'first item', action: action, href: '/some/url' }, + { text: 'second item', action: 'noop' }, + ]; + const wrapper = shallow(); + + it('contains one ', () => { + expect(wrapper).to.have.exactly(1).descendants(Dropdown); + }); + + it('contains one ', () => { + expect(wrapper.find(Dropdown)).to.have.exactly(1).descendants(DropdownTrigger); + }); + + it('contains one ', () => { + expect(wrapper.find(Dropdown)).to.have.exactly(1).descendants(DropdownContent); + }); + + it('uses props.size for style values', () => { + ['font-size', 'width', 'line-height'].map((property) => { + expect(wrapper.find(DropdownTrigger)).to.have.style(property, `${size}px`); + }); + }); + + it('uses props.icon as icon class name', () => { + expect(wrapper.find(DropdownTrigger).find('i')).to.have.className(`fa-${icon}`); + }); + + it('is not expanded by default', () => { + expect(wrapper.state('expanded')).to.be.equal(false); + }); + + it('does not render the list elements if not expanded', () => { + const lis = wrapper.find(DropdownContent).find('li'); + expect(lis.length).to.be.equal(0); + }); + + it('sets expanded to true when clicking the trigger', () => { + const wrapper = mount(); + wrapper.find(DropdownTrigger).first().simulate('click'); + expect(wrapper.state('expanded')).to.be.equal(true); + }); + + // Error: ReactWrapper::state() can only be called on the root + /*it('sets expanded to false when clicking outside', () => { + const wrapper = mount(( +
+ + +
+ )); + + wrapper.find(DropdownTrigger).first().simulate('click'); + expect(wrapper.find(DropdownMenu).first().state('expanded')).to.be.equal(true); + + wrapper.find('span').first().simulate('click'); + expect(wrapper.find(DropdownMenu).first().state('expanded')).to.be.equal(false); + })*/ + + it('renders list elements for each props.items if expanded', () => { + const wrapper = mount(); + wrapper.find(DropdownTrigger).first().simulate('click'); + const lis = wrapper.find(DropdownContent).find('li'); + expect(lis.length).to.be.equal(items.length); + }); + + it('uses the href passed in via props.items', () => { + wrapper + .find(DropdownContent).find('li a') + .forEach((a, i) => expect(a).to.have.attr('href', items[i].href)); + }); + + it('uses the text passed in via props.items', () => { + wrapper + .find(DropdownContent).find('li a') + .forEach((a, i) => expect(a).to.have.text(items[i].text)); + }); + + it('uses the action passed in via props.items as click handler', () => { + const wrapper = mount(); + wrapper.find(DropdownTrigger).first().simulate('click'); + wrapper.find(DropdownContent).find('li a').first().simulate('click'); + expect(action.calledOnce).to.equal(true); + }); +}); -- cgit