From daef2d75314e3f16d3c57daed3d663281bc78f1c Mon Sep 17 00:00:00 2001
From: yannis <yannisbarlas@gmail.com>
Date: Tue, 22 Aug 2017 15:06:12 +0300
Subject: [PATCH] add more xpub ui unit tests

---
 .babelrc                                   |   6 ++
 package.json                               |  20 +++-
 test/AppBar.test.js                        | 113 ++++++++++++++++++++
 test/Radio.test.js                         |  58 +++++++++++
 test/RadioGroup.test.js                    | 116 +++++++++++++++++++++
 test/YesOrNo.test.js                       |  57 ++++++++++
 test/__snapshots__/AppBar.test.js.snap     |  29 ++++++
 test/__snapshots__/Radio.test.js.snap      |  18 ++++
 test/__snapshots__/RadioGroup.test.js.snap |  48 +++++++++
 test/__snapshots__/YesOrNo.test.js.snap    |  34 ++++++
 test/setup/styleMock.js                    |   1 +
 11 files changed, 497 insertions(+), 3 deletions(-)
 create mode 100644 .babelrc
 create mode 100644 test/AppBar.test.js
 create mode 100644 test/Radio.test.js
 create mode 100644 test/RadioGroup.test.js
 create mode 100644 test/YesOrNo.test.js
 create mode 100644 test/__snapshots__/AppBar.test.js.snap
 create mode 100644 test/__snapshots__/Radio.test.js.snap
 create mode 100644 test/__snapshots__/RadioGroup.test.js.snap
 create mode 100644 test/__snapshots__/YesOrNo.test.js.snap
 create mode 100644 test/setup/styleMock.js

diff --git a/.babelrc b/.babelrc
new file mode 100644
index 000000000..2a4a32d91
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,6 @@
+{
+  "presets": [
+    "es2015",
+    "react"
+  ]
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 5e0804513..7c0d24f02 100644
--- a/package.json
+++ b/package.json
@@ -21,18 +21,28 @@
   "devDependencies": {
     "babel-core": "^6.26.0",
     "babel-loader": "^7.1.2",
+    "babel-jest": "^20.0.3",
+    "babel-preset-es2015": "^6.24.1",
     "babel-preset-env": "^1.6.0",
     "babel-preset-minify": "^0.2.0",
     "babel-preset-react": "^6.24.1",
     "babel-preset-stage-2": "^6.24.1",
     "css-loader": "^0.28.4",
+    "enzyme": "^2.9.1",
     "faker": "^4.1.0",
     "file-loader": "^0.11.2",
-    "xpub-styleguide": "^0.0.2",
+    "jest": "^20.0.4",
     "react-styleguidist": "^6.0.8",
+    "react-test-renderer": "^15.6.1",
     "style-loader": "^0.18.2",
     "webpack": "^3.5.5",
-    "webpack-node-externals": "^1.6.0"
+    "webpack-node-externals": "^1.6.0",
+    "xpub-styleguide": "^0.0.2"
+  },
+  "jest": {
+    "moduleNameMapper": {
+      "\\.(css|less)$": "<rootDir>/test/setup/styleMock.js"
+    }
   },
   "scripts": {
     "styleguide": "styleguidist server",
@@ -40,6 +50,10 @@
     "clean": "rimraf dist",
     "lint": "eslint src",
     "prebuild": "npm run clean && npm run lint",
-    "build": "webpack --progress --profile"
+    "build": "webpack --progress --profile",
+    "test": "NODE_ENV=test jest",
+    "test:watch": "NODE_ENV=test jest --watch",
+    "test:cover": "NODE_ENV=test jest --coverage",
+    "test:u": "NODE_ENV=test jest --updateSnapshot"
   }
 }
