Commit 04c4a14b by Clinton Blackburn

Merge pull request #263 from edx/clintonb/verification-deadline-fix

Fixed display of verification deadline on course form
parents 1873a530 57345d37
...@@ -9,7 +9,8 @@ define([ ...@@ -9,7 +9,8 @@ define([
'collections/product_collection', 'collections/product_collection',
'models/course_seats/course_seat', 'models/course_seats/course_seat',
'models/course_seats/honor_seat', 'models/course_seats/honor_seat',
'utils/course_utils' 'utils/course_utils',
'utils/utils'
], ],
function (Backbone, function (Backbone,
BackboneRelational, BackboneRelational,
...@@ -21,7 +22,8 @@ define([ ...@@ -21,7 +22,8 @@ define([
ProductCollection, ProductCollection,
CourseSeat, CourseSeat,
HonorSeat, HonorSeat,
CourseUtils) { CourseUtils,
Utils) {
'use strict'; 'use strict';
Backbone.Validation.configure({ Backbone.Validation.configure({
...@@ -59,13 +61,6 @@ define([ ...@@ -59,13 +61,6 @@ define([
type: { type: {
required: true, required: true,
msg: gettext('You must select a course type.') msg: gettext('You must select a course type.')
},
verification_deadline: {
msg: gettext('Verification deadline is required for course types with verified modes.'),
required: function (value, attr, computedState) {
// TODO Return true if one of the products requires ID verification.
return false;
}
} }
}, },
...@@ -100,6 +95,26 @@ define([ ...@@ -100,6 +95,26 @@ define([
this.on('sync', this.removeParentProducts, this); this.on('sync', this.removeParentProducts, this);
}, },
parse: function (response) {
response = this._super(response);
// Form fields display date-times in the user's local timezone. We want all
// times to be displayed in UTC to avoid confusion. Strip the timezone data to workaround the UI
// deficiencies. We will restore the UTC timezone in toJSON().
response.verification_deadline = Utils.stripTimezone(response.verification_deadline);
return response;
},
toJSON: function () {
var data = this._super();
// Restore the timezone component, and output the ISO 8601 format expected by the server.
data.verification_deadline = Utils.restoreTimezone(data.verification_deadline);
return data;
},
/** /**
* Alerts listeners that this Course's ID verification status MAY have changed. * Alerts listeners that this Course's ID verification status MAY have changed.
*/ */
......
...@@ -3,13 +3,15 @@ define([ ...@@ -3,13 +3,15 @@ define([
'backbone.relational', 'backbone.relational',
'backbone.validation', 'backbone.validation',
'moment', 'moment',
'underscore' 'underscore',
'utils/utils'
], ],
function (Backbone, function (Backbone,
BackboneRelational, BackboneRelational,
BackboneValidation, BackboneValidation,
moment, moment,
_) { _,
Utils) {
'use strict'; 'use strict';
_.extend(Backbone.Model.prototype, Backbone.Validation.mixin); _.extend(Backbone.Model.prototype, Backbone.Validation.mixin);
...@@ -27,12 +29,10 @@ define([ ...@@ -27,12 +29,10 @@ define([
delete response.attribute_values; delete response.attribute_values;
// The view displaying the expires value assumes times are in the user's local timezone. We want all // Form fields display date-times in the user's local timezone. We want all
// times to be displayed in UTC to avoid confusion. Strip the timezone data to workaround the UI // times to be displayed in UTC to avoid confusion. Strip the timezone data to workaround the UI
// deficiencies. We will restore the UTC timezone in toJSON(). // deficiencies. We will restore the UTC timezone in toJSON().
if (response.expires) { response.expires = Utils.stripTimezone(response.expires);
response.expires = moment.utc(response.expires).format('YYYY-MM-DDTHH:mm:ss');
}
return response; return response;
}, },
...@@ -54,9 +54,7 @@ define([ ...@@ -54,9 +54,7 @@ define([
}, this); }, this);
// Restore the timezone component, and output the ISO 8601 format expected by the server. // Restore the timezone component, and output the ISO 8601 format expected by the server.
if (data.expires) { data.expires = Utils.restoreTimezone(data.expires);
data.expires = moment.utc(data.expires + 'Z').format();
}
return data; return data;
} }
......
define([
'utils/utils'],
function (Utils) {
describe('stripTimezone', function(){
it('should return the input value if the input is empty', function(){
expect(Utils.stripTimezone('')).toEqual('');
expect(Utils.stripTimezone(null)).toBeNull();
expect(Utils.stripTimezone(undefined)).toBeUndefined();
});
it('should return the datetime without the timezone component', function(){
var dt = '2015-01-01T00:00:00';
expect(Utils.stripTimezone(dt + 'Z')).toEqual(dt);
});
});
describe('restoreTimezone', function(){
it('should return the input value if the input is empty', function(){
expect(Utils.restoreTimezone('')).toEqual('');
expect(Utils.restoreTimezone(null)).toBeNull();
expect(Utils.restoreTimezone(undefined)).toBeUndefined();
});
it('should return the datetime with the timezone component', function(){
var dt = '2015-01-01T00:00:00';
expect(Utils.restoreTimezone(dt)).toEqual(dt + '+00:00');
});
});
}
);
\ No newline at end of file
define(['underscore'], function (_) { define([
'use strict'; 'moment',
'underscore'],
function (moment,
_) {
'use strict';
var utils = { return {
/** /**
* Returns the attributes of a node. * Returns the attributes of a node.
* *
* @param nodeAttributes Attributes of the node. * @param nodeAttributes Attributes of the node.
* @param startsWithAndStrip Filters only attributes that start with * @param startsWithAndStrip Filters only attributes that start with
* this string and strips it off the attribute. * this string and strips it off the attribute.
* @param blackList Exclude attributes in this array of strings. * @param blackList Exclude attributes in this array of strings.
* @returns Hash of found attributes. * @returns Hash of found attributes.
*/ */
getNodeProperties: function (nodeAttributes, startsWithAndStrip, blackList) { getNodeProperties: function (nodeAttributes, startsWithAndStrip, blackList) {
var properties = {}; var properties = {};
// fill in defaults // fill in defaults
startsWithAndStrip = startsWithAndStrip || ''; startsWithAndStrip = startsWithAndStrip || '';
blackList = blackList || []; blackList = blackList || [];
_(_(nodeAttributes.length).range()).each(function (i) { _(_(nodeAttributes.length).range()).each(function (i) {
var nodeName = nodeAttributes.item(i).nodeName, var nodeName = nodeAttributes.item(i).nodeName,
strippedName; strippedName;
// filter the attributes to just the ones that start with our // filter the attributes to just the ones that start with our
// selection and aren't in our blacklist // selection and aren't in our blacklist
if (nodeName.indexOf(startsWithAndStrip) === 0 && !_(blackList).contains(nodeName)) { if (nodeName.indexOf(startsWithAndStrip) === 0 && !_(blackList).contains(nodeName)) {
// remove the // remove the
strippedName = nodeName.replace(startsWithAndStrip, ''); strippedName = nodeName.replace(startsWithAndStrip, '');
properties[strippedName] = properties[strippedName] =
nodeAttributes.item(i).value; nodeAttributes.item(i).value;
}
});
return properties;
},
/**
* Strips the timezone component from a datetime string.
*
* Input is assumed to be in UTC timezone. Output datetime is formatted as
* ISO 8601 without the timezone component.
*
* @param {String} datetime - String representing a UTC datetime
* @returns {String}
*/
stripTimezone: function (datetime) {
if (datetime) {
datetime = moment.utc(datetime).format('YYYY-MM-DDTHH:mm:ss');
} }
});
return properties;
}
};
return utils; return datetime;
}); },
/**
* Adds the UTC timezone to a given datetime string.
*
* Output is formatted as ISO 8601.
*
* @param {String} datetime - String representing a datetime WITHOUT a timezone component
* @returns {String}
*/
restoreTimezone: function (datetime) {
if (datetime) {
datetime = moment.utc(datetime + 'Z').format();
}
return datetime;
}
};
});
...@@ -118,12 +118,7 @@ define([ ...@@ -118,12 +118,7 @@ define([
validate: true validate: true
} }
}, },
'input[name=verification_deadline]': { 'input[name=verification_deadline]': 'verification_deadline'
observe: 'verification_deadline',
setOptions: {
validate: true
}
}
}, },
initialize: function (options) { initialize: function (options) {
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
<div class="fields"> <div class="fields">
<div class="form-group verification-deadline hidden"> <div class="form-group verification-deadline hidden">
<label class="hd-4" for="verification_deadline"><%= gettext('Verification Deadline') %></label> <label class="hd-4" for="verificationDeadline"><%= gettext('Verification Deadline') %></label>
<div class="input-group"> <div class="input-group">
<div class="input-group-addon"><i class="fa fa-calendar" aria-hidden="true"></i></div> <div class="input-group-addon"><i class="fa fa-calendar" aria-hidden="true"></i></div>
......
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