diff --git a/client/src/app-components/__tests__/password-recovery-test.js b/client/src/app-components/__tests__/password-recovery-test.js new file mode 100644 index 00000000..906a2624 --- /dev/null +++ b/client/src/app-components/__tests__/password-recovery-test.js @@ -0,0 +1,91 @@ +const APICallMock = require('lib-app/__mocks__/api-call-mock'); + +const SubmitButton = ReactMock(); +const Button = ReactMock(); +const Input = ReactMock(); +const Form = ReactMock(); +const Checkbox = ReactMock(); +const Message = ReactMock(); +const FormField = ReactMock(); +const Widget = ReactMock(); + +const PasswordRecovery = requireUnit('app-components/password-recovery', { + 'lib-app/api-call': APICallMock, + 'core-components/submit-button': SubmitButton, + 'core-components/button': Button, + 'core-components/form-field': FormField, + 'core-components/': FormField, + 'core-components/form': Form, + 'core-components/checkbox': Checkbox, + 'core-components/message': Message, + 'core-components/widget': Widget, +}); + +describe('PasswordRecovery component', function () { + let recoverWidget, recoverForm, widgetTransition, emailInput, component, + backToLoginButton, submitButton; + + let dispatch = stub(); + + beforeEach(function () { + component = TestUtils.renderIntoDocument( + + ); + recoverWidget = TestUtils.scryRenderedComponentsWithType(component, Widget)[0]; + recoverForm = TestUtils.scryRenderedComponentsWithType(component, Form)[0]; + emailInput = TestUtils.scryRenderedComponentsWithType(component, Input)[0]; + submitButton = TestUtils.scryRenderedComponentsWithType(component, SubmitButton)[0]; + backToLoginButton = TestUtils.scryRenderedComponentsWithType(component, Button)[0]; + }); + + it('should control form errors by prop', function () { + expect(recoverForm.props.errors).to.deep.equal({}); + recoverForm.props.onValidateErrors({email: 'MOCK_ERROR'}); + expect(recoverForm.props.errors).to.deep.equal({email: 'MOCK_ERROR'}); + }); + + it('should call sendRecoverPassword when submitted', function () { + let mockSubmitData = {email: 'MOCK_VALUE'}; + APICallMock.call.reset(); + + recoverForm.props.onSubmit(mockSubmitData); + expect(APICallMock.call).to.have.been.calledWith({ + path: '/user/send-recover-password', + data: mockSubmitData + }); + }); + + it('should set loading true in the form when submitted', function () { + let mockSubmitData = {email: 'MOCK_VALUE'}; + + recoverForm.props.onSubmit(mockSubmitData); + expect(recoverForm.props.loading).to.equal(true); + }); + + it('should add error and stop loading when send recover fails', function () { + component.refs.recoverForm.refs.email.focus.reset(); + + component.onRecoverPasswordFail(); + expect(recoverForm.props.errors).to.deep.equal({email: 'EMAIL_NOT_EXIST'}); + expect(recoverForm.props.loading).to.equal(false); + expect(component.refs.recoverForm.refs.email.focus).to.have.been.called; + }); + + it('should show message when send recover success', function () { + let message = TestUtils.scryRenderedComponentsWithType(component, Message)[0]; + expect(message).to.equal(undefined); + + component.onRecoverPasswordSent(); + message = TestUtils.scryRenderedComponentsWithType(component, Message)[0]; + + expect(recoverForm.props.loading).to.equal(false); + expect(message).to.not.equal(null); + expect(message.props.type).to.equal('info'); + expect(message.props.children).to.equal('RECOVER_SENT'); + }); + + it('should show front side if \'Back to login form\' link is clicked', function () { + backToLoginButton.props.onClick(); + expect(widgetTransition.props.sideToShow).to.equal('front'); + }); +}); diff --git a/client/src/app-components/password-recovery.js b/client/src/app-components/password-recovery.js index 4541a5fc..e3c61fcc 100644 --- a/client/src/app-components/password-recovery.js +++ b/client/src/app-components/password-recovery.js @@ -2,7 +2,7 @@ import React from 'react'; import classNames from 'classnames'; import i18n from 'lib-app/i18n'; -import API from 'lib-app/api-call'; +import API from 'lib-app/api-call'; import Form from 'core-components/form'; import FormField from 'core-components/form-field'; @@ -12,7 +12,7 @@ import SubmitButton from 'core-components/submit-button'; import Message from 'core-components/message'; class PasswordRecovery extends React.Component { - + static propTypes = { recoverSent: React.PropTypes.bool, formProps: React.PropTypes.object, diff --git a/client/src/app-components/ticket-viewer.js b/client/src/app-components/ticket-viewer.js index 10d62c24..3837aa90 100644 --- a/client/src/app-components/ticket-viewer.js +++ b/client/src/app-components/ticket-viewer.js @@ -111,7 +111,7 @@ class TicketViewer extends React.Component {
{ticket.closed ? - : i18n('OPENED')}
@@ -282,13 +282,27 @@ class TicketViewer extends React.Component { }).then(this.onTicketModification.bind(this)); } - onCloseClick() { - AreYouSure.openModal(null, this.toggleClose.bind(this)); + onReopenClick() { + AreYouSure.openModal(null, this.reopenTicket.bind(this)); } - toggleClose() { + onCloseTicketClick(event) { + event.preventDefault(); + AreYouSure.openModal(null, this.closeTicket.bind(this)); + } + + reopenTicket() { API.call({ - path: (this.props.ticket.closed) ? '/ticket/re-open' : '/ticket/close', + path: '/ticket/re-open', + data: { + ticketNumber: this.props.ticket.ticketNumber + } + }).then(this.onTicketModification.bind(this)); + } + + closeTicket() { + API.call({ + path: '/ticket/close', data: { ticketNumber: this.props.ticket.ticketNumber } @@ -373,15 +387,6 @@ class TicketViewer extends React.Component { this.props.onChange(); } } - onCloseTicketClick(event){ - event.preventDefault(); - API.call({ - path: '/ticket/close', - data: { - ticketNumber: this.props.ticket.ticketNumber - } - }).then(this.onTicketModification.bind(this)); - } } export default connect((store) => { diff --git a/client/src/app/main/main-home/__tests__/main-home-page-login-widget-test.js b/client/src/app/main/main-home/__tests__/main-home-page-login-widget-test.js index 9738a3f6..abe001d5 100644 --- a/client/src/app/main/main-home/__tests__/main-home-page-login-widget-test.js +++ b/client/src/app/main/main-home/__tests__/main-home-page-login-widget-test.js @@ -9,11 +9,13 @@ const Checkbox = ReactMock(); const Message = ReactMock(); const Widget = ReactMock(); const WidgetTransition = ReactMock(); +const PasswordRecovery = ReactMock(); const MainHomePageLoginWidget = requireUnit('app/main/main-home/main-home-page-login-widget', { 'react-redux': ReduxMock, 'actions/session-actions': SessionActionsMock, 'lib-app/api-call': APICallMock, + 'app-components/password-recovery': PasswordRecovery, 'core-components/submit-button': SubmitButton, 'core-components/button': Button, 'core-components/input': Input, @@ -98,7 +100,7 @@ describe('Login/Recover Widget', function () { expect(loginForm.props.errors).to.deep.equal({password: 'ERROR_PASSWORD'}); expect(loginForm.props.loading).to.equal(false); }); - + it('should show back side if \'Forgot your password?\' link is clicked', function () { expect(widgetTransition.props.sideToShow).to.equal('front'); forgotPasswordButton.props.onClick(); @@ -107,8 +109,7 @@ describe('Login/Recover Widget', function () { }); describe('Recover Password form', function () { - let recoverWidget, recoverForm, widgetTransition, emailInput, component, - backToLoginButton, submitButton; + let recoverPassword, widgetTransition, component; let dispatch = stub(); @@ -117,32 +118,20 @@ describe('Login/Recover Widget', function () { ); widgetTransition = TestUtils.scryRenderedComponentsWithType(component, WidgetTransition)[0]; - recoverWidget = TestUtils.scryRenderedComponentsWithType(component, Widget)[1]; - recoverForm = TestUtils.scryRenderedComponentsWithType(component, Form)[1]; - emailInput = TestUtils.scryRenderedComponentsWithType(component, Input)[2]; - submitButton = TestUtils.scryRenderedComponentsWithType(component, SubmitButton)[1]; - backToLoginButton = TestUtils.scryRenderedComponentsWithType(component, Button)[1]; - - component.refs.recoverForm = { - refs: { - email: { - focus: stub() - } - } - }; + recoverPassword = TestUtils.scryRenderedComponentsWithType(component, PasswordRecovery)[0]; }); it('should control form errors by prop', function () { - expect(recoverForm.props.errors).to.deep.equal({}); - recoverForm.props.onValidateErrors({email: 'MOCK_ERROR'}); - expect(recoverForm.props.errors).to.deep.equal({email: 'MOCK_ERROR'}); + expect(recoverPassword.props.formProps.errors).to.deep.equal({}); + recoverPassword.props.formProps.onValidateErrors({email: 'MOCK_ERROR'}); + expect(recoverPassword.props.formProps.errors).to.deep.equal({email: 'MOCK_ERROR'}); }); it('should call sendRecoverPassword when submitted', function () { let mockSubmitData = {email: 'MOCK_VALUE'}; APICallMock.call.reset(); - recoverForm.props.onSubmit(mockSubmitData); + recoverPassword.props.formProps.onSubmit(mockSubmitData); expect(APICallMock.call).to.have.been.calledWith({ path: '/user/send-recover-password', data: mockSubmitData @@ -152,12 +141,12 @@ describe('Login/Recover Widget', function () { it('should set loading true in the form when submitted', function () { let mockSubmitData = {email: 'MOCK_VALUE'}; - recoverForm.props.onSubmit(mockSubmitData); - expect(recoverForm.props.loading).to.equal(true); + recoverPassword.props.formProps.onSubmit(mockSubmitData); + expect(recoverForm.props.formProps.loading).to.equal(true); }); it('should add error and stop loading when send recover fails', function () { - component.refs.recoverForm.refs.email.focus.reset(); + component.refs.recoverPassword.refs.email.focus.reset(); component.onRecoverPasswordFail(); expect(recoverForm.props.errors).to.deep.equal({email: 'EMAIL_NOT_EXIST'}); @@ -183,4 +172,4 @@ describe('Login/Recover Widget', function () { expect(widgetTransition.props.sideToShow).to.equal('front'); }); }); -}); \ No newline at end of file +}); diff --git a/client/src/app/main/main-home/main-home-page-login-widget.js b/client/src/app/main/main-home/main-home-page-login-widget.js index 2a56aba0..e2e77b18 100644 --- a/client/src/app/main/main-home/main-home-page-login-widget.js +++ b/client/src/app/main/main-home/main-home-page-login-widget.js @@ -9,7 +9,7 @@ import API from 'lib-app/api-call'; import focus from 'lib-core/focus'; import i18n from 'lib-app/i18n'; -import PasswordRecovery from 'app-components/password-recovery.js'; +import PasswordRecovery from 'app-components/password-recovery'; import SubmitButton from 'core-components/submit-button'; import Button from 'core-components/button'; import Form from 'core-components/form'; diff --git a/client/src/lib-test/preprocessor.js b/client/src/lib-test/preprocessor.js index e3a1e44d..1904b33c 100644 --- a/client/src/lib-test/preprocessor.js +++ b/client/src/lib-test/preprocessor.js @@ -23,18 +23,19 @@ global.requireUnit = function (path, mocks) { }; global.reRenderIntoDocument = (function () { let div; - + return function (jsx) { if (!div) { div = document.createElement('div') } - + return ReactDOM.render(jsx, div); } })(); global.ReduxMock = { connect: stub().returns(stub().returnsArg(0)) }; +global.globalIndexPath = ''; Array.prototype.swap = function (x,y) { var b = this[x];