diff --git a/test/AppBar.test.js b/test/AppBar.test.js
new file mode 100644
index 000000000..b0cc4289d
--- /dev/null
+++ b/test/AppBar.test.js
@@ -0,0 +1,113 @@
+import React from 'react'
+import { clone } from 'lodash'
+import { shallow } from 'enzyme'
+import { Link } from 'react-router'
+import renderer from 'react-test-renderer'
+
+import AppBar from '../src/molecules/AppBar'
+
+const props = {
+  brandLink: 'some link',
+  brandName: 'some brand',
+  loginLink: 'login link',
+  logoutLink: 'logout link',
+  userName: 'some name',
+}
+
+const wrapper = shallow(<AppBar {...props} />)
+
+describe('AppBar', () => {
+  test('Snapshot', () => {
+    const tree = renderer.create(
+      <AppBar {...props} />
+    ).toJSON()
+    expect(tree).toMatchSnapshot()
+  })
+
+  test('Should render correctly', () => {
+    expect(wrapper.is('div'))
+    expect(wrapper.children()).toHaveLength(2)
+
+    const brand = wrapper.childAt(0)
+    expect(brand.is(Link)).toBeTruthy()
+    expect(brand.children()).toHaveLength(1)
+
+    const rightArea = wrapper.childAt(1)
+    expect(rightArea.is('div')).toBeTruthy()
+    expect(rightArea.children()).toHaveLength(2)
+
+    const username = rightArea.childAt(0)
+    expect(username.is('span')).toBeTruthy()
+
+    const logLink = rightArea.childAt(1)
+    expect(logLink.is(Link)).toBeTruthy()
+  })
+
+  test('Should link the brand to \'/\' if no brand link is given', () => {
+    const newProps = clone(props)
+    newProps.brandLink = undefined
+    const wrapper = shallow(<AppBar {...newProps} />)
+
+    const brand = wrapper.childAt(0)
+    expect(brand.prop('to')).toBe('/')
+  })
+
+  test('Should link the brand to the given prop', () => {
+    const brand = wrapper.childAt(0)
+    expect(brand.prop('to')).toBe(props.brandLink)
+  })
+
+  test('Should display the brand name', () => {
+    const brand = wrapper.childAt(0)
+    const brandName = brand.childAt(0)
+
+    expect(brandName.text()).toBe(props.brandName)
+  })
+
+  test('Should not display the username if there is none given', () => {
+    const newProps = clone(props)
+    newProps.userName = undefined
+    const wrapper = shallow(<AppBar {...newProps} />)
+
+    const rightArea = wrapper.childAt(1)
+
+    // If the username does not display, there is only child (login / logout)
+    expect(rightArea.children).toHaveLength(1)
+  })
+
+  test('Should display the username', () => {
+    const rightArea = wrapper.childAt(1)
+    expect(rightArea.children()).toHaveLength(2)
+
+    const userName = rightArea.childAt(0)
+    expect(userName.text()).toBe(props.userName)
+  })
+
+  test('Should display the login link if no username is given', () => {
+    const newProps = clone(props)
+    newProps.userName = undefined
+    const wrapper = shallow(<AppBar {...newProps} />)
+
+    const rightArea = wrapper.childAt(1)
+    const logLink = rightArea.childAt(0)  // first el if there is no username
+
+    expect(logLink.is(Link)).toBeTruthy()
+    expect(logLink.prop('to')).toBe(props.loginLink)
+    expect(logLink.children()).toHaveLength(1)
+
+    const logLinkText = logLink.childAt(0)
+    expect(logLinkText.text()).toBe('login')
+  })
+
+  test('Should display the logout link if a username is found', () => {
+    const rightArea = wrapper.childAt(1)
+    const logLink = rightArea.childAt(1) // 2nd el if there is a username
+
+    expect(logLink.is(Link)).toBeTruthy()
+    expect(logLink.prop('to')).toBe(props.logoutLink)
+    expect(logLink.children()).toHaveLength(1)
+
+    const logLinkText = logLink.childAt(0)
+    expect(logLinkText.text()).toBe('logout')
+  })
+})
diff --git a/test/Radio.test.js b/test/Radio.test.js
new file mode 100644
index 000000000..ef32d9dea
--- /dev/null
+++ b/test/Radio.test.js
@@ -0,0 +1,58 @@
+import React from 'react'
+import { shallow } from 'enzyme'
+import renderer from 'react-test-renderer'
+
+import Radio from '../src/atoms/Radio'
+
+const props = {
+  checked: false,
+  handleChange: jest.fn(),
+  label: 'TestLabel',
+  name: 'TestName',
+  required: true,
+  value: 'TestValue'
+}
+
+const wrapper = shallow(<Radio {...props} />)
+
+describe('Radio', () => {
+  test('Snapshot', () => {
+    const tree = renderer.create(
+      <Radio {...props} />
+    ).toJSON()
+    expect(tree).toMatchSnapshot()
+  })
+
+  test('Renders correctly', () => {
+    expect(wrapper.is('label')).toBeTruthy()
+    expect(wrapper.children()).toHaveLength(2)
+
+    const input = wrapper.childAt(0)
+    expect(input.is('input')).toBeTruthy()
+    expect(input.children()).toHaveLength(0)
+
+    const labelText = wrapper.childAt(1)
+    expect(labelText.text()).toBe(props.label)
+    expect(labelText.children()).toHaveLength(0)
+  })
+
+  test('Input gets the correct props', () => {
+    const input = wrapper.find('input')
+
+    expect(input.prop('name')).toBe(props.name)
+    expect(input.prop('value')).toBe(props.value)
+    expect(input.prop('checked')).toBe(props.checked)
+    expect(input.prop('required')).toBe(props.required)
+  })
+
+  test('Change handler should be called on change', () => {
+    const input = wrapper.find('input')
+
+    expect(props.handleChange).not.toHaveBeenCalled()
+
+    const event = { target: {} }
+    input.simulate('change', event)
+
+    expect(props.handleChange).toHaveBeenCalledTimes(1)
+  })
+})
diff --git a/test/RadioGroup.test.js b/test/RadioGroup.test.js
new file mode 100644
index 000000000..d2964e6d0
--- /dev/null
+++ b/test/RadioGroup.test.js
@@ -0,0 +1,116 @@
+import React from 'react'
+import { clone } from 'lodash'
+import { shallow } from 'enzyme'
+import renderer from 'react-test-renderer'
+
+import Radio from '../src/atoms/Radio'
+import RadioGroup from '../src/molecules/RadioGroup'
+
+const handleChange = () => { return null }
+
+const props = {
+  handleChange,
+  name: 'TestName',
+  options: [
+    {
+      label: 'Yes',
+      value: 'yes'
+    },
+    {
+      label: 'No',
+      value: 'no'
+    },
+    {
+      label: 'Maybe',
+      value: 'maybe'
+    }
+  ],
+  required: true,
+  value: undefined
+}
+
+const wrapper = shallow(<RadioGroup {...props} />)
+const radios = wrapper.find(Radio)
+
+describe('Radio Group', () => {
+  test('Snapshot', () => {
+    const tree = renderer.create(
+      <RadioGroup {...props} />
+    ).toJSON()
+    expect(tree).toMatchSnapshot()
+  })
+
+  test('Renders a number of radio buttons', () => {
+    expect(wrapper.is('div')).toBeTruthy()
+
+    const len = props.options.length
+    expect(wrapper.children()).toHaveLength(len)
+
+    let i = 0
+
+    while (i < len) {
+      const child = wrapper.childAt(i)
+      expect(child.is(Radio)).toBeTruthy()
+
+      i++
+    }
+
+    expect(radios).toHaveLength(len)
+  })
+
+  test('Radios get the correct props', () => {
+    const radioComps = radios.getNodes()
+    let i = 0
+
+    while (i < props.options.length) {
+      const radio = radioComps[i]
+      const radioProps = radio.props
+
+      expect(radioProps.label).toEqual(props.options[i].label)
+      expect(radioProps.value).toEqual(props.options[i].value)
+      expect(radioProps.name).toEqual(props.name)
+      expect(radioProps.required).toEqual(props.required)
+      expect(radioProps.handleChange).toEqual(props.handleChange)
+
+      i++
+    }
+  })
+
+  test('Value should match the checked radio button', () => {
+    // With no radio button selected
+    const radioComps = radios.getNodes()
+    let i = 0
+
+    while (i < props.options.length) {
+      const radio = radioComps[i]
+      const radioProps = radio.props
+
+      expect(radioProps.checked).toBeFalsy()
+      i++
+    }
+
+    // With the first radio button selected
+    // (re-initialise the wrapper with changed props)
+    const newProps = clone(props)
+    newProps.value = 'yes'
+
+    const newWrapper = shallow(<RadioGroup {...newProps} />)
+    const newRadios = newWrapper.find(Radio)
+    const newRadioComps = newRadios.getNodes()
+
+    i = 0
+
+    while (i < props.options.length) {
+      const radio = newRadioComps[i]
+      const radioProps = radio.props
+
+      if (i === 0) {
+        expect(radioProps.checked).toBeTruthy()
+      } else {
+        expect(radioProps.checked).toBeFalsy()
+      }
+
+      i++
+    }
+  })
+})
diff --git a/test/YesOrNo.test.js b/test/YesOrNo.test.js
new file mode 100644
index 000000000..31bab793d
--- /dev/null
+++ b/test/YesOrNo.test.js
@@ -0,0 +1,57 @@
+import React from 'react'
+import { shallow } from 'enzyme'
+import renderer from 'react-test-renderer'
+
+import YesOrNo from '../src/molecules/YesOrNo'
+import RadioGroup from '../src/molecules/RadioGroup'
+
+const handleChange = () => { return null }
+
+const props = {
+  handleChange,
+  name: 'TestName',
+  value: 'Maybe'
+}
+
+const wrapper = shallow(<YesOrNo {...props} />)
+const radio = wrapper.find(RadioGroup)
+
+describe('Yes or No', () => {
+  test('Snapshot', () => {
+    const tree = renderer.create(
+      <YesOrNo {...props} />
+    ).toJSON()
+    expect(tree).toMatchSnapshot()
+  })
+
+  test('Renders a RadioGroup', () => {
+    expect(wrapper.is('RadioGroup')).toBeTruthy()
+    expect(radio).toHaveLength(1)
+  })
+
+  test('Passes the correct options', () => {
+    const options = radio.props().options
+    expect(options).toHaveLength(2)
+
+    expect(options[0].value).toEqual('yes')
+    expect(options[0].label).toEqual('Yes')
+
+    expect(options[1].value).toEqual('no')
+    expect(options[1].label).toEqual('No')
+  })
+
+  test('Passes down the correct name', () => {
+    const name = radio.props().name
+    expect(name).toEqual(props.name)
+  })
+
+  test('Passes down the correct value', () => {
+    const value = radio.props().value
+    expect(value).toEqual(props.value)
+  })
+
+  test('Passes down the correct handle change function', () => {
+    const handle = radio.props().handleChange
+    expect(handle).toEqual(props.handleChange)
+  })
+})
diff --git a/test/__snapshots__/AppBar.test.js.snap b/test/__snapshots__/AppBar.test.js.snap
new file mode 100644
index 000000000..3ea9dd76f
--- /dev/null
+++ b/test/__snapshots__/AppBar.test.js.snap
@@ -0,0 +1,29 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`AppBar Snapshot 1`] = `
+<div
+  className={undefined}
+>
+  <a
+    className={undefined}
+    onClick={[Function]}
+    style={Object {}}
+  >
+    some brand
+  </a>
+  <div>
+    <span
+      className={undefined}
+    >
+      some name
+    </span>
+    <a
+      className=""
+      onClick={[Function]}
+      style={Object {}}
+    >
+      logout
+    </a>
+  </div>
+</div>
+`;
diff --git a/test/__snapshots__/Radio.test.js.snap b/test/__snapshots__/Radio.test.js.snap
new file mode 100644
index 000000000..d13bda93e
--- /dev/null
+++ b/test/__snapshots__/Radio.test.js.snap
@@ -0,0 +1,18 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Radio Snapshot 1`] = `
+<label
+  className={undefined}
+>
+  <input
+    checked={false}
+    className={undefined}
+    name="TestName"
+    onChange={[Function]}
+    required={true}
+    type="radio"
+    value="TestValue"
+  />
+  TestLabel
+</label>
+`;
diff --git a/test/__snapshots__/RadioGroup.test.js.snap b/test/__snapshots__/RadioGroup.test.js.snap
new file mode 100644
index 000000000..6443d52a4
--- /dev/null
+++ b/test/__snapshots__/RadioGroup.test.js.snap
@@ -0,0 +1,48 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Radio Group Snapshot 1`] = `
+<div>
+  <label
+    className={undefined}
+  >
+    <input
+      checked={false}
+      className={undefined}
+      name="TestName"
+      onChange={[Function]}
+      required={true}
+      type="radio"
+      value="yes"
+    />
+    Yes
+  </label>
+  <label
+    className={undefined}
+  >
+    <input
+      checked={false}
+      className={undefined}
+      name="TestName"
+      onChange={[Function]}
+      required={true}
+      type="radio"
+      value="no"
+    />
+    No
+  </label>
+  <label
+    className={undefined}
+  >
+    <input
+      checked={false}
+      className={undefined}
+      name="TestName"
+      onChange={[Function]}
+      required={true}
+      type="radio"
+      value="maybe"
+    />
+    Maybe
+  </label>
+</div>
+`;
diff --git a/test/__snapshots__/YesOrNo.test.js.snap b/test/__snapshots__/YesOrNo.test.js.snap
new file mode 100644
index 000000000..bfe7af7e3
--- /dev/null
+++ b/test/__snapshots__/YesOrNo.test.js.snap
@@ -0,0 +1,34 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Yes or No Snapshot 1`] = `
+<div>
+  <label
+    className={undefined}
+  >
+    <input
+      checked={false}
+      className={undefined}
+      name="TestName"
+      onChange={[Function]}
+      required={undefined}
+      type="radio"
+      value="yes"
+    />
+    Yes
+  </label>
+  <label
+    className={undefined}
+  >
+    <input
+      checked={false}
+      className={undefined}
+      name="TestName"
+      onChange={[Function]}
+      required={undefined}
+      type="radio"
+      value="no"
+    />
+    No
+  </label>
+</div>
+`;
diff --git a/test/setup/styleMock.js b/test/setup/styleMock.js
new file mode 100644
index 000000000..7c6d6c73d
--- /dev/null
+++ b/test/setup/styleMock.js
@@ -0,0 +1 @@
+module.exports = {}
\ No newline at end of file
-- 
GitLab