Revert "Merge pull request #14078 from edx/yro_remove-datetimetext-functions"
This reverts commit8c0098812d, reversing changes made to5b6e2dd5ee.
This commit is contained in:
@@ -12,6 +12,7 @@ from pytz import utc
|
||||
from lazy import lazy
|
||||
|
||||
from ccx_keys.locator import CCXLocator
|
||||
from openedx.core.lib.time_zone_utils import get_time_zone_abbr
|
||||
from openedx.core.djangoapps.xmodule_django.models import CourseKeyField, LocationKeyField
|
||||
from xmodule.error_module import ErrorDescriptor
|
||||
from xmodule.modulestore.django import modulestore
|
||||
@@ -83,6 +84,36 @@ class CustomCourseForEdX(models.Model):
|
||||
|
||||
return datetime.now(utc) > self.due
|
||||
|
||||
def start_datetime_text(self, format_string="SHORT_DATE", time_zone=utc):
|
||||
"""Returns the desired text representation of the CCX start datetime
|
||||
|
||||
The returned value is in specified time zone, defaulted to UTC.
|
||||
"""
|
||||
i18n = self.course.runtime.service(self.course, "i18n")
|
||||
strftime = i18n.strftime
|
||||
value = strftime(self.start.astimezone(time_zone), format_string)
|
||||
if format_string == 'DATE_TIME':
|
||||
value += ' ' + get_time_zone_abbr(time_zone, self.start)
|
||||
return value
|
||||
|
||||
def end_datetime_text(self, format_string="SHORT_DATE", time_zone=utc):
|
||||
"""Returns the desired text representation of the CCX due datetime
|
||||
|
||||
If the due date for the CCX is not set, the value returned is the empty
|
||||
string.
|
||||
|
||||
The returned value is in specified time zone, defaulted to UTC.
|
||||
"""
|
||||
if self.due is None:
|
||||
return ''
|
||||
|
||||
i18n = self.course.runtime.service(self.course, "i18n")
|
||||
strftime = i18n.strftime
|
||||
value = strftime(self.due.astimezone(time_zone), format_string)
|
||||
if format_string == 'DATE_TIME':
|
||||
value += ' ' + get_time_zone_abbr(time_zone, self.due)
|
||||
return value
|
||||
|
||||
@property
|
||||
def structure(self):
|
||||
"""
|
||||
|
||||
@@ -4,12 +4,14 @@ tests for the models
|
||||
import ddt
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from mock import patch
|
||||
from nose.plugins.attrib import attr
|
||||
from pytz import utc
|
||||
from pytz import timezone, utc
|
||||
from student.roles import CourseCcxCoachRole
|
||||
from student.tests.factories import (
|
||||
AdminFactory,
|
||||
)
|
||||
from util.tests.test_date_utils import fake_ugettext
|
||||
from xmodule.modulestore.tests.django_utils import (
|
||||
ModuleStoreTestCase,
|
||||
TEST_DATA_SPLIT_MODULESTORE
|
||||
@@ -150,6 +152,95 @@ class TestCCX(ModuleStoreTestCase):
|
||||
"""verify that a ccx without a due date has not ended"""
|
||||
self.assertFalse(self.ccx.has_ended()) # pylint: disable=no-member
|
||||
|
||||
# ensure that the expected localized format will be found by the i18n
|
||||
# service
|
||||
@patch('util.date_utils.ugettext', fake_ugettext(translations={
|
||||
"SHORT_DATE_FORMAT": "%b %d, %Y",
|
||||
}))
|
||||
def test_start_datetime_short_date(self):
|
||||
"""verify that the start date for a ccx formats properly by default"""
|
||||
start = datetime(2015, 1, 1, 12, 0, 0, tzinfo=utc)
|
||||
expected = "Jan 01, 2015"
|
||||
self.set_ccx_override('start', start)
|
||||
actual = self.ccx.start_datetime_text() # pylint: disable=no-member
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
@patch('util.date_utils.ugettext', fake_ugettext(translations={
|
||||
"DATE_TIME_FORMAT": "%b %d, %Y at %H:%M",
|
||||
}))
|
||||
def test_start_datetime_date_time_format(self):
|
||||
"""verify that the DATE_TIME format also works as expected"""
|
||||
start = datetime(2015, 1, 1, 12, 0, 0, tzinfo=utc)
|
||||
expected = "Jan 01, 2015 at 12:00 UTC"
|
||||
self.set_ccx_override('start', start)
|
||||
actual = self.ccx.start_datetime_text('DATE_TIME') # pylint: disable=no-member
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
@ddt.data((datetime(2015, 11, 1, 8, 59, 00, tzinfo=utc), "Nov 01, 2015", "Nov 01, 2015 at 01:59 PDT"),
|
||||
(datetime(2015, 11, 1, 9, 00, 00, tzinfo=utc), "Nov 01, 2015", "Nov 01, 2015 at 01:00 PST"))
|
||||
@ddt.unpack
|
||||
def test_start_date_time_zone(self, start_date_time, expected_short_date, expected_date_time):
|
||||
"""
|
||||
verify that start date is correctly converted when time zone specified
|
||||
during normal daylight hours and daylight savings hours
|
||||
"""
|
||||
time_zone = timezone('America/Los_Angeles')
|
||||
|
||||
self.set_ccx_override('start', start_date_time)
|
||||
actual_short_date = self.ccx.start_datetime_text(time_zone=time_zone) # pylint: disable=no-member
|
||||
actual_datetime = self.ccx.start_datetime_text('DATE_TIME', time_zone) # pylint: disable=no-member
|
||||
self.assertEqual(expected_short_date, actual_short_date)
|
||||
self.assertEqual(expected_date_time, actual_datetime)
|
||||
|
||||
@patch('util.date_utils.ugettext', fake_ugettext(translations={
|
||||
"SHORT_DATE_FORMAT": "%b %d, %Y",
|
||||
}))
|
||||
def test_end_datetime_short_date(self):
|
||||
"""verify that the end date for a ccx formats properly by default"""
|
||||
end = datetime(2015, 1, 1, 12, 0, 0, tzinfo=utc)
|
||||
expected = "Jan 01, 2015"
|
||||
self.set_ccx_override('due', end)
|
||||
actual = self.ccx.end_datetime_text() # pylint: disable=no-member
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
@patch('util.date_utils.ugettext', fake_ugettext(translations={
|
||||
"DATE_TIME_FORMAT": "%b %d, %Y at %H:%M",
|
||||
}))
|
||||
def test_end_datetime_date_time_format(self):
|
||||
"""verify that the DATE_TIME format also works as expected"""
|
||||
end = datetime(2015, 1, 1, 12, 0, 0, tzinfo=utc)
|
||||
expected = "Jan 01, 2015 at 12:00 UTC"
|
||||
self.set_ccx_override('due', end)
|
||||
actual = self.ccx.end_datetime_text('DATE_TIME') # pylint: disable=no-member
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
@ddt.data((datetime(2015, 11, 1, 8, 59, 00, tzinfo=utc), "Nov 01, 2015", "Nov 01, 2015 at 01:59 PDT"),
|
||||
(datetime(2015, 11, 1, 9, 00, 00, tzinfo=utc), "Nov 01, 2015", "Nov 01, 2015 at 01:00 PST"))
|
||||
@ddt.unpack
|
||||
def test_end_datetime_time_zone(self, end_date_time, expected_short_date, expected_date_time):
|
||||
"""
|
||||
verify that end date is correctly converted when time zone specified
|
||||
during normal daylight hours and daylight savings hours
|
||||
"""
|
||||
time_zone = timezone('America/Los_Angeles')
|
||||
|
||||
self.set_ccx_override('due', end_date_time)
|
||||
actual_short_date = self.ccx.end_datetime_text(time_zone=time_zone) # pylint: disable=no-member
|
||||
actual_datetime = self.ccx.end_datetime_text('DATE_TIME', time_zone) # pylint: disable=no-member
|
||||
self.assertEqual(expected_short_date, actual_short_date)
|
||||
self.assertEqual(expected_date_time, actual_datetime)
|
||||
|
||||
@patch('util.date_utils.ugettext', fake_ugettext(translations={
|
||||
"DATE_TIME_FORMAT": "%b %d, %Y at %H:%M",
|
||||
}))
|
||||
def test_end_datetime_no_due_date(self):
|
||||
"""verify that without a due date, the end date is an empty string"""
|
||||
expected = ''
|
||||
actual = self.ccx.end_datetime_text() # pylint: disable=no-member
|
||||
self.assertEqual(expected, actual)
|
||||
actual = self.ccx.end_datetime_text('DATE_TIME') # pylint: disable=no-member
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_ccx_max_student_enrollment_correct(self):
|
||||
"""
|
||||
Verify the override value for max_student_enrollments_allowed
|
||||
|
||||
@@ -12,7 +12,6 @@ from openedx.core.djangoapps.catalog.utils import get_programs as get_catalog_pr
|
||||
from openedx.core.djangoapps.credentials.utils import get_programs_credentials
|
||||
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
|
||||
from openedx.core.djangoapps.programs import utils
|
||||
from openedx.core.djangoapps.user_api.preferences.api import get_user_preferences
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -76,8 +75,7 @@ def program_details(request, program_id):
|
||||
'show_program_listing': programs_config.show_program_listing,
|
||||
'nav_hidden': True,
|
||||
'disable_courseware_js': True,
|
||||
'uses_pattern_library': True,
|
||||
'user_preferences': get_user_preferences(request.user)
|
||||
'uses_pattern_library': True
|
||||
}
|
||||
|
||||
return render_to_response('learner_dashboard/program_details.html', context)
|
||||
|
||||
@@ -332,7 +332,7 @@ class Order(models.Model):
|
||||
"""
|
||||
this function generates the csv file
|
||||
"""
|
||||
course_names = []
|
||||
course_info = []
|
||||
csv_file = StringIO.StringIO()
|
||||
csv_writer = csv.writer(csv_file)
|
||||
csv_writer.writerow(['Course Name', 'Registration Code', 'URL'])
|
||||
@@ -340,15 +340,15 @@ class Order(models.Model):
|
||||
course_id = item.course_id
|
||||
course = get_course_by_id(item.course_id, depth=0)
|
||||
registration_codes = CourseRegistrationCode.objects.filter(course_id=course_id, order=self)
|
||||
course_names.append(course.display_name)
|
||||
course_info.append((course.display_name, ' (' + course.start_datetime_text() + '-' + course.end_datetime_text() + ')'))
|
||||
for registration_code in registration_codes:
|
||||
redemption_url = reverse('register_code_redemption', args=[registration_code.code])
|
||||
url = '{base_url}{redemption_url}'.format(base_url=site_name, redemption_url=redemption_url)
|
||||
csv_writer.writerow([unicode(course.display_name).encode("utf-8"), registration_code.code, url])
|
||||
|
||||
return csv_file, course_names
|
||||
return csv_file, course_info
|
||||
|
||||
def send_confirmation_emails(self, orderitems, is_order_type_business, csv_file, pdf_file, site_name, course_names):
|
||||
def send_confirmation_emails(self, orderitems, is_order_type_business, csv_file, pdf_file, site_name, courses_info):
|
||||
"""
|
||||
send confirmation e-mail
|
||||
"""
|
||||
@@ -358,7 +358,8 @@ class Order(models.Model):
|
||||
joined_course_names = ""
|
||||
if self.recipient_email:
|
||||
recipient_list.append((self.recipient_name, self.recipient_email, 'email_recipient'))
|
||||
joined_course_names = " " + ", ".join(course_names)
|
||||
courses_names_with_dates = [course_info[0] + course_info[1] for course_info in courses_info]
|
||||
joined_course_names = " " + ", ".join(courses_names_with_dates)
|
||||
|
||||
if not is_order_type_business:
|
||||
subject = _("Order Payment Confirmation")
|
||||
@@ -386,7 +387,7 @@ class Order(models.Model):
|
||||
'recipient_type': recipient[2],
|
||||
'site_name': site_name,
|
||||
'order_items': orderitems,
|
||||
'course_names': ", ".join(course_names),
|
||||
'course_names': ", ".join([course_info[0] for course_info in courses_info]),
|
||||
'dashboard_url': dashboard_url,
|
||||
'currency_symbol': settings.PAID_COURSE_REGISTRATION_CURRENCY[1],
|
||||
'order_placed_by': '{username} ({email})'.format(
|
||||
@@ -476,13 +477,13 @@ class Order(models.Model):
|
||||
item.purchase_item()
|
||||
|
||||
csv_file = None
|
||||
course_names = []
|
||||
courses_info = []
|
||||
if self.order_type == OrderTypes.BUSINESS:
|
||||
#
|
||||
# Generate the CSV file that contains all of the RegistrationCodes that have already been
|
||||
# generated when the purchase has transacted
|
||||
#
|
||||
csv_file, course_names = self.generate_registration_codes_csv(orderitems, site_name)
|
||||
csv_file, courses_info = self.generate_registration_codes_csv(orderitems, site_name)
|
||||
|
||||
try:
|
||||
pdf_file = self.generate_pdf_receipt(orderitems)
|
||||
@@ -493,7 +494,7 @@ class Order(models.Model):
|
||||
try:
|
||||
self.send_confirmation_emails(
|
||||
orderitems, self.order_type == OrderTypes.BUSINESS,
|
||||
csv_file, pdf_file, site_name, course_names
|
||||
csv_file, pdf_file, site_name, courses_info
|
||||
)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
# Catch all exceptions here, since the Django view implicitly
|
||||
|
||||
@@ -514,6 +514,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
|
||||
response,
|
||||
unicode(course.id),
|
||||
course.display_name,
|
||||
course.start_datetime_text(),
|
||||
courseware_url
|
||||
)
|
||||
|
||||
@@ -965,11 +966,12 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
|
||||
else:
|
||||
self.assertFalse(displayed, msg="Expected '{req}' requirement to be hidden".format(req=req))
|
||||
|
||||
def _assert_course_details(self, response, course_key, display_name, url):
|
||||
def _assert_course_details(self, response, course_key, display_name, start_text, url):
|
||||
"""Check the course information on the page. """
|
||||
response_dict = self._get_page_data(response)
|
||||
self.assertEqual(response_dict['course_key'], course_key)
|
||||
self.assertEqual(response_dict['course_name'], display_name)
|
||||
self.assertEqual(response_dict['course_start_date'], start_text)
|
||||
self.assertEqual(response_dict['courseware_url'], url)
|
||||
|
||||
def _assert_user_details(self, response, full_name):
|
||||
@@ -999,6 +1001,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
|
||||
'full_name': pay_and_verify_div['data-full-name'],
|
||||
'course_key': pay_and_verify_div['data-course-key'],
|
||||
'course_name': pay_and_verify_div['data-course-name'],
|
||||
'course_start_date': pay_and_verify_div['data-course-start-date'],
|
||||
'courseware_url': pay_and_verify_div['data-courseware-url'],
|
||||
'course_mode_name': pay_and_verify_div['data-course-mode-name'],
|
||||
'course_mode_slug': pay_and_verify_div['data-course-mode-slug'],
|
||||
|
||||
@@ -5,23 +5,17 @@
|
||||
'js/discovery/views/search_form', 'js/discovery/views/courses_listing',
|
||||
'js/discovery/views/filter_bar', 'js/discovery/views/refine_sidebar'],
|
||||
function(Backbone, SearchState, Filters, SearchForm, CoursesListing, FilterBar, RefineSidebar) {
|
||||
return function(meanings, searchQuery, userLanguage, userTimezone) {
|
||||
return function(meanings, searchQuery) {
|
||||
var dispatcher = _.extend({}, Backbone.Events);
|
||||
var search = new SearchState();
|
||||
var filters = new Filters();
|
||||
var listing = new CoursesListing({model: search.discovery});
|
||||
var form = new SearchForm();
|
||||
var filterBar = new FilterBar({collection: filters});
|
||||
var refineSidebar = new RefineSidebar({
|
||||
collection: search.discovery.facetOptions,
|
||||
meanings: meanings
|
||||
});
|
||||
var listing;
|
||||
var courseListingModel = search.discovery;
|
||||
courseListingModel.userPreferences = {
|
||||
userLanguage: userLanguage,
|
||||
userTimezone: userTimezone
|
||||
};
|
||||
listing = new CoursesListing({model: courseListingModel});
|
||||
|
||||
dispatcher.listenTo(form, 'search', function(query) {
|
||||
filters.reset();
|
||||
|
||||
@@ -4,19 +4,24 @@
|
||||
'underscore',
|
||||
'backbone',
|
||||
'gettext',
|
||||
'edx-ui-toolkit/js/utils/date-utils'
|
||||
], function($, _, Backbone, gettext, DateUtils) {
|
||||
'date'
|
||||
], function($, _, Backbone, gettext, Date) {
|
||||
'use strict';
|
||||
|
||||
function formatDate(date, userLanguage, userTimezone) {
|
||||
var context;
|
||||
context = {
|
||||
datetime: date,
|
||||
language: userLanguage,
|
||||
timezone: userTimezone,
|
||||
format: DateUtils.dateFormatEnum.shortDate
|
||||
};
|
||||
return DateUtils.localize(context);
|
||||
function formatDate(date) {
|
||||
return dateUTC(date).toString('MMM dd, yyyy');
|
||||
}
|
||||
|
||||
// Return a date object using UTC time instead of local time
|
||||
function dateUTC(date) {
|
||||
return new Date(
|
||||
date.getUTCFullYear(),
|
||||
date.getUTCMonth(),
|
||||
date.getUTCDate(),
|
||||
date.getUTCHours(),
|
||||
date.getUTCMinutes(),
|
||||
date.getUTCSeconds()
|
||||
);
|
||||
}
|
||||
|
||||
return Backbone.View.extend({
|
||||
@@ -31,26 +36,8 @@
|
||||
|
||||
render: function() {
|
||||
var data = _.clone(this.model.attributes);
|
||||
var userLanguage = '',
|
||||
userTimezone = '';
|
||||
if (this.model.userPreferences !== undefined) {
|
||||
userLanguage = this.model.userPreferences.userLanguage;
|
||||
userTimezone = this.model.userPreferences.userTimezone;
|
||||
}
|
||||
if (data.advertised_start !== undefined) {
|
||||
data.start = data.advertised_start;
|
||||
} else {
|
||||
data.start = formatDate(
|
||||
new Date(data.start),
|
||||
userLanguage,
|
||||
userTimezone
|
||||
);
|
||||
}
|
||||
data.enrollment_start = formatDate(
|
||||
new Date(data.enrollment_start),
|
||||
userLanguage,
|
||||
userTimezone
|
||||
);
|
||||
data.start = formatDate(new Date(data.start));
|
||||
data.enrollment_start = formatDate(new Date(data.enrollment_start));
|
||||
this.$el.html(this.tpl(data));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -31,15 +31,12 @@
|
||||
},
|
||||
|
||||
renderItems: function() {
|
||||
/* eslint no-param-reassign: [2, { "props": true }] */
|
||||
var latest = this.model.latest();
|
||||
var items = latest.map(function(result) {
|
||||
result.userPreferences = this.model.userPreferences;
|
||||
var item = new CourseCardView({model: result});
|
||||
return item.render().el;
|
||||
}, this);
|
||||
this.$list.append(items);
|
||||
/* eslint no-param-reassign: [2, { "props": false }] */
|
||||
},
|
||||
|
||||
attachScrollHandler: function() {
|
||||
|
||||
@@ -4,15 +4,14 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define([
|
||||
'backbone',
|
||||
'edx-ui-toolkit/js/utils/date-utils'
|
||||
'backbone'
|
||||
],
|
||||
function(Backbone, DateUtils) {
|
||||
function(Backbone) {
|
||||
return Backbone.Model.extend({
|
||||
initialize: function(data) {
|
||||
if (data) {
|
||||
this.context = data;
|
||||
this.setActiveRunMode(this.getRunMode(data.run_modes), data.user_preferences);
|
||||
this.setActiveRunMode(this.getRunMode(data.run_modes));
|
||||
}
|
||||
},
|
||||
|
||||
@@ -32,7 +31,7 @@
|
||||
var enrolled_mode = _.findWhere(runModes, {is_enrolled: true}),
|
||||
openEnrollmentRunModes = this.getEnrollableRunModes(),
|
||||
desiredRunMode;
|
||||
// We populate our model by looking at the run modes.
|
||||
// We populate our model by looking at the run modes.
|
||||
if (enrolled_mode) {
|
||||
// If the learner is already enrolled in a run mode, return that one.
|
||||
desiredRunMode = enrolled_mode;
|
||||
@@ -65,44 +64,15 @@
|
||||
});
|
||||
},
|
||||
|
||||
formatDate: function(date, userPreferences) {
|
||||
var context,
|
||||
userTimezone = '',
|
||||
userLanguage = '';
|
||||
if (userPreferences !== undefined) {
|
||||
userTimezone = userPreferences.time_zone;
|
||||
userLanguage = userPreferences['pref-lang'];
|
||||
}
|
||||
context = {
|
||||
datetime: date,
|
||||
timezone: userTimezone,
|
||||
language: userLanguage,
|
||||
format: DateUtils.dateFormatEnum.shortDate
|
||||
};
|
||||
return DateUtils.localize(context);
|
||||
},
|
||||
|
||||
setActiveRunMode: function(runMode, userPreferences) {
|
||||
var startDateString;
|
||||
setActiveRunMode: function(runMode) {
|
||||
if (runMode) {
|
||||
if (runMode.advertised_start !== undefined && runMode.advertised_start !== 'None') {
|
||||
startDateString = runMode.advertised_start;
|
||||
} else {
|
||||
startDateString = this.formatDate(
|
||||
runMode.start_date,
|
||||
userPreferences
|
||||
);
|
||||
}
|
||||
this.set({
|
||||
certificate_url: runMode.certificate_url,
|
||||
course_image_url: runMode.course_image_url || '',
|
||||
course_key: runMode.course_key,
|
||||
course_url: runMode.course_url || '',
|
||||
display_name: this.context.display_name,
|
||||
end_date: this.formatDate(
|
||||
runMode.end_date,
|
||||
userPreferences
|
||||
),
|
||||
end_date: runMode.end_date,
|
||||
enrollable_run_modes: this.getEnrollableRunModes(),
|
||||
is_course_ended: runMode.is_course_ended,
|
||||
is_enrolled: runMode.is_enrolled,
|
||||
@@ -111,12 +81,13 @@
|
||||
marketing_url: runMode.marketing_url,
|
||||
mode_slug: runMode.mode_slug,
|
||||
run_key: runMode.run_key,
|
||||
start_date: startDateString,
|
||||
start_date: runMode.start_date,
|
||||
upcoming_run_modes: this.getUpcomingRunModes(),
|
||||
upgrade_url: runMode.upgrade_url
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
setUnselected: function() {
|
||||
// Called to reset the model back to the unselected state.
|
||||
var unselectedMode = this.getUnselectedRunMode(this.get('enrollable_run_modes'));
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
this.options = options;
|
||||
this.programModel = new Backbone.Model(this.options.programData);
|
||||
this.courseCardCollection = new CourseCardCollection(
|
||||
this.programModel.get('course_codes'),
|
||||
this.options.userPreferences
|
||||
this.programModel.get('course_codes')
|
||||
);
|
||||
this.render();
|
||||
},
|
||||
|
||||
@@ -47,7 +47,7 @@ define([
|
||||
expect(this.view.$el.find('.course-name')).toContainHtml(data.org);
|
||||
expect(this.view.$el.find('.course-name')).toContainHtml(data.content.number);
|
||||
expect(this.view.$el.find('.course-name')).toContainHtml(data.content.display_name);
|
||||
expect(this.view.$el.find('.course-date').text().trim()).toEqual('Starts: Jan 1, 1970');
|
||||
expect(this.view.$el.find('.course-date')).toContainHtml('Jan 01, 1970');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -30,9 +30,8 @@ define([
|
||||
context.run_modes[0].marketing_url
|
||||
);
|
||||
expect(view.$('.course-details .course-text .course-key').html()).toEqual(context.key);
|
||||
expect(view.$('.course-details .course-text .run-period').html()).toEqual(
|
||||
context.run_modes[0].start_date + ' - ' + context.run_modes[0].end_date
|
||||
);
|
||||
expect(view.$('.course-details .course-text .run-period').html())
|
||||
.toEqual(context.run_modes[0].start_date + ' - ' + context.run_modes[0].end_date);
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
@@ -93,15 +92,6 @@ define([
|
||||
validateCourseInfoDisplay();
|
||||
});
|
||||
|
||||
it('should show the course advertised start date', function() {
|
||||
var advertisedStart = 'This is an advertised start';
|
||||
context.run_modes[0].advertised_start = advertisedStart;
|
||||
setupView(context, false);
|
||||
expect(view.$('.course-details .course-text .run-period').html()).toEqual(
|
||||
advertisedStart + ' - ' + context.run_modes[0].end_date
|
||||
);
|
||||
});
|
||||
|
||||
it('should only show certificate status section if a certificate has been earned', function() {
|
||||
var certUrl = 'sample-certificate';
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ var edx = edx || {};
|
||||
'payment-confirmation-step': {
|
||||
courseKey: el.data('course-key'),
|
||||
courseName: el.data('course-name'),
|
||||
courseStartDate: el.data('course-start-date'),
|
||||
coursewareUrl: el.data('courseware-url'),
|
||||
platformName: el.data('platform-name'),
|
||||
requirements: el.data('requirements')
|
||||
@@ -93,6 +94,7 @@ var edx = edx || {};
|
||||
},
|
||||
'enrollment-confirmation-step': {
|
||||
courseName: el.data('course-name'),
|
||||
courseStartDate: el.data('course-start-date'),
|
||||
coursewareUrl: el.data('courseware-url'),
|
||||
platformName: el.data('platform-name')
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ var edx = edx || {};
|
||||
defaultContext: function() {
|
||||
return {
|
||||
courseName: '',
|
||||
courseStartDate: '',
|
||||
coursewareUrl: '',
|
||||
platformName: ''
|
||||
};
|
||||
|
||||
@@ -16,6 +16,7 @@ var edx = edx || {};
|
||||
return {
|
||||
courseKey: '',
|
||||
courseName: '',
|
||||
courseStartDate: '',
|
||||
coursewareUrl: '',
|
||||
platformName: '',
|
||||
requirements: []
|
||||
|
||||
@@ -20,9 +20,7 @@
|
||||
<%static:require_module module_name="js/discovery/discovery_factory" class_name="DiscoveryFactory">
|
||||
DiscoveryFactory(
|
||||
${course_discovery_meanings | n, dump_js_escaped_json},
|
||||
getParameterByName('search_query'),
|
||||
"${user_language}",
|
||||
"${user_timezone}"
|
||||
getParameterByName('search_query')
|
||||
);
|
||||
</%static:require_module>
|
||||
</%block>
|
||||
|
||||
@@ -16,7 +16,6 @@ from openedx.core.djangolib.js_utils import (
|
||||
ProgramDetailsFactory({
|
||||
programData: ${program_data | n, dump_js_escaped_json},
|
||||
urls: ${urls | n, dump_js_escaped_json},
|
||||
userPreferences: ${user_preferences | n, dump_js_escaped_json},
|
||||
});
|
||||
</%static:require_module>
|
||||
</%block>
|
||||
|
||||
@@ -301,6 +301,26 @@ from openedx.core.lib.courses import course_image_url
|
||||
<span class="course-registration-title">${_('Registration for:')}</span>
|
||||
<span class="course-display-name">${ course.display_name | h }</span>
|
||||
</h3>
|
||||
<p class="course-meta-info" aria-describedby="course-title">
|
||||
<span class="course-dates-title">
|
||||
<%
|
||||
course_start_time = course.start_datetime_text()
|
||||
course_end_time = course.end_datetime_text()
|
||||
%>
|
||||
% if course_start_time or course_end_time:
|
||||
${_("Course Dates")}:
|
||||
%endif
|
||||
</span>
|
||||
<span class="course-display-dates">
|
||||
% if course_start_time:
|
||||
${course_start_time}
|
||||
%endif
|
||||
-
|
||||
% if course_end_time:
|
||||
${course_end_time}
|
||||
%endif
|
||||
</span>
|
||||
</p>
|
||||
<hr>
|
||||
<div class="three-col">
|
||||
% if item.status == "purchased":
|
||||
|
||||
@@ -34,6 +34,12 @@ from openedx.core.lib.courses import course_image_url
|
||||
<div class="course-title">
|
||||
<h1>
|
||||
${_("{course_name}").format(course_name=course.display_name) | h}
|
||||
<span class="course-dates">
|
||||
${_("{start_date} - {end_date}").format(
|
||||
start_date=course.start_datetime_text(),
|
||||
end_date=course.end_datetime_text()
|
||||
)}
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
@@ -34,6 +34,11 @@ from openedx.core.lib.courses import course_image_url
|
||||
<div class="course-title">
|
||||
<h1>
|
||||
${course.display_name | h}
|
||||
<span class="course-dates">
|
||||
${course.start_datetime_text()}
|
||||
-
|
||||
${course.end_datetime_text()}
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
@@ -74,6 +74,10 @@ from openedx.core.lib.courses import course_image_url
|
||||
<span class="course-registration-title">${_('Registration for:')}</span>
|
||||
<span class="course-display-name">${ course.display_name }</span>
|
||||
</h3>
|
||||
<p class="course-meta-info" aria-describedby="course-title">
|
||||
<span class="course-dates-title">${_('Course Dates:')}</span>
|
||||
<span class="course-display-dates">${ course.start_datetime_text() } - ${ course.end_datetime_text() }</span>
|
||||
</p>
|
||||
<hr>
|
||||
<div class="three-col">
|
||||
<div class="col-1">
|
||||
|
||||
@@ -13,14 +13,16 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" ><%- gettext( "Course" ) %></th>
|
||||
<th scope="col" ></th>
|
||||
<th scope="col" ><%- gettext( "Status" ) %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><%- courseName %></td>
|
||||
<td></td>
|
||||
<td>
|
||||
<%- _.sprintf( gettext( "Starts: %(start)s" ), { start: courseStartDate } ) %>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ from lms.djangoapps.verify_student.views import PayAndVerifyView
|
||||
data-platform-name='${platform_name}'
|
||||
data-course-key='${course_key}'
|
||||
data-course-name='${course.display_name}'
|
||||
data-course-start-date='${course.start_datetime_text()}'
|
||||
data-courseware-url='${courseware_url}'
|
||||
data-course-mode-name='${course_mode.name}'
|
||||
data-course-mode-slug='${course_mode.slug}'
|
||||
@@ -123,3 +124,6 @@ from lms.djangoapps.verify_student.views import PayAndVerifyView
|
||||
</section>
|
||||
</div>
|
||||
</%block>
|
||||
<%static:require_module_async module_name="js/dateutil_factory" class_name="DateUtilFactory">
|
||||
DateUtilFactory.transform(iterationKey=".localized-datetime");
|
||||
</%static:require_module_async>
|
||||
|
||||
Reference in New Issue
Block a user