Commit 3d09290c by Diana Huang Committed by Andy Armstrong

Add a dismiss button to welcome message.

Store user's preference indefinitely.
parent 72fb9722
define ["js/models/uploads", "js/views/uploads", "js/models/chapter",
define ["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
"edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers", "js/spec_helpers/modal_helpers"],
(FileUpload, UploadDialog, Chapter, AjaxHelpers, modal_helpers) ->
(sinon, FileUpload, UploadDialog, Chapter, AjaxHelpers, modal_helpers) ->
describe "UploadDialog", ->
tpl = readFixtures("upload-dialog.underscore")
......
define(['js/utils/drag_and_drop', 'common/js/components/views/feedback_notification',
define(['sinon', 'js/utils/drag_and_drop', 'common/js/components/views/feedback_notification',
'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'jquery', 'underscore'],
function(ContentDragger, Notification, AjaxHelpers, $, _) {
function(sinon, ContentDragger, Notification, AjaxHelpers, $, _) {
'use strict';
describe('Overview drag and drop functionality', function() {
beforeEach(function() {
setFixtures(readFixtures('mock/mock-outline.underscore'));
......
......@@ -10,6 +10,10 @@
font-weight: $font-bold;
color: $black;
}
.dismiss-message {
@include float(right);
}
}
// Course sidebar
......
(function(define) {
'use strict';
define(['gettext', 'jquery', 'underscore', 'backbone', 'js/views/message_banner'],
function(gettext, $, _, Backbone, MessageBannerView) {
return Backbone.View.extend({
......
(function(define) {
'use strict';
define([
'gettext', 'jquery', 'underscore', 'backbone', 'logger', 'moment', 'edx-ui-toolkit/js/utils/html-utils',
'common/js/components/views/paging_header', 'common/js/components/views/paging_footer',
......
<div class="welcome-message">
<div class="dismiss-message">
<button type="button" class="btn-link">${_("Dismiss")}</button>
</div>
This is a useful welcome message!
</div>
/* globals $ */
import 'jquery.cookie';
export class WelcomeMessage { // eslint-disable-line import/prefer-default-export
constructor(dismissUrl) {
$('.dismiss-message button').click(() => {
$.ajax({
type: 'POST',
url: dismissUrl,
headers: {
'X-CSRFToken': $.cookie('csrftoken'),
},
success: () => {
$('.welcome-message').hide();
},
});
});
}
}
/* globals $, loadFixtures */
import {
expectRequest,
requests as mockRequests,
respondWithJson,
} from 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers';
import { WelcomeMessage } from '../WelcomeMessage';
describe('Welcome Message factory', () => {
describe('Ensure button click', () => {
const endpointUrl = '/course/course_id/dismiss_message/';
beforeEach(() => {
loadFixtures('course_experience/fixtures/welcome-message-fragment.html');
new WelcomeMessage(endpointUrl); // eslint-disable-line no-new
});
it('When button click is made, ajax call is made and message is hidden.', () => {
const $message = $('.welcome-message');
const requests = mockRequests(this);
document.querySelector('.dismiss-message button').dispatchEvent(new Event('click'));
expectRequest(
requests,
'POST',
endpointUrl,
);
respondWithJson(requests);
expect($message.attr('style')).toBe('display: none;');
requests.restore();
});
});
});
......@@ -4,11 +4,21 @@
<%namespace name='static' file='../static_content.html'/>
<%!
from openedx.core.djangolib.js_utils import js_escaped_string
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import HTML
%>
<%block name="content">
<div class="welcome-message">
<div class="dismiss-message">
<button type="button" class="btn-link">${_("Dismiss")}</button>
</div>
${HTML(welcome_message_html)}
</div>
</%block>
<%static:webpack entry="WelcomeMessage">
new WelcomeMessage("${dismiss_url | n, js_escaped_string}");
</%static:webpack>
......@@ -89,7 +89,7 @@ class TestCourseHomePage(SharedModuleStoreTestCase):
course_home_url(self.course)
# Fetch the view and verify the query counts
with self.assertNumQueries(48):
with self.assertNumQueries(49):
with check_mongo_calls(5):
url = course_home_url(self.course)
self.client.get(url)
......@@ -27,6 +27,18 @@ def welcome_message_url(course):
)
def dismiss_message_url(course):
"""
Returns the URL for the dismiss message endpoint.
"""
return reverse(
'openedx.course_experience.dismiss_welcome_message',
kwargs={
'course_id': unicode(course.id),
}
)
class TestWelcomeMessageView(ModuleStoreTestCase):
"""
Tests for the course welcome message fragment view.
......@@ -41,10 +53,8 @@ class TestWelcomeMessageView(ModuleStoreTestCase):
chapter = ItemFactory.create(category='chapter', parent_location=self.course.location)
section = ItemFactory.create(category='sequential', parent_location=chapter.location)
ItemFactory.create(category='vertical', parent_location=section.location)
self.user = UserFactory(password=TEST_PASSWORD)
CourseEnrollment.enroll(self.user, self.course.id)
self.client.login(username=self.user.username, password=TEST_PASSWORD)
def tearDown(self):
......@@ -58,6 +68,7 @@ class TestWelcomeMessageView(ModuleStoreTestCase):
response = self.client.get(welcome_message_url(self.course))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Second Update')
self.assertContains(response, 'Dismiss')
def test_replace_urls(self):
img_url = 'img.png'
......@@ -72,3 +83,15 @@ class TestWelcomeMessageView(ModuleStoreTestCase):
def test_empty_welcome_message(self):
response = self.client.get(welcome_message_url(self.course))
self.assertEqual(response.status_code, 204)
def test_dismiss_message(self):
create_course_update(self.course, self.user, 'First Update', date='January 1, 2017')
response = self.client.get(welcome_message_url(self.course))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'First Update')
self.client.post(dismiss_message_url(self.course))
response = self.client.get(welcome_message_url(self.course))
self.assertNotIn('First Update', response)
self.assertEqual(response.status_code, 204)
......@@ -7,8 +7,8 @@ from django.conf.urls import url
from views.course_home import CourseHomeFragmentView, CourseHomeView
from views.course_outline import CourseOutlineFragmentView
from views.course_updates import CourseUpdatesFragmentView, CourseUpdatesView
from views.welcome_message import WelcomeMessageFragmentView
from views.course_sock import CourseSockFragmentView
from views.welcome_message import WelcomeMessageFragmentView, dismiss_welcome_message
urlpatterns = [
url(
......@@ -46,4 +46,9 @@ urlpatterns = [
CourseSockFragmentView.as_view(),
name='openedx.course_experience.course_sock_fragment_view',
),
url(
r'^dismiss_welcome_message$',
dismiss_welcome_message,
name='openedx.course_experience.dismiss_welcome_message',
),
]
......@@ -2,13 +2,19 @@
View logic for handling course welcome messages.
"""
from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseBadRequest
from django.template.loader import render_to_string
from django.views.decorators.csrf import ensure_csrf_cookie
from opaque_keys.edx.keys import CourseKey
from web_fragments.fragment import Fragment
from course_updates import CourseUpdatesFragmentView
from courseware.courses import get_course_info_section_module, get_course_with_access
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
from openedx.core.djangoapps.user_api.course_tag.api import set_course_tag, get_course_tag
PREFERENCE_KEY = 'view-welcome-message'
class WelcomeMessageFragmentView(EdxFragmentView):
......@@ -27,12 +33,20 @@ class WelcomeMessageFragmentView(EdxFragmentView):
if not welcome_message_html:
return None
dismiss_url = reverse(
'openedx.course_experience.dismiss_welcome_message', kwargs={'course_id': unicode(course_key)}
)
context = {
'dismiss_url': dismiss_url,
'welcome_message_html': welcome_message_html,
}
html = render_to_string('course_experience/welcome-message-fragment.html', context)
return Fragment(html)
if get_course_tag(request.user, course_key, PREFERENCE_KEY) == 'False':
return None
else:
html = render_to_string('course_experience/welcome-message-fragment.html', context)
return Fragment(html)
@classmethod
def welcome_message_html(cls, request, course):
......@@ -51,3 +65,13 @@ class WelcomeMessageFragmentView(EdxFragmentView):
content = info_block.system.replace_urls(ordered_updates[0]['content'])
return content
@ensure_csrf_cookie
def dismiss_welcome_message(request, course_id):
"""
Given the course_id in the request, disable displaying the welcome message for the user.
"""
course_key = CourseKey.from_string(course_id)
set_course_tag(request.user, course_key, PREFERENCE_KEY, 'False')
return HttpResponse()
......@@ -34,7 +34,7 @@
"eslint-config-edx": "^2.0.1",
"eslint-config-edx-es5": "^2.0.0",
"eslint-import-resolver-webpack": "^0.8.1",
"jasmine-core": "^2.4.1",
"jasmine-core": "^2.6.4",
"jasmine-jquery": "^2.1.1",
"karma": "^0.13.22",
"karma-chrome-launcher": "^0.2.3",
......@@ -50,7 +50,7 @@
"pa11y": "4.0.1",
"pa11y-reporter-json-oldnode": "1.0.0",
"plato": "1.2.2",
"sinon": "^1.17.7",
"sinon": "2.3.5",
"squirejs": "^0.1.0"
}
}
......@@ -20,6 +20,7 @@ var wpconfig = {
entry: {
CourseOutline: './openedx/features/course_experience/static/course_experience/js/CourseOutline.js',
CourseSock: './openedx/features/course_experience/static/course_experience/js/CourseSock.js',
WelcomeMessage: './openedx/features/course_experience/static/course_experience/js/WelcomeMessage.js',
Import: './cms/static/js/features/import/factories/import.js'
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment