summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--web-ui/package.json6
-rw-r--r--web-ui/src/backup_account/backup_account.js2
-rw-r--r--web-ui/src/backup_account/backup_email/backup_email.js16
-rw-r--r--web-ui/src/backup_account/backup_email/backup_email.spec.js89
-rw-r--r--web-ui/src/backup_account/page.js6
-rw-r--r--web-ui/src/backup_account/page.spec.js4
-rw-r--r--web-ui/webpack.test.config.js10
7 files changed, 91 insertions, 42 deletions
diff --git a/web-ui/package.json b/web-ui/package.json
index 5a5375e6..d26fc7f8 100644
--- a/web-ui/package.json
+++ b/web-ui/package.json
@@ -19,12 +19,14 @@
"css-loader": "^0.26.1",
"dompurify": "^0.8.4",
"enzyme": "^2.7.1",
+ "es6-promise": "^4.1.0",
"eslint": "^3.17.1",
"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",
+ "fetch-mock": "^5.9.4",
"file-loader": "^0.10.0",
"font-awesome": "^4.7.0",
"handlebars": "^4.0.5",
@@ -37,6 +39,7 @@
"imagemin": "5.2.1",
"imagemin-pngquant": "^5.0.0",
"imagemin-svgo": "^5.2.0",
+ "isomorphic-fetch": "^2.2.1",
"jasmine-flight": "^4.0.0",
"jasmine-jquery": "^2.1.1",
"jquery": "^3.1.1",
@@ -78,7 +81,8 @@
"utf8": "^2.1.2",
"validator": "^7.0.0",
"watch": "0.19.1",
- "webpack": "^1.14.0"
+ "webpack": "^1.14.0",
+ "webpack-node-externals": "^1.5.4"
},
"scripts": {
"test": "npm run lint --silent && npm run build:statics --silent && npm run test:unit && npm run test:integration",
diff --git a/web-ui/src/backup_account/backup_account.js b/web-ui/src/backup_account/backup_account.js
index ac218a39..19b7c19c 100644
--- a/web-ui/src/backup_account/backup_account.js
+++ b/web-ui/src/backup_account/backup_account.js
@@ -22,6 +22,8 @@ import a11y from 'react-a11y';
import App from 'src/common/app';
import PageWrapper from './page';
+require('es6-promise').polyfill();
+
if (process.env.NODE_ENV === 'development') a11y(React);
render(
diff --git a/web-ui/src/backup_account/backup_email/backup_email.js b/web-ui/src/backup_account/backup_email/backup_email.js
index 05cba35e..09863950 100644
--- a/web-ui/src/backup_account/backup_email/backup_email.js
+++ b/web-ui/src/backup_account/backup_email/backup_email.js
@@ -15,11 +15,13 @@
* along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
*/
+import 'isomorphic-fetch';
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 validator from 'validator';
+import browser from 'helpers/browser';
import './backup_email.scss';
@@ -42,9 +44,17 @@ export class BackupEmail extends React.Component {
submitHandler = (event) => {
event.preventDefault();
- if (typeof this.props.onSubmit === 'function') {
- this.props.onSubmit();
- }
+
+ fetch('/backup-account', {
+ credentials: 'same-origin',
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ csrftoken: [browser.getCookie('XSRF-TOKEN')]
+ })
+ }).then(() => this.props.onSubmit('success'));
}
render() {
diff --git a/web-ui/src/backup_account/backup_email/backup_email.spec.js b/web-ui/src/backup_account/backup_email/backup_email.spec.js
index 8732003b..48199738 100644
--- a/web-ui/src/backup_account/backup_email/backup_email.spec.js
+++ b/web-ui/src/backup_account/backup_email/backup_email.spec.js
@@ -1,90 +1,125 @@
import { shallow } from 'enzyme';
import expect from 'expect';
import React from 'react';
+import fetchMock from 'fetch-mock';
import { BackupEmail } from 'src/backup_account/backup_email/backup_email';
+import browser from 'helpers/browser';
describe('BackupEmail', () => {
- let page;
+ let backupEmail;
+ let mockOnSubmit;
let mockTranslations;
beforeEach(() => {
+ mockOnSubmit = expect.createSpy();
+
mockTranslations = key => key;
- page = shallow(<BackupEmail t={mockTranslations} />);
+ backupEmail = shallow(<BackupEmail t={mockTranslations} onSubmit={mockOnSubmit} />);
});
it('renders backup email title', () => {
- expect(page.find('h1').text()).toEqual('backup-account.backup-email.title');
+ expect(backupEmail.find('h1').text()).toEqual('backup-account.backup-email.title');
});
it('renders backup account email input field', () => {
- expect(page.find('InputField').props().name).toEqual('email');
+ expect(backupEmail.find('InputField').props().name).toEqual('email');
});
it('renders backup account submit button', () => {
- expect(page.find('SubmitButton').props().buttonText).toEqual('backup-account.backup-email.button');
- });
-
- it('form submit should call parameter custom submit', () => {
- const mockOnSubmit = expect.createSpy();
- const event = { preventDefault() {} };
- page = shallow(<BackupEmail t={mockTranslations} onSubmit={mockOnSubmit} />);
-
- page.instance().submitHandler(event);
- expect(mockOnSubmit).toHaveBeenCalled();
+ expect(backupEmail.find('SubmitButton').props().buttonText).toEqual('backup-account.backup-email.button');
});
describe('Email validation', () => {
- let pageInstance;
+ let backupEmailInstance;
beforeEach(() => {
- pageInstance = page.instance();
+ backupEmailInstance = backupEmail.instance();
});
it('verify initial state', () => {
- expect(pageInstance.state.error).toEqual('');
- expect(page.find('SubmitButton').props().disabled).toEqual(true);
+ expect(backupEmailInstance.state.error).toEqual('');
+ expect(backupEmail.find('SubmitButton').props().disabled).toBe(true);
});
context('with invalid email', () => {
beforeEach(() => {
- pageInstance.validateEmail({ target: { value: 'test' } });
+ backupEmailInstance.validateEmail({ target: { value: 'test' } });
});
it('sets error in state', () => {
- expect(pageInstance.state.error).toEqual('backup-account.backup-email.error.invalid-email');
+ expect(backupEmailInstance.state.error).toEqual('backup-account.backup-email.error.invalid-email');
});
it('disables submit button', () => {
- expect(page.find('SubmitButton').props().disabled).toEqual(true);
+ expect(backupEmail.find('SubmitButton').props().disabled).toBe(true);
});
});
context('with valid email', () => {
beforeEach(() => {
- pageInstance.validateEmail({ target: { value: 'test@test.com' } });
+ backupEmailInstance.validateEmail({ target: { value: 'test@test.com' } });
});
it('does not set error in state', () => {
- expect(pageInstance.state.error).toEqual('');
+ expect(backupEmailInstance.state.error).toEqual('');
});
it('submit button is enabled', () => {
- expect(page.find('SubmitButton').props().disabled).toEqual(false);
+ expect(backupEmail.find('SubmitButton').props().disabled).toBe(false);
});
});
context('with empty email', () => {
beforeEach(() => {
- pageInstance.validateEmail({ target: { value: '' } });
+ backupEmailInstance.validateEmail({ target: { value: '' } });
});
it('not set error in state', () => {
- expect(pageInstance.state.error).toEqual('');
+ expect(backupEmailInstance.state.error).toEqual('');
});
it('disables submit button', () => {
- expect(page.find('SubmitButton').props().disabled).toEqual(true);
+ expect(backupEmail.find('SubmitButton').props().disabled).toBe(true);
});
});
});
+
+ describe('Submit', () => {
+ let preventDefaultSpy;
+
+ beforeEach((done) => {
+ mockOnSubmit = expect.createSpy().andCall(() => done());
+ preventDefaultSpy = expect.createSpy();
+ expect.spyOn(browser, 'getCookie').andReturn('abc123');
+
+ backupEmail = shallow(<BackupEmail t={mockTranslations} onSubmit={mockOnSubmit} />);
+
+ fetchMock.post('/backup-account', 204);
+ backupEmail.find('form').simulate('submit', { preventDefault: preventDefaultSpy });
+ });
+
+ it('posts backup email', () => {
+ expect(fetchMock.called('/backup-account')).toBe(true, 'Backup account POST was not called');
+ });
+
+ it('sends csrftoken as content', () => {
+ expect(fetchMock.lastOptions('/backup-account').body).toContain('"csrftoken":["abc123"]');
+ });
+
+ it('sends content-type header', () => {
+ expect(fetchMock.lastOptions('/backup-account').headers['Content-Type']).toEqual('application/json');
+ });
+
+ it('sends same origin headers', () => {
+ expect(fetchMock.lastOptions('/backup-account').credentials).toEqual('same-origin');
+ });
+
+ it('prevents default call to refresh page', () => {
+ expect(preventDefaultSpy).toHaveBeenCalled();
+ });
+
+ it('calls onSubmit from props when success', () => {
+ expect(mockOnSubmit).toHaveBeenCalledWith('success');
+ });
+ });
});
diff --git a/web-ui/src/backup_account/page.js b/web-ui/src/backup_account/page.js
index 221c6978..49e4b316 100644
--- a/web-ui/src/backup_account/page.js
+++ b/web-ui/src/backup_account/page.js
@@ -34,10 +34,8 @@ export class Page extends React.Component {
this.state = { status: '' };
}
- saveBackupEmail = () => {
- this.setState({
- status: 'success'
- });
+ saveBackupEmail = (status) => {
+ this.setState({ status });
}
mainContent = () => {
diff --git a/web-ui/src/backup_account/page.spec.js b/web-ui/src/backup_account/page.spec.js
index 23c117a0..bd7bb884 100644
--- a/web-ui/src/backup_account/page.spec.js
+++ b/web-ui/src/backup_account/page.spec.js
@@ -29,7 +29,7 @@ describe('BackupAccount', () => {
});
it('changes state', () => {
- pageInstance.saveBackupEmail();
+ pageInstance.saveBackupEmail('success');
expect(pageInstance.state.status).toEqual('success');
});
@@ -38,7 +38,7 @@ describe('BackupAccount', () => {
});
it('renders confirmation component', () => {
- pageInstance.saveBackupEmail();
+ pageInstance.saveBackupEmail('success');
expect(page.find(Confirmation).length).toEqual(1);
});
});
diff --git a/web-ui/webpack.test.config.js b/web-ui/webpack.test.config.js
index 3dc1b311..699aa12e 100644
--- a/web-ui/webpack.test.config.js
+++ b/web-ui/webpack.test.config.js
@@ -1,17 +1,17 @@
var path = require('path');
var webpack = require('webpack');
var aliases = require('./config/alias-webpack');
+var nodeExternals = require('webpack-node-externals');
module.exports = {
+ target: 'node',
resolve: {
alias: aliases,
extensions: ['', '.js']
},
- externals: {
- 'react/lib/ExecutionEnvironment': true,
- 'react/addons': true,
- 'react/lib/ReactContext': 'window'
- },
+ externals: [nodeExternals({
+ whitelist: [/\.(?!(?:jsx?|json)$).{1,5}$/i]
+ })],
module: {
loaders: [
{