(function(define) { 'use strict'; define([ 'jquery', 'jquery.url', 'utility', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'js/student_account/views/FinishAuthView', 'js/student_account/enrollment', 'js/student_account/shoppingcart', 'js/student_account/emailoptin' ], function($, url, utility, AjaxHelpers, FinishAuthView, EnrollmentInterface, ShoppingCartInterface, EmailOptInInterface) { describe('FinishAuthView', function() { var requests = null, view = null, FORWARD_URL = '/courseware/next', COURSE_KEY = 'course-v1:edX+test+15'; var ajaxSpyAndInitialize = function(that) { // Spy on AJAX requests requests = AjaxHelpers.requests(that); // Initialize the access view view = new FinishAuthView({}); // Mock the redirect call spyOn(view, 'redirect').and.callFake(function() {}); // Mock the enrollment and shopping cart interfaces spyOn(EnrollmentInterface, 'enroll').and.callFake(function() {}); spyOn(ShoppingCartInterface, 'addCourseToCart').and.callFake(function() {}); spyOn(EmailOptInInterface, 'setPreference') .and.callFake(function() { return {'always': function(r) { r(); }}; }); view.render(); }; /** * Simulate query string params. * * @param {object} params Parameters to set, each of which * should be prefixed with '?' */ var setFakeQueryParams = function(params) { spyOn($, 'url').and.callFake(function(requestedParam) { if (params.hasOwnProperty(requestedParam)) { return params[requestedParam]; } }); }; beforeEach(function() { // Stub analytics tracking window.analytics = jasmine.createSpyObj('analytics', ['track', 'page', 'pageview', 'trackLink']); }); it('saves the email opt-in preference before enrollment', function() { // Simulate providing enrollment query string params setFakeQueryParams({ '?enrollment_action': 'enroll', '?course_id': COURSE_KEY, '?email_opt_in': 'true' }); ajaxSpyAndInitialize(this); // Expect that the view tried to save the email opt in preference expect(EmailOptInInterface.setPreference).toHaveBeenCalledWith( COURSE_KEY, 'true' ); // Expect that the view tried to enroll the student expect(EnrollmentInterface.enroll).toHaveBeenCalledWith( COURSE_KEY, '/course_modes/choose/' + COURSE_KEY + '/' ); }); it('enrolls the user on auth complete', function() { // Simulate providing enrollment query string params setFakeQueryParams({ '?enrollment_action': 'enroll', '?course_id': COURSE_KEY }); ajaxSpyAndInitialize(this); // Expect that the view tried to enroll the student expect(EnrollmentInterface.enroll).toHaveBeenCalledWith( COURSE_KEY, '/course_modes/choose/' + COURSE_KEY + '/' ); }); it('sends the user to the course mode selection flow with bulk purchase workflow', function() { // Simulate providing enrollment query string params setFakeQueryParams({ '?enrollment_action': 'enroll', '?course_id': COURSE_KEY, '?purchase_workflow': 'bulk' }); ajaxSpyAndInitialize(this); // Expect that the view redirected to the course // mode select flow with the purchase_workflow parameter expect(EnrollmentInterface.enroll).toHaveBeenCalledWith( COURSE_KEY, '/course_modes/choose/' + COURSE_KEY + '/?purchase_workflow=bulk' ); }); it('sends the user to the payment flow for a paid course mode', function() { // Simulate providing enrollment query string params // AND specifying a course mode. setFakeQueryParams({ '?enrollment_action': 'enroll', '?course_id': COURSE_KEY, '?course_mode': 'verified' }); ajaxSpyAndInitialize(this); // Expect that the view tried to auto-enroll the student // with a redirect into the payment flow. expect(EnrollmentInterface.enroll).toHaveBeenCalledWith( COURSE_KEY, '/verify_student/start-flow/' + COURSE_KEY + '/' ); }); it('sends the user to the payment flow for a paid course mode with bulk purchase workflow', function() { // Simulate providing enrollment query string params // AND specifying a course mode // AND purchase workflow type. setFakeQueryParams({ '?enrollment_action': 'enroll', '?course_id': COURSE_KEY, '?course_mode': 'professional-no-id', '?purchase_workflow': 'bulk' }); ajaxSpyAndInitialize(this); // Expect that the view tried to auto-enroll the student // with a redirect into the payment flow including the // purchase_workflow parameter. expect(EnrollmentInterface.enroll).toHaveBeenCalledWith( COURSE_KEY, '/verify_student/start-flow/' + COURSE_KEY + '/?purchase_workflow=bulk' ); }); it('sends the user to the student dashboard for an unpaid course mode', function() { // Simulate providing enrollment query string params // AND specifying a course mode. setFakeQueryParams({ '?enrollment_action': 'enroll', '?course_id': COURSE_KEY, '?course_mode': 'audit' }); ajaxSpyAndInitialize(this); // Expect that the view tried auto-enrolled the student // and sent the student to the dashboard // (skipping the payment flow). expect(EnrollmentInterface.enroll).toHaveBeenCalledWith(COURSE_KEY, '/dashboard'); }); it('adds a white-label course to the shopping cart on auth complete', function() { // Simulate providing "add to cart" query string params setFakeQueryParams({ '?enrollment_action': 'add_to_cart', '?course_id': COURSE_KEY }); ajaxSpyAndInitialize(this); // Expect that the view tried to add the course to the user's shopping cart expect(ShoppingCartInterface.addCourseToCart).toHaveBeenCalledWith(COURSE_KEY); }); it('redirects the user to the dashboard if no course is provided', function() { ajaxSpyAndInitialize(this); // Since we did not provide a ?next query param, expect a redirect to the dashboard. expect(view.redirect).toHaveBeenCalledWith('/dashboard'); }); it('redirects the user to the next page when done', function() { // Simulate providing a ?next query string parameter setFakeQueryParams({'?next': FORWARD_URL}); ajaxSpyAndInitialize(this); // Verify that we were redirected expect(view.redirect).toHaveBeenCalledWith(FORWARD_URL); }); it('ignores redirect to external URLs', function() { // Simulate providing a ?next query string parameter // that goes to an external URL setFakeQueryParams({'?next': 'http://www.example.com'}); ajaxSpyAndInitialize(this); // Expect that we ignore the external URL and redirect to the dashboard expect(view.redirect).toHaveBeenCalledWith('/dashboard'); }); }); }); }).call(this, define || RequireJS.define);