summaryrefslogtreecommitdiff
path: root/web-ui
diff options
context:
space:
mode:
authorAnike Arni <anikarni@gmail.com>2017-02-08 17:45:34 -0200
committerGitHub <noreply@github.com>2017-02-08 17:45:34 -0200
commit0d4cf4ad3a5da62f65730d6c3e3665fc12d72590 (patch)
treee852ab83caeca6158ffc78e3cda100157ddb9f88 /web-ui
parenta1c384cebd80e177389ef79c2de6400db986aaa6 (diff)
parentea852b12e33b0e50ba7986c33ad68be5e38305ba (diff)
Merge pull request #965 from pixelated/backup-email-page
Adds lint, coverage and css autoprefixer
Diffstat (limited to 'web-ui')
-rw-r--r--web-ui/.babelrc7
-rw-r--r--web-ui/.eslintrc.json18
-rw-r--r--web-ui/config/loaders-webpack.js2
-rw-r--r--web-ui/package.json53
-rw-r--r--web-ui/postcss.config.js5
-rw-r--r--web-ui/src/account_recovery/account_recovery.js20
-rw-r--r--web-ui/src/account_recovery/page.js22
-rw-r--r--web-ui/src/account_recovery/page.scss11
-rw-r--r--web-ui/src/common/input_field/input-field.scss4
-rw-r--r--web-ui/src/common/input_field/input_field.js13
-rw-r--r--web-ui/src/common/submit_button/submit-button.scss2
-rw-r--r--web-ui/src/common/submit_button/submit_button.js12
-rw-r--r--web-ui/src/i18n.js12
-rw-r--r--web-ui/test/unit/account_recovery/page.spec.js31
-rw-r--r--web-ui/test/unit/common/input_field/input_field.spec.js20
-rw-r--r--web-ui/test/unit/common/submit_button/submit_button.spec.js16
-rw-r--r--web-ui/webpack.config.js1
17 files changed, 164 insertions, 85 deletions
diff --git a/web-ui/.babelrc b/web-ui/.babelrc
index 86c445f5..e74e4d82 100644
--- a/web-ui/.babelrc
+++ b/web-ui/.babelrc
@@ -1,3 +1,8 @@
{
- "presets": ["es2015", "react"]
+ "presets": ["es2015", "react"],
+ "env": {
+ "test": {
+ "plugins": ["istanbul"]
+ }
+ }
}
diff --git a/web-ui/.eslintrc.json b/web-ui/.eslintrc.json
new file mode 100644
index 00000000..554498f9
--- /dev/null
+++ b/web-ui/.eslintrc.json
@@ -0,0 +1,18 @@
+/* see https://github.com/airbnb/javascript for lint rules */
+{
+ "extends": "airbnb",
+ "plugins": [
+ "react",
+ "jsx-a11y",
+ "import"
+ ],
+ "rules": {
+ "import/no-extraneous-dependencies": ["off"],
+ "import/extensions": ["off"],
+ "import/no-unresolved": ["off"],
+ "react/jsx-filename-extension": ["off"],
+ "jsx-quotes": ["error", "prefer-single"],
+ "no-undef": ["off"],
+ "comma-dangle": ["off"]
+ }
+}
diff --git a/web-ui/config/loaders-webpack.js b/web-ui/config/loaders-webpack.js
index 21e9a572..f5237dff 100644
--- a/web-ui/config/loaders-webpack.js
+++ b/web-ui/config/loaders-webpack.js
@@ -7,7 +7,7 @@ module.exports = [
},
{
test: /\.scss|css$/,
- loader: "style-loader!css-loader!sass-loader"
+ loader: "style-loader!css-loader!postcss-loader!sass-loader"
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
diff --git a/web-ui/package.json b/web-ui/package.json
index dba34e97..4f7c1bc5 100644
--- a/web-ui/package.json
+++ b/web-ui/package.json
@@ -9,6 +9,7 @@
"babel-cli": "^6.22.2",
"babel-core": "^6.21.0",
"babel-loader": "^6.2.10",
+ "babel-plugin-istanbul": "^3.1.2",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.22.0",
"bower": "1.7.9",
@@ -16,6 +17,11 @@
"css-loader": "^0.26.1",
"dompurify": "^0.8.4",
"enzyme": "^2.7.1",
+ "eslint": "^3.15.0",
+ "eslint-config-airbnb": "^14.1.0",
+ "eslint-plugin-import": "^2.2.0",
+ "eslint-plugin-jsx-a11y": "^4.0.0",
+ "eslint-plugin-react": "^6.9.0",
"expect": "^1.20.2",
"file-loader": "^0.10.0",
"font-awesome": "^4.7.0",
@@ -48,6 +54,8 @@
"mocha-webpack": "^0.7.0",
"modernizr": "^3.3.1",
"node-sass": "^4.5.0",
+ "nyc": "^10.1.2",
+ "postcss-loader": "^1.2.2",
"quoted-printable": "^1.0.1",
"react": "^15.4.2",
"react-a11y": "^0.3.3",
@@ -64,26 +72,35 @@
"webpack": "^1.14.0"
},
"scripts": {
- "test": "npm run jshint --silent && npm run build-statics --silent && npm run mocha-test && npm run karma-test",
- "mocha-test": "mocha-webpack --webpack-config webpack.test.config.js \"test/unit/**/*.spec.js\"",
- "mocha-watch": "mocha-webpack --watch --webpack-config webpack.test.config.js \"test/unit/**/*.spec.js\"",
- "karma-test": "karma start --single-run $GRUNT_OPTS",
- "debug": "npm run build && karma start --browsers Chrome $GRUNT_OPTS",
- "watch": "npm run compass-watch & npm run handlebars-watch & npm run build-js-watch",
- "watch-test": "karma start",
- "handlebars": "mkdir -p app/js/generated/hbs/ && handlebars app/templates/**/*.hbs > app/js/generated/hbs/templates.js --namespace=window.Pixelated --root .",
- "handlebars-watch": "watch 'npm run handlebars' app/templates",
- "compass": "compass compile",
- "compass-watch": "compass watch",
- "build": "npm run build-statics && npm run build-js",
- "build-statics": "npm run clean && npm run handlebars && npm run add_git_version && npm run compass",
- "build-prod": "npm run build-statics && webpack -p --config ./webpack.production.config.js",
- "build-js": "webpack --colors --progress",
- "build-js-watch": "webpack --colors --progress --watch",
- "jshint": "jshint --config=.jshintrc app test",
+ "test": "npm run lint --silent && npm run build:statics --silent && npm run test:unit",
+ "test:unit": "npm run test:coverage && npm run test:karma",
+ "test:coverage": "NODE_ENV=test nyc --check-coverage npm run test:mocha",
+ "test:mocha": "mocha-webpack --webpack-config webpack.test.config.js \"test/unit/**/*.spec.js\"",
+ "test:karma": "karma start --single-run $GRUNT_OPTS",
+ "test:watch:mocha": "npm run test:mocha -- --watch",
+ "test:watch:karma": "karma start",
+ "lint": "npm run lint:jshint && npm run lint:eslint",
+ "lint:jshint": "jshint --config=.jshintrc app test",
+ "lint:eslint": "eslint src test/unit",
+ "build": "npm run build:statics && npm run build:js",
+ "build:debug": "npm run build && karma start --browsers Chrome $GRUNT_OPTS",
+ "build:statics": "npm run clean && npm run build:handlebars && npm run add_git_version && npm run build:compass",
+ "build:prod": "npm run build:statics && webpack -p --config ./webpack.production.config.js",
+ "build:js": "webpack --colors --progress",
+ "build:compass": "compass compile",
+ "build:handlebars": "mkdir -p app/js/generated/hbs/ && handlebars app/templates/**/*.hbs > app/js/generated/hbs/templates.js --namespace=window.Pixelated --root .",
+ "watch": "npm run watch:compass & npm run watch:handlebars & npm run watch:js",
+ "watch:handlebars": "watch 'npm run build:handlebars' app/templates",
+ "watch:compass": "compass watch",
+ "watch:js": "webpack --colors --progress --watch",
"clean": "rm -rf dist/ app/js/generated/hbs/* app/css/*",
- "package": "PIXELATED_BUILD='package' npm run build-prod && npm run imagemin",
"imagemin": "node config/imagemin.js",
+ "package": "PIXELATED_BUILD='package' npm run build:prod && npm run imagemin",
"add_git_version": "/bin/bash config/add_git_version.sh"
+ },
+ "nyc": {
+ "include": [
+ "src/**/*.js"
+ ]
}
}
diff --git a/web-ui/postcss.config.js b/web-ui/postcss.config.js
new file mode 100644
index 00000000..88752c6c
--- /dev/null
+++ b/web-ui/postcss.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ plugins: [
+ require('autoprefixer')
+ ]
+}
diff --git a/web-ui/src/account_recovery/account_recovery.js b/web-ui/src/account_recovery/account_recovery.js
index 6c12e326..d4e0f4e8 100644
--- a/web-ui/src/account_recovery/account_recovery.js
+++ b/web-ui/src/account_recovery/account_recovery.js
@@ -15,21 +15,21 @@
* along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
*/
-import React from 'react'
-import { render } from 'react-dom'
-import a11y from 'react-a11y'
-import { I18nextProvider } from 'react-i18next'
+import React from 'react';
+import { render } from 'react-dom';
+import a11y from 'react-a11y';
+import { I18nextProvider } from 'react-i18next';
-import Page from './page'
-import i18n from '../i18n'
+import 'font-awesome/scss/font-awesome.scss';
-import 'font-awesome/scss/font-awesome.scss'
+import PageWrapper from './page';
+import i18n from '../i18n';
-if(process.env.NODE_ENV === 'development') a11y(React);
+if (process.env.NODE_ENV === 'development') a11y(React);
render(
- <I18nextProvider i18n={ i18n }>
- <Page/>
+ <I18nextProvider i18n={i18n}>
+ <PageWrapper />
</I18nextProvider>,
document.getElementById('root')
);
diff --git a/web-ui/src/account_recovery/page.js b/web-ui/src/account_recovery/page.js
index d1bcb464..ac01529d 100644
--- a/web-ui/src/account_recovery/page.js
+++ b/web-ui/src/account_recovery/page.js
@@ -15,12 +15,12 @@
* along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
*/
-import React from 'react'
-import { translate } from 'react-i18next'
-import SubmitButton from 'src/common/submit_button/submit_button'
-import InputField from 'src/common/input_field/input_field'
+import React from 'react';
+import { translate } from 'react-i18next';
+import SubmitButton from 'src/common/submit_button/submit_button';
+import InputField from 'src/common/input_field/input_field';
-import './page.scss'
+import './page.scss';
export const Page = ({ t }) => (
<div className='container'>
@@ -32,13 +32,17 @@ export const Page = ({ t }) => (
<InputField name='email' label={t('backup-account.input-label')} />
<SubmitButton buttonText={t('backup-account.button')} />
<div>
- <a href="/">
- <i className="fa fa-angle-left" aria-hidden="true"></i>
+ <a href='/'>
+ <i className='fa fa-angle-left' aria-hidden='true' />
<span>{t('back-to-inbox')}</span>
</a>
</div>
</form>
</div>
-)
+);
-export default translate('', { wait: true })(Page)
+Page.propTypes = {
+ t: React.PropTypes.func.isRequired
+};
+
+export default translate('', { wait: true })(Page);
diff --git a/web-ui/src/account_recovery/page.scss b/web-ui/src/account_recovery/page.scss
index c928d815..619d1105 100644
--- a/web-ui/src/account_recovery/page.scss
+++ b/web-ui/src/account_recovery/page.scss
@@ -65,18 +65,13 @@ a {
width: 84%;
margin: 3% auto;
padding: 6% 5%;
-
- -webkit-display: flex;
display: flex;
- -webkit-align-items: flex-start;
align-items: flex-start;
- -webkit-flex-direction: column;
flex-direction: column;
}
img {
width: 50%;
- -webkit-align-self: center;
align-self: center;
}
@@ -87,13 +82,10 @@ img {
form {
display: flex;
- -webkit-display: flex;
- -webkit-flex-direction: column;
flex-direction: column;
div {
width: 70%;
- -webkit-align-self: center;
align-self: center;
}
}
@@ -103,9 +95,7 @@ img {
.container{
width: 60%;
padding: 3%;
- -webkit-align-items: flex-start;
align-items: flex-start;
- -webkit-flex-direction: row;
flex-direction: row;
max-width: 700px;
}
@@ -115,7 +105,6 @@ img {
div {
width: 300px;
- -webkit-align-self: flex-start;
align-self: flex-start;
}
}
diff --git a/web-ui/src/common/input_field/input-field.scss b/web-ui/src/common/input_field/input-field.scss
index 6ec827ab..dd8e8927 100644
--- a/web-ui/src/common/input_field/input-field.scss
+++ b/web-ui/src/common/input_field/input-field.scss
@@ -33,8 +33,6 @@
left: 6px;
top:10px;
transition:0.2s ease all;
- -moz-transition:0.2s ease all;
- -webkit-transition:0.2s ease all;
}
.input-field {
@@ -61,7 +59,6 @@
@media only screen and (min-width : 500px) {
.input-field-group {
width: 70%;
- -webkit-align-self: center;
align-self: center;
}
}
@@ -69,7 +66,6 @@
@media only screen and (min-width : 960px) {
.input-field-group {
width: 300px;
- -webkit-align-self: flex-start;
align-self: flex-start;
margin-top: 3em;
font-size: 1em;
diff --git a/web-ui/src/common/input_field/input_field.js b/web-ui/src/common/input_field/input_field.js
index 43899419..1378ba74 100644
--- a/web-ui/src/common/input_field/input_field.js
+++ b/web-ui/src/common/input_field/input_field.js
@@ -15,15 +15,20 @@
* along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
*/
-import React from 'react'
+import React from 'react';
-import './input-field.scss'
+import './input-field.scss';
const InputField = ({ label, name }) => (
<div className='input-field-group'>
<input type='text' name={name} className='input-field' required />
<label className='input-field-label' htmlFor={name}>{label}</label>
</div>
-)
+);
-export default InputField
+InputField.propTypes = {
+ label: React.PropTypes.string.isRequired,
+ name: React.PropTypes.string.isRequired
+};
+
+export default InputField;
diff --git a/web-ui/src/common/submit_button/submit-button.scss b/web-ui/src/common/submit_button/submit-button.scss
index ccd0bef4..13cb7607 100644
--- a/web-ui/src/common/submit_button/submit-button.scss
+++ b/web-ui/src/common/submit_button/submit-button.scss
@@ -32,7 +32,6 @@
@media only screen and (min-width : 500px) {
.submit-button {
width: 70%;
- -webkit-align-self: center;
align-self: center;
}
}
@@ -40,7 +39,6 @@
@media only screen and (min-width : 960px) {
.submit-button {
width: 300px;
- -webkit-align-self: flex-start;
align-self: flex-start;
font-size: 0.8em;
margin-bottom: 1em;
diff --git a/web-ui/src/common/submit_button/submit_button.js b/web-ui/src/common/submit_button/submit_button.js
index 89cfc55b..fb87bf7d 100644
--- a/web-ui/src/common/submit_button/submit_button.js
+++ b/web-ui/src/common/submit_button/submit_button.js
@@ -15,12 +15,16 @@
* along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
*/
-import React from 'react'
+import React from 'react';
-import './submit-button.scss'
+import './submit-button.scss';
const SubmitButton = ({ buttonText }) => (
<input type='submit' className='submit-button' value={buttonText} />
-)
+);
-export default SubmitButton
+SubmitButton.propTypes = {
+ buttonText: React.PropTypes.string.isRequired
+};
+
+export default SubmitButton;
diff --git a/web-ui/src/i18n.js b/web-ui/src/i18n.js
index 9c6ad550..bbbe2dcd 100644
--- a/web-ui/src/i18n.js
+++ b/web-ui/src/i18n.js
@@ -14,15 +14,15 @@
* You should have received a copy of the GNU Affero General Public License
* along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
*/
-import i18n from 'i18next'
-import i18nBackend from 'i18nextXHRBackend'
-import i18nDetector from 'i18nextBrowserLanguageDetector'
+import i18n from 'i18next';
+import i18nBackend from 'i18nextXHRBackend';
+import I18nDetector from 'i18nextBrowserLanguageDetector';
-const detector = new i18nDetector();
+const detector = new I18nDetector();
const detect = detector.detect.bind(detector);
-detector.detect = function(detectionOrder) {
- let result = detect(detectionOrder);
+detector.detect = (detectionOrder) => {
+ const result = detect(detectionOrder);
return result.replace('-', '_');
};
diff --git a/web-ui/test/unit/account_recovery/page.spec.js b/web-ui/test/unit/account_recovery/page.spec.js
index 590d1de8..6a139167 100644
--- a/web-ui/test/unit/account_recovery/page.spec.js
+++ b/web-ui/test/unit/account_recovery/page.spec.js
@@ -1,25 +1,26 @@
-import { shallow } from 'enzyme'
-import expect from 'expect'
-import React from 'react'
-import { Page } from 'src/account_recovery/page'
+import { shallow } from 'enzyme';
+import expect from 'expect';
+import React from 'react';
+import { Page } from 'src/account_recovery/page';
describe('Page', () => {
- let mockT, page
+ let mockT;
+ let page;
beforeEach(() => {
- mockT = (key) => (key)
- page = shallow(<Page t={mockT}/>)
- })
+ mockT = key => key;
+ page = shallow(<Page t={mockT} />);
+ });
it('renders backup email page title', () => {
- expect(page.find('h1').text()).toEqual('backup-account.title')
- })
+ expect(page.find('h1').text()).toEqual('backup-account.title');
+ });
it('renders backup account email input field', () => {
- expect(page.find('InputField').props().name).toEqual('email')
- })
+ expect(page.find('InputField').props().name).toEqual('email');
+ });
it('renders backup account submit button', () => {
- expect(page.find('SubmitButton').props().buttonText).toEqual('backup-account.button')
- })
-})
+ expect(page.find('SubmitButton').props().buttonText).toEqual('backup-account.button');
+ });
+});
diff --git a/web-ui/test/unit/common/input_field/input_field.spec.js b/web-ui/test/unit/common/input_field/input_field.spec.js
new file mode 100644
index 00000000..0c044ce1
--- /dev/null
+++ b/web-ui/test/unit/common/input_field/input_field.spec.js
@@ -0,0 +1,20 @@
+import { shallow } from 'enzyme';
+import expect from 'expect';
+import React from 'react';
+import InputField from 'src/common/input_field/input_field';
+
+describe('InputField', () => {
+ let inputField;
+
+ beforeEach(() => {
+ inputField = shallow(<InputField label='Email' name='email' />);
+ });
+
+ it('renders an input of type text for email', () => {
+ expect(inputField.find('input[type="text"]').props().name).toEqual('email');
+ });
+
+ it('renders a label for the email', () => {
+ expect(inputField.find('label').text()).toEqual('Email');
+ });
+});
diff --git a/web-ui/test/unit/common/submit_button/submit_button.spec.js b/web-ui/test/unit/common/submit_button/submit_button.spec.js
new file mode 100644
index 00000000..8279547c
--- /dev/null
+++ b/web-ui/test/unit/common/submit_button/submit_button.spec.js
@@ -0,0 +1,16 @@
+import { shallow } from 'enzyme';
+import expect from 'expect';
+import React from 'react';
+import SubmitButton from 'src/common/submit_button/submit_button';
+
+describe('SubmitButton', () => {
+ let submitButton;
+
+ beforeEach(() => {
+ submitButton = shallow(<SubmitButton buttonText='Add Email' />);
+ });
+
+ it('renders an input of type submit for add email', () => {
+ expect(submitButton.find('input[type="submit"]').props().value).toEqual('Add Email');
+ });
+});
diff --git a/web-ui/webpack.config.js b/web-ui/webpack.config.js
index 9171b8f5..8a54af21 100644
--- a/web-ui/webpack.config.js
+++ b/web-ui/webpack.config.js
@@ -16,6 +16,7 @@ module.exports = {
filename: '[name].js',
publicPath: '/assets/'
},
+ devtool: 'source-map',
resolve: {
alias: aliases,
extensions: ['', '.js']