From ca1f2f77688a4b1b2d0901cc00b2c7249ecfe49d Mon Sep 17 00:00:00 2001 From: muhammad-ammar Date: Mon, 13 Apr 2015 16:33:52 +0500 Subject: [PATCH] Jasmine tests for upload/remove profile image on learner profile page. TNL-1538 --- .../student_profile/test/test_views.py | 20 ++ lms/static/js/spec/main.js | 1 + lms/static/js/spec/student_account/helpers.js | 10 +- lms/static/js/spec/student_profile/helpers.js | 28 +- .../learner_profile_factory_spec.js | 13 +- .../learner_profile_fields_spec.js | 276 ++++++++++++++++++ .../learner_profile_view_spec.js | 7 +- .../views/learner_profile_fields.js | 10 +- lms/static/js/views/fields.js | 15 +- lms/static/sass/views/_learner-profile.scss | 1 + .../{ => fields}/message_banner.underscore | 0 .../student_profile/learner_profile.html | 8 +- 12 files changed, 355 insertions(+), 34 deletions(-) create mode 100644 lms/static/js/spec/student_profile/learner_profile_fields_spec.js rename lms/templates/{ => fields}/message_banner.underscore (100%) diff --git a/lms/djangoapps/student_profile/test/test_views.py b/lms/djangoapps/student_profile/test/test_views.py index 12d57026bb..aa78183108 100644 --- a/lms/djangoapps/student_profile/test/test_views.py +++ b/lms/djangoapps/student_profile/test/test_views.py @@ -53,6 +53,26 @@ class LearnerProfileViewTest(UrlResetMixin, TestCase): reverse('preferences_api', kwargs={'username': self.user.username}) ) + self.assertEqual( + context['data']['profile_image_upload_url'], + reverse("profile_image_upload", kwargs={'username': self.user.username}) + ) + + self.assertEqual( + context['data']['profile_image_remove_url'], + reverse('profile_image_remove', kwargs={'username': self.user.username}) + ) + + self.assertEqual( + context['data']['profile_image_max_bytes'], + settings.PROFILE_IMAGE_MAX_BYTES + ) + + self.assertEqual( + context['data']['profile_image_min_bytes'], + settings.PROFILE_IMAGE_MIN_BYTES + ) + self.assertEqual(context['data']['account_settings_page_url'], reverse('account_settings')) for attribute in self.CONTEXT_DATA: diff --git a/lms/static/js/spec/main.js b/lms/static/js/spec/main.js index 8bebcf05dd..05b9357134 100644 --- a/lms/static/js/spec/main.js +++ b/lms/static/js/spec/main.js @@ -598,6 +598,7 @@ 'lms/include/js/spec/views/fields_spec.js', 'lms/include/js/spec/student_profile/learner_profile_factory_spec.js', 'lms/include/js/spec/student_profile/learner_profile_view_spec.js', + 'lms/include/js/spec/student_profile/learner_profile_fields_spec.js', 'lms/include/js/spec/verify_student/pay_and_verify_view_spec.js', 'lms/include/js/spec/verify_student/webcam_photo_view_spec.js', 'lms/include/js/spec/verify_student/image_input_spec.js', diff --git a/lms/static/js/spec/student_account/helpers.js b/lms/static/js/spec/student_account/helpers.js index c4dc04e48a..3ca13867e2 100644 --- a/lms/static/js/spec/student_account/helpers.js +++ b/lms/static/js/spec/student_account/helpers.js @@ -6,11 +6,15 @@ define(['underscore'], function(_) { var IMAGE_UPLOAD_API_URL = '/api/profile_images/v0/staff/upload'; var IMAGE_REMOVE_API_URL = '/api/profile_images/v0/staff/remove'; + var PROFILE_IMAGE = { + image_url_large: '/media/profile-images/image.jpg', + has_image: true + }; + var USER_ACCOUNTS_DATA = { username: 'student', name: 'Student', email: 'student@edx.org', - level_of_education: '0', gender: '0', year_of_birth: '0', @@ -18,7 +22,8 @@ define(['underscore'], function(_) { language: '0', bio: "About the student", language_proficiencies: [{code: '1'}], - requires_parental_consent: true + requires_parental_consent: true, + profile_image: PROFILE_IMAGE }; var USER_PREFERENCES_DATA = { @@ -101,6 +106,7 @@ define(['underscore'], function(_) { IMAGE_REMOVE_API_URL: IMAGE_REMOVE_API_URL, IMAGE_MAX_BYTES: IMAGE_MAX_BYTES, IMAGE_MIN_BYTES: IMAGE_MIN_BYTES, + PROFILE_IMAGE: PROFILE_IMAGE, USER_ACCOUNTS_DATA: USER_ACCOUNTS_DATA, USER_PREFERENCES_DATA: USER_PREFERENCES_DATA, FIELD_OPTIONS: FIELD_OPTIONS, diff --git a/lms/static/js/spec/student_profile/helpers.js b/lms/static/js/spec/student_profile/helpers.js index 5ea7dd1877..dff6e9c26c 100644 --- a/lms/static/js/spec/student_profile/helpers.js +++ b/lms/static/js/spec/student_profile/helpers.js @@ -9,10 +9,12 @@ define(['underscore'], function(_) { expect(fieldTitle).toBe(view.options.title); } - if ('fieldValue' in view) { + if ('fieldValue' in view || 'imageUrl' in view) { expect(view.model.get(view.options.valueAttribute)).toBeTruthy(); - if (view.fieldValue()) { + if ('imageUrl' in view) { + expect($($element.find('.image-frame')[0]).attr('src')).toBe(view.imageUrl()); + } else if (view.fieldValue()) { expect(view.fieldValue()).toBe(view.modelValue()); } else if ('optionForValue' in view) { @@ -43,9 +45,11 @@ define(['underscore'], function(_) { var sectionOneFieldElements = $(learnerProfileView.$('.wrapper-profile-section-one')).find('.u-field'); - expect(sectionOneFieldElements.length).toBe(learnerProfileView.options.sectionOneFieldViews.length); + expect(sectionOneFieldElements.length).toBe(4); + expectProfileElementContainsField(sectionOneFieldElements[0], learnerProfileView.options.profileImageFieldView); + expectProfileElementContainsField(sectionOneFieldElements[1], learnerProfileView.options.usernameFieldView); - _.each(sectionOneFieldElements, function (sectionFieldElement, fieldIndex) { + _.each(_.rest(sectionOneFieldElements, 2) , function (sectionFieldElement, fieldIndex) { expectProfileElementContainsField( sectionFieldElement, learnerProfileView.options.sectionOneFieldViews[fieldIndex] @@ -79,13 +83,15 @@ define(['underscore'], function(_) { var sectionOneFieldElements = $(learnerProfileView.$('.wrapper-profile-section-one')).find('.u-field'); - expect(sectionOneFieldElements.length).toBe(1); - _.each(sectionOneFieldElements, function (sectionFieldElement, fieldIndex) { - expectProfileElementContainsField( - sectionFieldElement, - learnerProfileView.options.sectionOneFieldViews[fieldIndex] - ); - }); + expect(sectionOneFieldElements.length).toBe(2); + expectProfileElementContainsField( + sectionOneFieldElements[0], + learnerProfileView.options.profileImageFieldView + ); + expectProfileElementContainsField( + sectionOneFieldElements[1], + learnerProfileView.options.usernameFieldView + ); if (othersProfile) { expect($('.profile-private--message').text()) diff --git a/lms/static/js/spec/student_profile/learner_profile_factory_spec.js b/lms/static/js/spec/student_profile/learner_profile_factory_spec.js index 3fba060b8e..a004c53aa2 100644 --- a/lms/static/js/spec/student_profile/learner_profile_factory_spec.js +++ b/lms/static/js/spec/student_profile/learner_profile_factory_spec.js @@ -6,7 +6,8 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j 'js/student_account/models/user_preferences_model', 'js/student_profile/views/learner_profile_view', 'js/student_profile/views/learner_profile_fields', - 'js/student_profile/views/learner_profile_factory' + 'js/student_profile/views/learner_profile_factory', + 'js/views/message_banner' ], function (Backbone, $, _, AjaxHelpers, TemplateHelpers, Helpers, LearnerProfileHelpers, FieldViews, UserAccountModel, UserPreferencesModel, LearnerProfileView, LearnerProfileFields, LearnerProfilePage) { @@ -17,10 +18,12 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j var requests; beforeEach(function () { - setFixtures('

Loading

'); + setFixtures('

Loading

'); TemplateHelpers.installTemplate('templates/fields/field_readonly'); TemplateHelpers.installTemplate('templates/fields/field_dropdown'); TemplateHelpers.installTemplate('templates/fields/field_textarea'); + TemplateHelpers.installTemplate('templates/fields/field_image'); + TemplateHelpers.installTemplate('templates/fields/message_banner'); TemplateHelpers.installTemplate('templates/student_profile/learner_profile'); }); @@ -32,7 +35,11 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j 'account_settings_page_url': Helpers.USER_ACCOUNTS_API_URL, 'country_options': Helpers.FIELD_OPTIONS, 'language_options': Helpers.FIELD_OPTIONS, - 'has_preferences_access': true + 'has_preferences_access': true, + 'profile_image_max_bytes': Helpers.IMAGE_MAX_BYTES, + 'profile_image_min_bytes': Helpers.IMAGE_MIN_BYTES, + 'profile_image_upload_url': Helpers.IMAGE_UPLOAD_API_URL, + 'profile_image_remove_url': Helpers.IMAGE_REMOVE_API_URL }); }; diff --git a/lms/static/js/spec/student_profile/learner_profile_fields_spec.js b/lms/static/js/spec/student_profile/learner_profile_fields_spec.js new file mode 100644 index 0000000000..cb39ae53d5 --- /dev/null +++ b/lms/static/js/spec/student_profile/learner_profile_fields_spec.js @@ -0,0 +1,276 @@ +define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'js/common_helpers/template_helpers', + 'js/spec/student_account/helpers', + 'js/student_account/models/user_account_model', + 'js/student_profile/views/learner_profile_fields', + 'js/views/message_banner' + ], + function (Backbone, $, _, AjaxHelpers, TemplateHelpers, Helpers, UserAccountModel, LearnerProfileFields, + MessageBannerView) { + 'use strict'; + + describe("edx.user.LearnerProfileFields", function () { + + var createImageView = function (ownProfile, hasImage, imageMaxBytes, imageMinBytes, yearOfBirth) { + + var imageData = { + image_url_large: '/media/profile-images/default.jpg', + has_image: hasImage ? true : false + }; + + yearOfBirth = _.isUndefined(yearOfBirth) ? 1989 : yearOfBirth; + + var accountSettingsModel = new UserAccountModel(); + accountSettingsModel.set({'profile_image': imageData}); + accountSettingsModel.set({'year_of_birth': yearOfBirth}); + accountSettingsModel.set({'requires_parental_consent': _.isEmpty(yearOfBirth) ? true : false}); + + accountSettingsModel.url = Helpers.USER_ACCOUNTS_API_URL; + + var messageView = new MessageBannerView({ + el: $('.message-banner') + }); + + imageMaxBytes = imageMaxBytes || 64; + imageMinBytes = imageMinBytes || 16; + + var editable = ownProfile ? 'toggle' : 'never'; + + return new LearnerProfileFields.ProfileImageFieldView({ + model: accountSettingsModel, + valueAttribute: "profile_image", + editable: editable === 'toggle', + messageView: messageView, + imageMaxBytes: imageMaxBytes, + imageMinBytes: imageMinBytes, + imageUploadUrl: Helpers.IMAGE_UPLOAD_API_URL, + imageRemoveUrl: Helpers.IMAGE_REMOVE_API_URL + }); + }; + + beforeEach(function () { + setFixtures('

Loading

'); + TemplateHelpers.installTemplate('templates/student_profile/learner_profile'); + TemplateHelpers.installTemplate('templates/fields/field_image'); + TemplateHelpers.installTemplate("templates/fields/message_banner"); + }); + + var createFakeImageFile = function (size) { + var fileFakeData = 'i63ljc6giwoskyb9x5sw0169bdcmcxr3cdz8boqv0lik971972cmd6yknvcxr5sw0nvc169bdcmcxsdf'; + return new Blob( + [ fileFakeData.substr(0, size) ], + { type: 'image/jpg' } + ); + }; + + it("can upload profile image", function() { + + var imageView = createImageView(true, false); + imageView.render(); + + var requests = AjaxHelpers.requests(this); + + var imageName = 'profile_image.jpg'; + + // Initialize jquery file uploader + imageView.$('.upload-button-input').fileupload({ + url: Helpers.IMAGE_UPLOAD_API_URL, + type: 'POST', + add: imageView.fileSelected, + done: imageView.imageChangeSucceeded, + fail: imageView.imageChangeFailed + }); + + // Remove button should not be present for default image + expect(imageView.$('.u-field-remove-button').css('display') === 'none').toBeTruthy(); + + // For default image, image title should be `Upload an image` + expect(imageView.$('.upload-button-title').text().trim()).toBe(imageView.titleAdd); + + // Add image to upload queue, this will validate the image size and send POST request to upload image + imageView.$('.upload-button-input').fileupload('add', {files: [createFakeImageFile(60)]}); + + // Verify image upload progress message + expect(imageView.$('.upload-button-title').text().trim()).toBe(imageView.titleUploading); + + // Verify if POST request received for image upload + AjaxHelpers.expectRequest(requests, 'POST', Helpers.IMAGE_UPLOAD_API_URL, new FormData()); + + // Send 204 NO CONTENT to confirm the image upload success + AjaxHelpers.respondWithNoContent(requests); + + // Upon successful image upload, account settings model will be fetched to get the url for newly uploaded image + // So we need to send the response for that GET + var data = {profile_image: { + image_url_large: '/media/profile-images/' + imageName, + has_image: true + }}; + AjaxHelpers.respondWithJson(requests, data); + + // Verify uploaded image name + expect(imageView.$('.image-frame').attr('src')).toContain(imageName); + + // Remove button should be present after successful image upload + expect(imageView.$('.u-field-remove-button').css('display') !== 'none').toBeTruthy(); + + // After image upload, image title should be `Change image` + expect(imageView.$('.upload-button-title').text().trim()).toBe(imageView.titleEdit); + }); + + it("can remove profile image", function() { + var imageView = createImageView(true, true); + imageView.render(); + + var requests = AjaxHelpers.requests(this); + + imageView.$('.u-field-remove-button').click(); + + // Verify image remove progress message + expect(imageView.$('.remove-button-title').text().trim()).toBe(imageView.titleRemoving); + + // Verify if POST request received for image remove + AjaxHelpers.expectRequest(requests, 'POST', Helpers.IMAGE_REMOVE_API_URL, null); + + // Send 204 NO CONTENT to confirm the image removal success + AjaxHelpers.respondWithNoContent(requests); + + // Upon successful image removal, account settings model will be fetched to get the default image url + // So we need to send the response for that GET + var data = {profile_image: { + image_url_large: '/media/profile-images/default.jpg', + has_image: false + }}; + AjaxHelpers.respondWithJson(requests, data); + + // Remove button should not be present for default image + expect(imageView.$('.u-field-remove-button').css('display') === 'none').toBeTruthy(); + }); + + it("can't remove default profile image", function() { + var imageView = createImageView(true, false); + imageView.render(); + + spyOn(imageView, 'clickedRemoveButton'); + + // Remove button should not be present for default image + expect(imageView.$('.u-field-remove-button').css('display') === 'none').toBeTruthy(); + + imageView.$('.u-field-remove-button').click(); + + // Remove button click handler should not be called + expect(imageView.clickedRemoveButton).not.toHaveBeenCalled(); + }); + + it("can't upload image having size greater than max size", function() { + var imageView = createImageView(true, false); + imageView.render(); + + // Initialize jquery file uploader + imageView.$('.upload-button-input').fileupload({ + url: Helpers.IMAGE_UPLOAD_API_URL, + type: 'POST', + add: imageView.fileSelected, + done: imageView.imageChangeSucceeded, + fail: imageView.imageChangeFailed + }); + + // Add image to upload queue, this will validate the image size + imageView.$('.upload-button-input').fileupload('add', {files: [createFakeImageFile(70)]}); + + // Verify error message + expect($('.message-banner').text().trim()).toBe('Your image must be smaller than 64 Bytes in size.'); + }); + + it("can't upload image having size less than min size", function() { + var imageView = createImageView(true, false); + imageView.render(); + + // Initialize jquery file uploader + imageView.$('.upload-button-input').fileupload({ + url: Helpers.IMAGE_UPLOAD_API_URL, + type: 'POST', + add: imageView.fileSelected, + done: imageView.imageChangeSucceeded, + fail: imageView.imageChangeFailed + }); + + // Add image to upload queue, this will validate the image size + imageView.$('.upload-button-input').fileupload('add', {files: [createFakeImageFile(10)]}); + + // Verify error message + expect($('.message-banner').text().trim()).toBe('Your image must be at least 16 Bytes in size.'); + }); + + it("can't upload/remove image if parental consent required", function() { + var imageView = createImageView(true, false, 64, 16, ''); + imageView.render(); + + spyOn(imageView, 'clickedUploadButton'); + spyOn(imageView, 'clickedRemoveButton'); + + expect(imageView.$('.u-field-upload-button').css('display') === 'none').toBeTruthy(); + expect(imageView.$('.u-field-remove-button').css('display') === 'none').toBeTruthy(); + + imageView.$('.u-field-upload-button').click(); + imageView.$('.u-field-remove-button').click(); + + expect(imageView.clickedUploadButton).not.toHaveBeenCalled(); + expect(imageView.clickedRemoveButton).not.toHaveBeenCalled(); + }); + + it("can't upload image on others profile", function() { + var imageView = createImageView(false); + imageView.render(); + + spyOn(imageView, 'clickedUploadButton'); + spyOn(imageView, 'clickedRemoveButton'); + + expect(imageView.$('.u-field-upload-button').css('display') === 'none').toBeTruthy(); + expect(imageView.$('.u-field-remove-button').css('display') === 'none').toBeTruthy(); + + imageView.$('.u-field-upload-button').click(); + imageView.$('.u-field-remove-button').click(); + + expect(imageView.clickedUploadButton).not.toHaveBeenCalled(); + expect(imageView.clickedRemoveButton).not.toHaveBeenCalled(); + }); + + it("shows message if we try to navigate away during image upload/remove", function() { + var imageView = createImageView(true, false); + spyOn(imageView, 'onBeforeUnload'); + imageView.render(); + + // Initialize jquery file uploader + imageView.$('.upload-button-input').fileupload({ + url: Helpers.IMAGE_UPLOAD_API_URL, + type: 'POST', + add: imageView.fileSelected, + done: imageView.imageChangeSucceeded, + fail: imageView.imageChangeFailed + }); + + // Add image to upload queue, this will validate the image size and send POST request to upload image + imageView.$('.upload-button-input').fileupload('add', {files: [createFakeImageFile(60)]}); + + // Verify image upload progress message + expect(imageView.$('.upload-button-title').text().trim()).toBe(imageView.titleUploading); + + $(window).trigger('beforeunload'); + + expect(imageView.onBeforeUnload).toHaveBeenCalled(); + }); + + it('renders message correctly', function() { + var messageSelector = '.message-banner'; + var messageView = new MessageBannerView({ + el: $(messageSelector) + }); + + messageView.showMessage('I am message view'); + // Verify error message + expect($(messageSelector).text().trim()).toBe('I am message view'); + + messageView.hideMessage(); + expect($(messageSelector).text().trim()).toBe(''); + }); + }); + }); diff --git a/lms/static/js/spec/student_profile/learner_profile_view_spec.js b/lms/static/js/spec/student_profile/learner_profile_view_spec.js index 00826017a5..fd869a9e06 100644 --- a/lms/static/js/spec/student_profile/learner_profile_view_spec.js +++ b/lms/static/js/spec/student_profile/learner_profile_view_spec.js @@ -24,6 +24,7 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j accountSettingsData.requires_parental_consent = false; accountSettingsModel.set(accountSettingsData); accountSettingsModel.set({'profile_is_public': profileIsPublic}); + accountSettingsModel.set({'profile_image': Helpers.PROFILE_IMAGE}); var accountPreferencesModel = new AccountPreferencesModel(); accountPreferencesModel.set({account_privacy: accountPrivacy}); @@ -51,7 +52,7 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j el: $('.message-banner') }); - var profileImageFieldView = new FieldsView.ImageFieldView({ + var profileImageFieldView = new LearnerProfileFields.ProfileImageFieldView({ model: accountSettingsModel, valueAttribute: "profile_image", editable: editable, @@ -69,7 +70,6 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j }); var sectionOneFieldViews = [ - usernameFieldView, new FieldViews.DropdownFieldView({ model: accountSettingsModel, required: false, @@ -117,6 +117,7 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j preferencesModel: accountPreferencesModel, accountPrivacyFieldView: accountPrivacyFieldView, usernameFieldView: usernameFieldView, + profileImageFieldView: profileImageFieldView, sectionOneFieldViews: sectionOneFieldViews, sectionTwoFieldViews: sectionTwoFieldViews }); @@ -128,7 +129,7 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j TemplateHelpers.installTemplate('templates/fields/field_dropdown'); TemplateHelpers.installTemplate('templates/fields/field_textarea'); TemplateHelpers.installTemplate('templates/fields/field_image'); - TemplateHelpers.installTemplate('templates/message_banner'); + TemplateHelpers.installTemplate('templates/fields/message_banner'); TemplateHelpers.installTemplate('templates/student_profile/learner_profile'); }); diff --git a/lms/static/js/student_profile/views/learner_profile_fields.js b/lms/static/js/student_profile/views/learner_profile_fields.js index e5c6e13d61..071fca5fe6 100644 --- a/lms/static/js/student_profile/views/learner_profile_fields.js +++ b/lms/static/js/student_profile/views/learner_profile_fields.js @@ -70,9 +70,14 @@ imageChangeFailed: function (e, data) { this.setCurrentStatus(''); - if (_.contains([400, 404], data.jqXHR.status)) { + this.showImageChangeFailedMessage(data.jqXHR.status, data.jqXHR.responseText); + this.render(); + }, + + showImageChangeFailedMessage: function (status, responseText) { + if (_.contains([400, 404], status)) { try { - var errors = JSON.parse(data.jqXHR.responseText); + var errors = JSON.parse(responseText); this.showErrorMessage(errors.user_message); } catch (error) { this.showErrorMessage(this.errorMessage); @@ -80,7 +85,6 @@ } else { this.showErrorMessage(this.errorMessage); } - this.render(); }, showErrorMessage: function (message) { diff --git a/lms/static/js/views/fields.js b/lms/static/js/views/fields.js index 2a8c1b7619..932f4fb2d5 100644 --- a/lms/static/js/views/fields.js +++ b/lms/static/js/views/fields.js @@ -548,7 +548,8 @@ return this; }, - showErrorMessage: function () { + showErrorMessage: function (message) { + return message; }, imageUrl: function () { @@ -593,7 +594,7 @@ } }, - clickedUploadButton: function () { + clickedUploadButton: function (e, data) { $(this.uploadButtonSelector).fileupload({ url: this.options.imageUploadUrl, type: 'POST', @@ -603,7 +604,7 @@ }); }, - clickedRemoveButton: function () { + clickedRemoveButton: function (e, data) { var view = this; this.setCurrentStatus('removing'); this.setUploadButtonVisibility('none'); @@ -615,7 +616,7 @@ view.imageChangeSucceeded(); }, error: function (xhr, status, error) { - view.imageChangeFailed(); + view.showImageChangeFailedMessage(xhr.status, xhr.responseText); } }); }, @@ -627,8 +628,11 @@ imageChangeFailed: function (e, data) { }, + showImageChangeFailedMessage: function (status, responseText) { + }, + fileSelected: function (e, data) { - if (this.validateImageSize(data.files[0].size)) { + if (_.isUndefined(data.files[0].size) || this.validateImageSize(data.files[0].size)) { data.formData = {file: data.files[0]}; this.setCurrentStatus('uploading'); this.setRemoveButtonVisibility('none'); @@ -681,6 +685,7 @@ }, onBeforeUnload: function () { + console.log('Do you really want to go away?'); var status = this.getCurrentStatus(); if (status === 'uploading') { return gettext("Upload is in progress. To avoid errors, stay on this page until the process is complete."); diff --git a/lms/static/sass/views/_learner-profile.scss b/lms/static/sass/views/_learner-profile.scss index 06ea05ea3c..2679d6af98 100644 --- a/lms/static/sass/views/_learner-profile.scss +++ b/lms/static/sass/views/_learner-profile.scss @@ -30,6 +30,7 @@ background: transparent !important; border: none !important; padding: 0; + -webkit-tap-highlight-color: transparent; } .u-field-image { diff --git a/lms/templates/message_banner.underscore b/lms/templates/fields/message_banner.underscore similarity index 100% rename from lms/templates/message_banner.underscore rename to lms/templates/fields/message_banner.underscore diff --git a/lms/templates/student_profile/learner_profile.html b/lms/templates/student_profile/learner_profile.html index 29475aa614..741025156e 100644 --- a/lms/templates/student_profile/learner_profile.html +++ b/lms/templates/student_profile/learner_profile.html @@ -10,7 +10,7 @@ <%block name="bodyclass">view-profile <%block name="header_extras"> - % for template_name in ["field_dropdown", "field_image", "field_textarea", "field_readonly"]: + % for template_name in ["field_dropdown", "field_image", "field_textarea", "field_readonly", "message_banner"]: @@ -21,12 +21,6 @@ <%static:include path="student_profile/${template_name}.underscore" /> % endfor - - % for template_name in ["message_banner"]: - - % endfor