diff options
| -rw-r--r-- | ui/.babelrc | 3 | ||||
| -rw-r--r-- | ui/app/components/center.js | 43 | ||||
| -rw-r--r-- | ui/app/components/confirmation.js | 68 | ||||
| -rw-r--r-- | ui/app/components/spinner/index.js | 19 | ||||
| -rw-r--r-- | ui/package.json | 8 | ||||
| -rw-r--r-- | ui/test/components/center.js | 43 | ||||
| -rw-r--r-- | ui/test/components/confirmation.js | 57 | 
7 files changed, 168 insertions, 73 deletions
| diff --git a/ui/.babelrc b/ui/.babelrc new file mode 100644 index 00000000..86c445f5 --- /dev/null +++ b/ui/.babelrc @@ -0,0 +1,3 @@ +{ +  "presets": ["es2015", "react"] +} diff --git a/ui/app/components/center.js b/ui/app/components/center.js index 5e47d0cc..e7e074af 100644 --- a/ui/app/components/center.js +++ b/ui/app/components/center.js @@ -3,38 +3,27 @@  //  import React from 'react' +import PropTypes from 'prop-types' -class Center extends React.Component { +const Center = props => ( +  <div className={"center-container center-" + props.direction}> +    <div className="center-item" style={props.width ? {width: props.width + 'px'} : null}> +      {props.children} +    </div> +  </div> +) -  static get defaultProps() {return{ -    width: null, -    direction: 'both', -  }} - -  constructor(props) { -    super(props) -  } - -  render() { -    let style = null -    if (this.props.width) { -      style = {width: this.props.width + 'px'} -    } -    let className = "center-container center-" + this.props.direction -    return ( -      <div className={className}> -        <div className="center-item" style={style}> -          {this.props.children} -        </div> -      </div> -    ) -  } +Center.defaultProps = { +  width: null, +  direction: 'both'  }  Center.propTypes = { -  children: React.PropTypes.oneOfType([ -    React.PropTypes.element, -    React.PropTypes.arrayOf(React.PropTypes.element) +  children: PropTypes.oneOfType([ +    PropTypes.element, +    PropTypes.arrayOf( +      PropTypes.element +    )    ])  } diff --git a/ui/app/components/confirmation.js b/ui/app/components/confirmation.js index 69186162..deceb47b 100644 --- a/ui/app/components/confirmation.js +++ b/ui/app/components/confirmation.js @@ -3,41 +3,43 @@  //  import React from 'react' -import {Button, ButtonGroup, ButtonToolbar, Glyphicon, Modal} -  from 'react-bootstrap' +import {Button, ButtonToolbar, Modal} from 'react-bootstrap' +import PropTypes from 'prop-types' -export default class Confirmation extends React.Component { +const Confirmation = props => ( +  <Modal> +    <Modal.Header closeButton> +      <Modal.Title> +        {props.title} +      </Modal.Title> +    </Modal.Header> +    <Modal.Body> +      <ButtonToolbar> +        <Button onClick={props.onAccept} bsStyle="success"> +          {props.acceptStr} +        </Button> +        <Button onClick={props.onCancel}> +          {props.cancelStr} +        </Button> +      </ButtonToolbar> +    </Modal.Body> +  </Modal> +) -  static get defaultProps() {return{ -    title: "Are you sure?", -    onCancel: null, -    onAccept: null, -    acceptStr: 'Accept', -    cancelStr: 'Cancel' -  }} - -  constructor(props) { -    super(props) -  } +Confirmation.defaultProps = { +  title: "Are you sure?", +  onCancel: null, +  onAccept: null, +  acceptStr: 'Accept', +  cancelStr: 'Cancel' +} -  render() { -    return ( -      <Modal show={true} onHide={this.props.onCancel}> -        <Modal.Header closeButton> -          <Modal.Title>{this.props.title}</Modal.Title> -        </Modal.Header> -        <Modal.Body> -          <ButtonToolbar> -            <Button onClick={this.props.onAccept} bsStyle="success"> -              {this.props.acceptStr} -            </Button> -            <Button onClick={this.props.onCancel}> -              {this.props.cancelStr} -            </Button> -          </ButtonToolbar> -        </Modal.Body> -      </Modal> -    ) -  } +Confirmation.propTypes = { +  className: PropTypes.string, +  onCancel: PropTypes.func.isRequired, +  onAccept: PropTypes.func.isRequired, +  acceptStr: PropTypes.string, +  cancelStr:  PropTypes.string  } +export default Confirmation diff --git a/ui/app/components/spinner/index.js b/ui/app/components/spinner/index.js index ffc32850..6cd34770 100644 --- a/ui/app/components/spinner/index.js +++ b/ui/app/components/spinner/index.js @@ -1,15 +1,12 @@  import React from 'react';  import './spinner.css'; -class Spinner extends React.Component { -  render() { -    let props = {} -    return <div className="spinner"> -      <div className="spin1"></div> -      <div className="spin2"></div> -      <div className="spin3"></div> -    </div> -  } -} +const Spinner = props => ( +  <div className="spinner"> +    <div className="spin1"></div> +    <div className="spin2"></div> +    <div className="spin3"></div> +  </div> +) -export default Spinner
\ No newline at end of file +export default Spinner diff --git a/ui/package.json b/ui/package.json index ed99e955..4749b985 100644 --- a/ui/package.json +++ b/ui/package.json @@ -17,13 +17,16 @@      "babel-preset-react": "^6.16.0",      "babel-preset-stage-0": "^6.16.0",      "bootstrap": "^3.3.7", +    "chai": "^3.5.0", +    "chai-enzyme": "^0.6.1",      "copy-webpack-plugin": "^3.0.1",      "css-loader": "^0.23.1",      "less": "^2.7.1",      "less-loader": "^2.2.3", +    "mocha": "^3.4.1",      "react": "^15.3.2", -    "react-dom": "^15.3.2",      "react-bootstrap": "^0.30.5", +    "react-dom": "^15.3.2",      "style-loader": "^0.13.1",      "webpack": "^1.13.1",      "zxcvbn": "^4.4.0" @@ -32,6 +35,7 @@      "ui": "chromium-browser \"http://localhost:7070/#$(cat ~/.config/leap/authtoken)\"",      "watch": "NODE_ENV=development webpack --watch",      "build": "NODE_ENV=development webpack", -    "build:production": "NODE_ENV=production webpack" +    "build:production": "NODE_ENV=production webpack", +    "test": "mocha --compilers js:babel-core/register ./test/**/*.js"    }  } diff --git a/ui/test/components/center.js b/ui/test/components/center.js new file mode 100644 index 00000000..e9242e7d --- /dev/null +++ b/ui/test/components/center.js @@ -0,0 +1,43 @@ +import React from 'react'; +import {shallow} from 'enzyme'; +import chaiEnzyme from 'chai-enzyme' +import chai, { expect } from 'chai' +import Center from '../../app/components/center'; + + +describe('Center Component', () => { + +  chai.use(chaiEnzyme()) + +  it('has reasonable defaults', () => { +    const center = shallow( +      <Center> +        test +      </Center> +    ) + +    expect(center.hasClass("center-both")) + +    expect(center.find(".center-item")).to.not.have.style('width') +  }) + +  it('has a width parameter on the inner div', () => { +    const center = shallow( +      <Center width="10"> +        test +      </Center> +    ) + +    expect(center.find(".center-item")).to.have.style('width').equal('10px') +  }) + +  it('sets direction parameter in the class name', () => { +    const center = shallow( +      <Center direction="vertically"> +        test +      </Center> +    ) + +    expect(center).to.have.className("center-vertically") +  }) +}) diff --git a/ui/test/components/confirmation.js b/ui/test/components/confirmation.js new file mode 100644 index 00000000..a563fb3f --- /dev/null +++ b/ui/test/components/confirmation.js @@ -0,0 +1,57 @@ +import React from 'react'; +import {shallow} from 'enzyme'; +import chaiEnzyme from 'chai-enzyme' +import Confirmation from '../../app/components/confirmation'; +import chai, { expect } from 'chai' + + +describe('Confirmation Component', () => { + +  const simpleFunction0 = () => {return 0} +  const simpleFunction1 = () => {return 1} + +  it('Passed functionss run on click', () => { +    const confirmation = shallow( +      <Confirmation +          onAccept={simpleFunction0} +          onCancel={simpleFunction1} +      /> +    ) + +    expect(confirmation.find('Button').get(0).props.onClick()).to.equal(simpleFunction0()) +    expect(confirmation.find('Button').get(1).props.onClick()).to.equal(simpleFunction1()) +  }) + +  it('sets defaults correctly', () => { +    const confirmation = shallow( +      <Confirmation +          onAccept={simpleFunction0} +          onCancel={simpleFunction1} +      /> +    ) + +    expect(confirmation.find("ModalTitle").first().children()).to.have.text("Are you sure?") +    expect(confirmation.find('Button').at(0).children().first()).to.have.text("Accept") +    expect(confirmation.find('Button').at(1).children().first()).to.have.text("Cancel") +  }) + +  it('overwrites defaults correctly', () => { +    const testTitle = "Test Title" +    const testAcceptStr = "Test accept string" +    const testCancelStr = "Test cancel string" + +    const confirmation = shallow( +      <Confirmation +          onAccept={simpleFunction0} +          onCancel={simpleFunction1} +          title={testTitle} +          acceptStr={testAcceptStr} +          cancelStr={testCancelStr} +      /> +    ) + +    expect(confirmation.find("ModalTitle").first().children()).to.have.text(testTitle) +    expect(confirmation.find('Button').at(0).children().first()).to.have.text(testAcceptStr) +    expect(confirmation.find('Button').at(1).children().first()).to.have.text(testCancelStr) +  }) +}) | 
