Skip to content

Commit

Permalink
Merge pull request #61 from edx/fsheets/EDUCATOR-1828
Browse files Browse the repository at this point in the history
Accessibility Policy Form
  • Loading branch information
Eric Fischer authored Dec 8, 2017
2 parents 68b0885 + f716129 commit dca0235
Show file tree
Hide file tree
Showing 16 changed files with 685 additions and 73 deletions.
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"license": "AGPL-3.0",
"dependencies": {
"@edx/edx-bootstrap": "^0.4.0",
"@edx/paragon": "^1.3.0",
"@edx/paragon": "^1.4.5",
"babel-polyfill": "^6.26.0",
"classnames": "^2.2.5",
"copy-to-clipboard": "^3.0.8",
Expand Down Expand Up @@ -44,24 +44,28 @@
"enzyme-adapter-react-16": "^1.0.4",
"eslint-config-edx": "4.0.0",
"extract-text-webpack-plugin": "^3.0.0",
"fetch-mock": "^5.13.1",
"file-loader": "^1.1.4",
"html-webpack-harddisk-plugin": "^0.1.0",
"html-webpack-plugin": "^2.30.1",
"husky": "^0.14.3",
"identity-obj-proxy": "^3.0.0",
"jest": "^21.2.1",
"fetch-mock": "^5.13.1",
"node-sass": "^4.5.3",
"react-dev-utils": "^4.0.0",
"react-test-renderer": "^16.1.0",
"redux-mock-store": "^1.3.0",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.2",
"webpack": "^3.5.5",
"webpack-dev-server": "^2.7.1",
"webpack-merge": "^4.1.0"
},
"jest": {
"setupFiles": ["./shim.js", "./setupTests.js"],
"setupFiles": [
"./shim.js",
"./setupTests.js"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|scss)$": "identity-obj-proxy"
Expand Down
7 changes: 0 additions & 7 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@
revision: "",
base_url: "http://localhost:18010",
},
zendesk: {
zendeskTags: "",
customFields: {
course_id: "course-v1:edX+DemoX+Demo_Course",
},
accessToken: "accessToken",
},
};
</script>
<div id="root"></div>
Expand Down
2 changes: 1 addition & 1 deletion src/SFE.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/* The page-header class exists in bootstrap 3.3 but not in our alpha version currently */
.page-header {
padding-bottom: $spacer * 0.5;
padding-bottom: $spacer * 0.5;
margin: ($spacer * 2) 0 $spacer;
border-bottom: 1px solid #eee;
}
8 changes: 6 additions & 2 deletions src/accessibilityIndex.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';

import WrappedAccessibilityPolicyPage from './components/AccessibilityPolicyPage';
import AccessibilityPolicyPage from './components/AccessibilityPolicyPage';
import store from './data/store';

