diff options
Diffstat (limited to 'web-ui/src/backup_account')
-rw-r--r-- | web-ui/src/backup_account/backup_email/backup_email.js | 28 | ||||
-rw-r--r-- | web-ui/src/backup_account/backup_email/backup_email.spec.js | 68 | ||||
-rw-r--r-- | web-ui/src/backup_account/page.js | 11 | ||||
-rw-r--r-- | web-ui/src/backup_account/page.scss | 14 | ||||
-rw-r--r-- | web-ui/src/backup_account/page.spec.js | 25 |
5 files changed, 97 insertions, 49 deletions
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 09863950..9d622d8d 100644 --- a/web-ui/src/backup_account/backup_email/backup_email.js +++ b/web-ui/src/backup_account/backup_email/backup_email.js @@ -18,11 +18,13 @@ 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 SubmitButton from 'src/common/submit_button/submit_button'; +import InputField from 'src/common/input_field/input_field'; +import BackLink from 'src/common/back_link/back_link'; + import './backup_email.scss'; export class BackupEmail extends React.Component { @@ -40,7 +42,7 @@ export class BackupEmail extends React.Component { error: !emptyEmail && !validEmail ? t('backup-account.backup-email.error.invalid-email') : '', submitButtonDisabled: !validEmail || emptyEmail }); - } + }; submitHandler = (event) => { event.preventDefault(); @@ -54,8 +56,14 @@ export class BackupEmail extends React.Component { body: JSON.stringify({ csrftoken: [browser.getCookie('XSRF-TOKEN')] }) - }).then(() => this.props.onSubmit('success')); - } + }).then((response) => { + if (response.ok) { + this.props.onSubmit('success'); + } else { + this.props.onSubmit('error'); + } + }); + }; render() { const t = this.props.t; @@ -72,12 +80,10 @@ export class BackupEmail extends React.Component { <p>{t('backup-account.backup-email.paragraph2')}</p> <InputField name='email' label={t('backup-account.backup-email.input-label')} errorText={this.state.error} onChange={this.validateEmail} /> <SubmitButton buttonText={t('backup-account.backup-email.button')} disabled={this.state.submitButtonDisabled} /> - <div className='link-content'> - <a href='/' className='link'> - <i className='fa fa-angle-left' aria-hidden='true' /> - <span>{t('back-to-inbox')}</span> - </a> - </div> + <BackLink + href='/' + text={t('back-to-inbox')} + /> </form> </div> ); 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 48199738..65fad608 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 @@ -87,39 +87,61 @@ describe('BackupEmail', () => { describe('Submit', () => { let preventDefaultSpy; - beforeEach((done) => { - mockOnSubmit = expect.createSpy().andCall(() => done()); + beforeEach(() => { preventDefaultSpy = expect.createSpy(); - expect.spyOn(browser, 'getCookie').andReturn('abc123'); + }); - backupEmail = shallow(<BackupEmail t={mockTranslations} onSubmit={mockOnSubmit} />); + context('on success', () => { + beforeEach((done) => { + mockOnSubmit = expect.createSpy().andCall(() => done()); + expect.spyOn(browser, 'getCookie').andReturn('abc123'); - fetchMock.post('/backup-account', 204); - backupEmail.find('form').simulate('submit', { preventDefault: preventDefaultSpy }); - }); + fetchMock.post('/backup-account', 204); + backupEmail = shallow(<BackupEmail t={mockTranslations} onSubmit={mockOnSubmit} />); + 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('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 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 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('sends same origin headers', () => { + expect(fetchMock.lastOptions('/backup-account').credentials).toEqual('same-origin'); + }); + + it('prevents default call to refresh page', () => { + expect(preventDefaultSpy).toHaveBeenCalled(); + }); - it('prevents default call to refresh page', () => { - expect(preventDefaultSpy).toHaveBeenCalled(); + it('calls onSubmit from props with success', () => { + expect(mockOnSubmit).toHaveBeenCalledWith('success'); + }); }); - it('calls onSubmit from props when success', () => { - expect(mockOnSubmit).toHaveBeenCalledWith('success'); + context('on error', () => { + beforeEach((done) => { + mockOnSubmit = expect.createSpy().andCall(() => done()); + + fetchMock.post('/backup-account', 500); + backupEmail = shallow(<BackupEmail t={mockTranslations} onSubmit={mockOnSubmit} />); + backupEmail.find('form').simulate('submit', { preventDefault: preventDefaultSpy }); + }); + + it('calls onSubmit from props with error', () => { + expect(mockOnSubmit).toHaveBeenCalledWith('error'); + }); }); }); + + afterEach(() => { + fetchMock.restore(); + }); }); diff --git a/web-ui/src/backup_account/page.js b/web-ui/src/backup_account/page.js index 49e4b316..be3bae36 100644 --- a/web-ui/src/backup_account/page.js +++ b/web-ui/src/backup_account/page.js @@ -22,6 +22,7 @@ import Footer from 'src/common/footer/footer'; import Header from 'src/common/header/header'; import BackupEmail from 'src/backup_account/backup_email/backup_email'; import Confirmation from 'src/backup_account/confirmation/confirmation'; +import SnackbarNotification from 'src/common/snackbar_notification/snackbar_notification'; import 'font-awesome/scss/font-awesome.scss'; import './page.scss'; @@ -36,13 +37,20 @@ export class Page extends React.Component { saveBackupEmail = (status) => { this.setState({ status }); - } + }; mainContent = () => { if (this.state.status === 'success') return <Confirmation />; return <BackupEmail onSubmit={this.saveBackupEmail} />; }; + showSnackbarOnError = (t) => { + if (this.state.status === 'error') { + return <SnackbarNotification message={t('backup-account.error.submit-error')} isError />; + } + return undefined; // To satisfy eslint error - consistent-return + }; + render() { const t = this.props.t; return ( @@ -52,6 +60,7 @@ export class Page extends React.Component { <section> {this.mainContent()} </section> + {this.showSnackbarOnError(t)} <Footer /> </div> </DocumentTitle> diff --git a/web-ui/src/backup_account/page.scss b/web-ui/src/backup_account/page.scss index 71e3f074..d4f1f887 100644 --- a/web-ui/src/backup_account/page.scss +++ b/web-ui/src/backup_account/page.scss @@ -64,20 +64,6 @@ p { margin-bottom: 0.5em; } -.link { - color: $dark_blue; - font-style: italic; - font-size: 0.8em; - - .fa { - font-size: 1.6em; - position: relative; - top: 3px; - margin-right: 0.3em; - } - -} - @media only screen and (min-width : 500px) { body { font-size: 1.3em; diff --git a/web-ui/src/backup_account/page.spec.js b/web-ui/src/backup_account/page.spec.js index bd7bb884..2933a64e 100644 --- a/web-ui/src/backup_account/page.spec.js +++ b/web-ui/src/backup_account/page.spec.js @@ -4,6 +4,7 @@ import React from 'react'; import { Page } from 'src/backup_account/page'; import BackupEmail from 'src/backup_account/backup_email/backup_email'; import Confirmation from 'src/backup_account/confirmation/confirmation'; +import SnackbarNotification from 'src/common/snackbar_notification/snackbar_notification'; describe('BackupAccount', () => { let page; @@ -41,5 +42,29 @@ describe('BackupAccount', () => { pageInstance.saveBackupEmail('success'); expect(page.find(Confirmation).length).toEqual(1); }); + + context('on submit error', () => { + beforeEach(() => { + pageInstance.saveBackupEmail('error'); + }); + + it('returns snackbar component on error', () => { + const snackbar = pageInstance.showSnackbarOnError(pageInstance.props.t); + expect(snackbar).toEqual(<SnackbarNotification message='backup-account.error.submit-error' isError />); + }); + + it('returns nothing when there is no error', () => { + pageInstance.saveBackupEmail('success'); + const snackbar = pageInstance.showSnackbarOnError(pageInstance.props.t); + expect(snackbar).toEqual(undefined); + }); + + it('renders snackbar notification on error', () => { + const snackbar = page.find(SnackbarNotification); + expect(snackbar).toExist(); + expect(snackbar.props().message).toEqual('backup-account.error.submit-error'); + expect(snackbar.props().isError).toEqual(true); + }); + }); }); }); |