diff --git a/lms/djangoapps/verify_student/tests/test_views.py b/lms/djangoapps/verify_student/tests/test_views.py index 6883eb01d8..c7cf5b13dc 100644 --- a/lms/djangoapps/verify_student/tests/test_views.py +++ b/lms/djangoapps/verify_student/tests/test_views.py @@ -1473,6 +1473,31 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): PayAndVerifyView.WEBCAM_REQ, ]) + def test_no_contribution(self): + # Do NOT specify a contribution for the course in a session var. + course = self._create_course("verified") + response = self._get_page("verify_student_start_flow", course.id) + self._assert_contribution_amount(response, "") + + def test_contribution_other_course(self): + # Specify a contribution amount for another course in the session + course = self._create_course("verified") + other_course_id = CourseLocator(org="other", run="test", course="test") + self._set_contribution("12.34", other_course_id) + + # Expect that the contribution amount is NOT pre-filled, + response = self._get_page("verify_student_start_flow", course.id) + self._assert_contribution_amount(response, "") + + def test_contribution(self): + # Specify a contribution amount for this course in the session + course = self._create_course("verified") + self._set_contribution("12.34", course.id) + + # Expect that the contribution amount is pre-filled, + response = self._get_page("verify_student_start_flow", course.id) + self._assert_contribution_amount(response, "12.34") + def _create_course(self, *course_modes, **kwargs): """Create a new course with the specified course modes. """ course = CourseFactory.create() @@ -1524,6 +1549,14 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): attempt.created_at = datetime.now(pytz.UTC) - timedelta(days=(days_good_for + 1)) attempt.save() + def _set_contribution(self, amount, course_id): + """Set the contribution amount pre-filled in a session var. """ + session = self.client.session + session["donation_for_course"] = { + unicode(course_id): amount + } + session.save() + def _get_page(self, url_name, course_key, expected_status_code=200, skip_first_step=False): """Retrieve one of the verification pages. """ url = reverse(url_name, kwargs={"course_id": unicode(course_key)}) @@ -1576,6 +1609,11 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): response_dict = self._get_page_data(response) self.assertEqual(response_dict['full_name'], full_name) + def _assert_contribution_amount(self, response, expected_amount): + """Check the pre-filled contribution amount. """ + response_dict = self._get_page_data(response) + self.assertEqual(response_dict['contribution_amount'], expected_amount) + def _get_page_data(self, response): """Retrieve the data attributes rendered on the page. """ soup = BeautifulSoup(response.content) @@ -1591,7 +1629,8 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): 'display_steps': json.loads(pay_and_verify_div['data-display-steps']), 'current_step': pay_and_verify_div['data-current-step'], 'requirements': json.loads(pay_and_verify_div['data-requirements']), - 'message_key': pay_and_verify_div['data-msg-key'] + 'message_key': pay_and_verify_div['data-msg-key'], + 'contribution_amount': pay_and_verify_div['data-contribution-amount'] } def _assert_redirects_to_dashboard(self, response): diff --git a/lms/djangoapps/verify_student/views.py b/lms/djangoapps/verify_student/views.py index 350935f1da..74f86f0635 100644 --- a/lms/djangoapps/verify_student/views.py +++ b/lms/djangoapps/verify_student/views.py @@ -483,6 +483,12 @@ class PayAndVerifyView(View): else "" ) + # If the user set a contribution amount on another page, + # use that amount to pre-fill the price selection form. + contribution_amount = request.session.get( + 'donation_for_course', {} + ).get(unicode(course_key), '') + # Render the top-level page context = { 'user_full_name': full_name, @@ -493,6 +499,7 @@ class PayAndVerifyView(View): 'current_step': current_step, 'disable_courseware_js': True, 'display_steps': display_steps, + 'contribution_amount': contribution_amount, 'is_active': request.user.is_active, 'messages': self._messages( message, diff --git a/lms/static/js/verify_student/pay_and_verify.js b/lms/static/js/verify_student/pay_and_verify.js index 39e1674b7d..4911af7850 100644 --- a/lms/static/js/verify_student/pay_and_verify.js +++ b/lms/static/js/verify_student/pay_and_verify.js @@ -48,6 +48,7 @@ var edx = edx || {}; courseKey: el.data('course-key'), minPrice: el.data('course-mode-min-price'), suggestedPrices: (el.data('course-mode-suggested-prices') || "").split(","), + contributionAmount: el.data('contribution-amount'), currency: el.data('course-mode-currency'), purchaseEndpoint: el.data('purchase-endpoint') }, diff --git a/lms/static/js/verify_student/views/make_payment_step_view.js b/lms/static/js/verify_student/views/make_payment_step_view.js index d5b59fd726..e0d498db41 100644 --- a/lms/static/js/verify_student/views/make_payment_step_view.js +++ b/lms/static/js/verify_student/views/make_payment_step_view.js @@ -17,6 +17,12 @@ var edx = edx || {}; requirements: this.stepData.requirements }).render(); + // Update the contribution amount with the amount the user + // selected in a previous screen. + if ( this.stepData.contributionAmount ) { + this.selectPaymentAmount( this.stepData.contributionAmount ); + } + // Enable the payment button once an amount is chosen $( "input[name='contribution']" ).on( 'click', _.bind( this.enablePaymentButton, this ) ); @@ -110,6 +116,31 @@ var edx = edx || {}; } else { return contributionInput.val(); } + }, + + selectPaymentAmount: function( amount ) { + var amountFloat = parseFloat( amount ), + foundPrice; + + // Check if we have a suggested price that matches the amount + foundPrice = _.find( + this.stepData.suggestedPrices, + function( price ) { + return parseFloat( price ) === amountFloat; + } + ); + + // If we've found an option for the price, select it. + if ( foundPrice ) { + $( '#contribution-' + foundPrice, this.el ).prop( 'checked', true ); + } else { + // Otherwise, enter the value into the text box + $( '#contribution-other-amt', this.el ).val( amount ); + $( '#contribution-other', this.el ).prop( 'checked', true ); + } + + // In either case, enable the payment button + this.enablePaymentButton(); } }); diff --git a/lms/templates/verify_student/pay_and_verify.html b/lms/templates/verify_student/pay_and_verify.html index c4f1550497..87afeea5e1 100644 --- a/lms/templates/verify_student/pay_and_verify.html +++ b/lms/templates/verify_student/pay_and_verify.html @@ -65,6 +65,7 @@ from verify_student.views import PayAndVerifyView data-course-mode-min-price='${course_mode.min_price}' data-course-mode-suggested-prices='${course_mode.suggested_prices}' data-course-mode-currency='${course_mode.currency}' + data-contribution-amount='${contribution_amount}' data-purchase-endpoint='${purchase_endpoint}' data-display-steps='${json.dumps(display_steps)}' data-current-step='${current_step}'