const AccessibilityApp = () => (
<Provider store={store}>
<div>
<WrappedAccessibilityPolicyPage />
<AccessibilityPolicyPage
communityAccessibilityLink="https://www.edx.org/accessibility"
phoneNumber="+1 617-258-6577"
email="[email protected]"
/>
</div>
</Provider>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@import '../../SFE.scss';

.list {
margin-left: $spacer * 2;
}

.form-section {
padding: 0 $spacer $spacer;
font-size: $font-size-base;

// set label and validation text to be larger in Studio
div, label {
font-size: $font-size-base;
}
}

.bullet-list {
@extend .list;
list-style-type: disc;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import React from 'react';
import Enzyme from 'enzyme';
import { AccessibilityPolicyForm } from './index';
import { accessibilityActions } from '../../data/constants/actionTypes';

const mount = Enzyme.mount;

const defaultProps = {
accessibilityStatus: {},
accessibilityEmail: '[email protected]',
clearAccessibilityStatus: () => {},
submitAccessibilityForm: () => {},
};

const formInputs = {
email: '[email protected]',
fullName: 'test name',
message: 'feedback message',
};

const validationMessages = {
email: 'Valid email required.',
fullName: 'Full name required.',
message: 'Message required.',
};

const clearStatus = (wrapper) => {
wrapper.setProps({ accessibilityStatus: {} });
};

const getMockForZendeskSuccess = (wrapper) => {
wrapper.setProps({
accessibilityStatus: {
type: accessibilityActions.ACCESSIBILITY_FORM_SUBMIT_SUCCESS,
},
});
};

const getMockForZendeskRateLimit = (wrapper) => {
wrapper.setProps({
accessibilityStatus: {
type: accessibilityActions.ACCESSIBILITY_FORM_SUBMIT_RATE_LIMIT_FAILURE,
},
});
};

let wrapper;

describe('<AccessibilityPolicyForm />', () => {
describe('renders', () => {
beforeEach(() => {
wrapper = mount(
<AccessibilityPolicyForm
{...defaultProps}
/>,
);
});

it('correct number of form fields', () => {
const formSection = wrapper.find('section');
expect(formSection.find('input')).toHaveLength(2);
expect(formSection.find('textarea')).toHaveLength(1);
expect(formSection.find('button')).toHaveLength(1);
});

it('hides StatusAlert on initial load', () => {
const statusAlert = wrapper.find('StatusAlert');
expect(statusAlert.find('div').first().prop('hidden')).toEqual(true);
});

it('adds validation checking on each input field', () => {
const emailInput = wrapper.find('input#email');
emailInput.simulate('blur');

const emailError = wrapper.find('div#error-email');
expect(emailError.exists()).toEqual(true);
expect(emailError.text()).toEqual(validationMessages.email);

const fullNameInput = wrapper.find('input#fullName');
fullNameInput.simulate('blur');

const fullNameError = wrapper.find('div#error-fullName');
expect(fullNameError.exists()).toEqual(true);
expect(fullNameError.text()).toEqual(validationMessages.fullName);

const messageInput = wrapper.find('textarea#message');
messageInput.simulate('blur');

const messageError = wrapper.find('div#error-message');
expect(messageError.exists()).toEqual(true);
expect(messageError.text()).toEqual(validationMessages.message);
});

it('shows validation errors when trying to submit with empty fields', () => {
const formSection = wrapper.find('section');
const submitButton = formSection.find('button');
submitButton.simulate('click');

const statusAlert = wrapper.find('StatusAlert');
expect(statusAlert.find('div').first().prop('hidden')).toEqual(false);
expect(statusAlert.find('div').first().hasClass('alert-danger')).toEqual(true);
expect(statusAlert.text()).toContain(`Please fill in all required fields.${validationMessages.email}${validationMessages.fullName}${validationMessages.message}`);
});

it('shows correct success message', () => {
wrapper.setProps({
clearAccessibilityStatus: () => clearStatus(wrapper),
submitAccessibilityForm: () => getMockForZendeskSuccess(wrapper),
});
wrapper.setState({
submitterEmail: '[email protected]',
submitterFullName: 'test name',
submitterMessage: 'feedback message',
});

const formSection = wrapper.find('section');
const submitButton = formSection.find('button');
submitButton.simulate('click');

const statusAlert = wrapper.find('StatusAlert');
const statusAlertType = statusAlert.prop('alertType');
expect(statusAlertType).toEqual('success');
expect(statusAlert.find('div').first().hasClass('alert-success')).toEqual(true);
expect(statusAlert.text()).toContain('Thank you for contacting edX!Thank you for your feedback regarding the accessibility of Studio. We typically respond within one business day (Monday to Friday, 13:00 to 21:00 UTC).');
});

it('shows correct rate limiting message', () => {
wrapper.setProps({
clearAccessibilityStatus: () => clearStatus(wrapper),
submitAccessibilityForm: () => getMockForZendeskRateLimit(wrapper),
});
wrapper.setState({
submitterEmail: formInputs.email,
submitterFullName: formInputs.fullName,
submitterMessage: formInputs.message,
});

const formSection = wrapper.find('section');
const submitButton = formSection.find('button');
submitButton.simulate('click');

const statusAlert = wrapper.find('StatusAlert');
const statusAlertType = statusAlert.prop('alertType');
expect(statusAlertType).toEqual('danger');
expect(statusAlert.find('div').first().hasClass('alert-danger')).toEqual(true);
expect(statusAlert.text()).toContain(`We are currently experiencing high volume. Try again later today or send an email message to ${wrapper.props().accessibilityEmail}`);
});

it('clears inputs on valid submit', () => {
const formSection = wrapper.find('section');
const emailInput = wrapper.find('input#email');
const fullNameInput = wrapper.find('input#fullName');
const messageInput = wrapper.find('textarea#message');

wrapper.setState({
submitterEmail: formInputs.email,
submitterFullName: formInputs.fullName,
submitterMessage: formInputs.message,
});

const submitButton = formSection.find('button');
submitButton.simulate('click');

expect(emailInput.instance().value).toEqual('');
expect(fullNameInput.instance().value).toEqual('');
expect(messageInput.instance().value).toEqual('');
});

it('clears accessibilityStatus as expected', () => {
wrapper.setProps({
accessibilityStatus: {
type: accessibilityActions.ACCESSIBILITY_FORM_SUBMIT_SUCCESS,
},
clearAccessibilityStatus: () => clearStatus(wrapper),
});

const formSection = wrapper.find('section');
const submitButton = formSection.find('button');
submitButton.simulate('click');
expect(wrapper.props().accessibilityStatus).toEqual({});
});
});
});
Loading

0 comments on commit dca0235

Please sign in to comment.