diff --git a/lms/static/js/financial-assistance/views/financial_assistance_form_view.js b/lms/static/js/financial-assistance/views/financial_assistance_form_view.js index 1cecdb4db7..276d719b6e 100644 --- a/lms/static/js/financial-assistance/views/financial_assistance_form_view.js +++ b/lms/static/js/financial-assistance/views/financial_assistance_form_view.js @@ -6,12 +6,13 @@ 'underscore', 'gettext', 'js/financial-assistance/models/financial_assistance_model', - 'text!js/financial-assistance/templates/financial_assessment_form.underscore', - 'text!js/financial-assistance/templates/financial_assessment_submitted.underscore', 'js/student_account/views/FormView', - 'text!templates/student_account/form_field.underscore' + 'text!../../../templates/financial-assistance/financial_assessment_form.underscore', + 'text!../../../templates/financial-assistance/financial_assessment_submitted.underscore', + 'text!templates/student_account/form_field.underscore', + 'string_utils' ], - function(Backbone, $, _, gettext, FinancialAssistanceModel, formViewTpl, successTpl, FormView, formFieldTpl) { + function(Backbone, $, _, gettext, FinancialAssistanceModel, FormView, formViewTpl, successTpl, formFieldTpl) { return FormView.extend({ el: '.financial-assistance-wrapper', events: { @@ -54,7 +55,7 @@ this.model.set( context.user_details ); this.listenTo( this.model, 'error', this.saveError ); this.model.on('sync', this.renderSuccess, this); - + // Build the form this.buildForm( fields ); }, diff --git a/lms/static/js/spec/financial-assistance/financial_assistance_form_view_spec.js b/lms/static/js/spec/financial-assistance/financial_assistance_form_view_spec.js index 9ec688e934..bb83e29476 100644 --- a/lms/static/js/spec/financial-assistance/financial_assistance_form_view_spec.js +++ b/lms/static/js/spec/financial-assistance/financial_assistance_form_view_spec.js @@ -1,30 +1,88 @@ define([ 'backbone', 'jquery', + 'js/financial-assistance/models/financial_assistance_model', 'js/financial-assistance/views/financial_assistance_form_view' - ], function (Backbone, $, FinancialAssistanceFormView) { + ], function (Backbone, $, FinancialAssistanceModel, FinancialAssistanceFormView) { 'use strict'; + /*jslint maxlen: 500 */ describe('Financial Assistance View', function () { var view = null, context = { - fields: [{ - defaultValue: '', - form: 'financial-assistance', - instructions: 'select a course', - label: 'Course', - name: 'course', - options: [ - {'name': 'Verified with Audit', 'value': 'course-v1:HCFA+VA101+2015'}, - {'name': 'Something Else', 'value': 'course-v1:SomethingX+SE101+215'}, - {'name': 'Test Course', 'value': 'course-v1:TestX+T101+2015'} - ], - placeholder: '', - required: true, - requiredStr: '', - type: 'select' - }], + fields: [ + { + defaultValue: '', + form: 'financial-assistance', + instructions: 'select a course', + label: 'Course', + name: 'course', + options: [ + {'name': 'Verified with Audit', 'value': 'course-v1:HCFA+VA101+2015'}, + {'name': 'Something Else', 'value': 'course-v1:SomethingX+SE101+215'}, + {'name': 'Test Course', 'value': 'course-v1:TestX+T101+2015'} + ], + placeholder: '', + required: true, + requiredStr: '', + type: 'select' + }, { + defaultValue: '', + instructions: 'Specify your annual income in USD.', + label: 'Annual Income', + name: 'income', + placeholder: 'income in USD ($)', + required: true, + restrictions: {}, + type: 'text' + }, { + defaultValue: '', + instructions: 'Use between 250 and 500 words or so in your response.', + label: 'Tell us about your current financial situation, including any unusual circumstances.', + name: 'reason_for_applying', + placeholder: '', + required: true, + restrictions: { + min_length: 800, + max_length: 2500 + }, + type: 'textarea' + }, { + defaultValue: '', + instructions: 'Use between 250 and 500 words or so in your response.', + label: 'Tell us about your learning or professional goals. How will a Verified Certificate in this course help you achieve these goals?', + name: 'goals', + placeholder: '', + required: true, + restrictions: { + min_length: 800, + max_length: 2500 + }, + type: 'textarea' + }, { + defaultValue: '', + instructions: 'Use between 250 and 500 words or so in your response.', + label: 'Tell us about your plans for this course. What steps will you take to help you complete the course work a receive a certificate?', + name: 'effort', + placeholder: '', + required: true, + restrictions: { + min_length: 800, + max_length: 2500 + }, + type: 'textarea' + }, { + defaultValue: '', + instructions: 'Annual income and personal information such as email address will not be shared.', + label: 'I allow edX to use the information provided in this application for edX marketing purposes.', + name: 'mktg-permission', + placeholder: '', + required: false, + restrictions: {}, + type: 'checkbox' + } + ], user_details: { country: 'UK', email: 'xsy@edx.org', @@ -36,10 +94,48 @@ define([ dashboard_url: '/dashboard', platform_name: 'edx', submit_url: '/api/financial/v1/assistance' - }; + }, + completeForm, + validSubmission, + successfulSubmission, + failedSubmission; + + completeForm = function() { + var options = context.fields[0].options, + selectValue = options[options.length - 1].value; + + view.$('#financial-assistance-course').val(selectValue); + view.$('#financial-assistance-income').val(1312); + view.$('textarea').html('w'.repeat(801)); + }; + + validSubmission = function() { + completeForm(); + view.$('.js-submit-form').click(); + expect(view.model.save).toHaveBeenCalled(); + }; + + successfulSubmission = function() { + expect(view.$('.js-success-message').length).toEqual(0); + validSubmission(); + view.model.trigger('sync'); + expect(view.$('.js-success-message').length).toEqual(1); + }; + + failedSubmission = function() { + expect(view.$('.js-success-message').length).toEqual(0); + expect(view.$('.submission-error')).toHaveClass('hidden'); + validSubmission(); + view.model.trigger('error', {status: 500}); + expect(view.$('.js-success-message').length).toEqual(0); + expect(view.$('.submission-error')).not.toHaveClass('hidden'); + }; beforeEach(function() { setFixtures('
'); + + spyOn(FinancialAssistanceModel.prototype, 'save'); + view = new FinancialAssistanceFormView({ el: '.financial-assistance-wrapper', context: context @@ -54,6 +150,45 @@ define([ it('should exist', function() { expect(view).toBeDefined(); }); + + it('should load the form based on passed in context', function() { + var $form = view.$('.financial-assistance-form'); + + expect($form.find('select').attr('name')).toEqual(context.fields[0].name); + expect($form.find('input[type=text]').first().attr('name')).toEqual(context.fields[1].name); + expect($form.find('textarea').first().attr('name')).toEqual(context.fields[2].name); + expect($form.find('input[type=checkbox]').attr('name')).toEqual(context.fields[5].name); + }); + + it('should not submit the form if the front end validation fails', function() { + expect(view.$('.submission-error')).toHaveClass('hidden'); + view.$('.js-submit-form').click(); + expect(view.model.save).not.toHaveBeenCalled(); + expect(view.$('.submission-error')).not.toHaveClass('hidden'); + }); + + it('should submit the form data and additional data if validation passes', function() { + validSubmission(); + }); + + it('should submit the form and show a success message if content is valid and API returns success', function() { + successfulSubmission(); + }); + + it('should submit the form and show an error message if content is valid and API returns error', function() { + failedSubmission(); + }); + + it('should allow form resubmission after a front end validation failure', function() { + view.$('#financial-assistance-income').val(1312); + expect(view.model.save).not.toHaveBeenCalled(); + validSubmission(); + }); + + it('should allow form resubmission after an API error is returned', function() { + failedSubmission(); + successfulSubmission(); + }); }); } ); diff --git a/lms/static/js/spec/main.js b/lms/static/js/spec/main.js index a94e006ce6..6f372fd588 100644 --- a/lms/static/js/spec/main.js +++ b/lms/static/js/spec/main.js @@ -728,7 +728,8 @@ 'lms/include/teams/js/spec/views/topic_card_spec.js', 'lms/include/teams/js/spec/views/topic_teams_spec.js', 'lms/include/teams/js/spec/views/topics_spec.js', - 'lms/include/teams/js/spec/views/team_profile_header_actions_spec.js' + 'lms/include/teams/js/spec/views/team_profile_header_actions_spec.js', + 'lms/include/js/spec/financial-assistance/financial_assistance_form_view_spec.js' ]); }).call(this, requirejs, define); diff --git a/lms/static/js_test.yml b/lms/static/js_test.yml index a2ee74ff77..7b84a1766e 100644 --- a/lms/static/js_test.yml +++ b/lms/static/js_test.yml @@ -106,6 +106,7 @@ fixture_paths: - templates/components/header - templates/components/tabbed - templates/components/card + - templates/financial-assistance/ - js/fixtures/edxnotes - js/fixtures/search - templates/search diff --git a/lms/static/js/financial-assistance/templates/financial_assessment_form.underscore b/lms/templates/financial-assistance/financial_assessment_form.underscore similarity index 100% rename from lms/static/js/financial-assistance/templates/financial_assessment_form.underscore rename to lms/templates/financial-assistance/financial_assessment_form.underscore diff --git a/lms/static/js/financial-assistance/templates/financial_assessment_submitted.underscore b/lms/templates/financial-assistance/financial_assessment_submitted.underscore similarity index 100% rename from lms/static/js/financial-assistance/templates/financial_assessment_submitted.underscore rename to lms/templates/financial-assistance/financial_assessment_submitted.underscore