Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
ecommerce
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
ecommerce
Commits
3ce4d09e
Commit
3ce4d09e
authored
Sep 02, 2015
by
Clinton Blackburn
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #291 from edx/clintonb/date-validation
Validating course seat upgrade deadline
parents
3e3ca2da
7ab6d43a
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
116 additions
and
22 deletions
+116
-22
ecommerce/static/js/collections/product_collection.js
+22
-1
ecommerce/static/js/models/course_model.js
+5
-4
ecommerce/static/js/models/course_seats/course_seat.js
+21
-2
ecommerce/static/js/test/specs/models/course_seats/course_seat_spec.js
+34
-0
ecommerce/static/js/views/course_seat_form_fields/course_seat_form_field_view.js
+6
-1
ecommerce/static/js/views/course_seat_form_fields/credit_course_seat_form_field_row_view.js
+6
-1
ecommerce/static/templates/audit_course_seat_form_field.html
+1
-1
ecommerce/static/templates/professional_course_seat_form_field.html
+11
-6
ecommerce/static/templates/verified_course_seat_form_field.html
+10
-6
No files found.
ecommerce/static/js/collections/product_collection.js
View file @
3ce4d09e
define
([
define
([
'backbone'
,
'backbone'
,
'utils/utils'
'underscore'
,
'utils/utils'
,
'backbone.super'
],
],
function
(
Backbone
,
function
(
Backbone
,
_
,
Utils
)
{
Utils
)
{
'use strict'
;
'use strict'
;
return
Backbone
.
Collection
.
extend
({
return
Backbone
.
Collection
.
extend
({
initialize
:
function
(
models
,
options
)
{
// NOTE (CCB): This is a hack to workaround an issue with Backbone.relational's reverseRelation
// not working properly.
if
(
options
)
{
this
.
course
=
options
.
course
;
}
},
/**
/**
* Validates the collection by iterating over the nested models.
* Validates the collection by iterating over the nested models.
*
*
...
@@ -14,6 +25,16 @@ define([
...
@@ -14,6 +25,16 @@ define([
*/
*/
isValid
:
function
()
{
isValid
:
function
()
{
return
Utils
.
areModelsValid
(
this
.
models
);
return
Utils
.
areModelsValid
(
this
.
models
);
},
set
:
function
(
models
,
options
)
{
_
.
each
(
models
,
function
(
model
)
{
if
(
_
.
isObject
(
model
))
{
model
.
course
=
this
.
course
;
}
},
this
);
this
.
_super
(
models
,
options
);
}
}
});
});
}
}
...
...
ecommerce/static/js/models/course_model.js
View file @
3ce4d09e
...
@@ -11,7 +11,6 @@ define([
...
@@ -11,7 +11,6 @@ define([
'underscore'
,
'underscore'
,
'collections/product_collection'
,
'collections/product_collection'
,
'models/course_seats/course_seat'
,
'models/course_seats/course_seat'
,
'models/course_seats/honor_seat'
,
'utils/course_utils'
,
'utils/course_utils'
,
'utils/utils'
'utils/utils'
],
],
...
@@ -25,7 +24,6 @@ define([
...
@@ -25,7 +24,6 @@ define([
_
,
_
,
ProductCollection
,
ProductCollection
,
CourseSeat
,
CourseSeat
,
HonorSeat
,
CourseUtils
,
CourseUtils
,
Utils
)
{
Utils
)
{
'use strict'
;
'use strict'
;
...
@@ -102,7 +100,10 @@ define([
...
@@ -102,7 +100,10 @@ define([
key
:
'products'
,
key
:
'products'
,
relatedModel
:
CourseSeat
,
relatedModel
:
CourseSeat
,
includeInJSON
:
false
,
includeInJSON
:
false
,
parse
:
true
parse
:
true
,
collectionOptions
:
function
(
model
)
{
return
{
course
:
model
};
}
}],
}],
/**
/**
...
@@ -196,7 +197,7 @@ define([
...
@@ -196,7 +197,7 @@ define([
if
(
_
.
isEmpty
(
seats
)
&&
_
.
contains
(
this
.
creatableSeatTypes
,
seatType
))
{
if
(
_
.
isEmpty
(
seats
)
&&
_
.
contains
(
this
.
creatableSeatTypes
,
seatType
))
{
seatClass
=
CourseUtils
.
getCourseSeatModel
(
seatType
);
seatClass
=
CourseUtils
.
getCourseSeatModel
(
seatType
);
/*jshint newcap: false */
/*jshint newcap: false */
seat
=
new
seatClass
();
seat
=
new
seatClass
(
{
course
:
this
}
);
/*jshint newcap: true */
/*jshint newcap: true */
this
.
get
(
'products'
).
add
(
seat
);
this
.
get
(
'products'
).
add
(
seat
);
seats
.
push
(
seat
);
seats
.
push
(
seat
);
...
...
ecommerce/static/js/models/course_seats/course_seat.js
View file @
3ce4d09e
define
([
define
([
'moment'
,
'models/product_model'
'models/product_model'
],
],
function
(
ProductModel
)
{
function
(
moment
,
Product
)
{
'use strict'
;
'use strict'
;
return
Product
Model
.
extend
({
return
Product
.
extend
({
defaults
:
{
defaults
:
{
certificate_type
:
null
,
certificate_type
:
null
,
expires
:
null
,
expires
:
null
,
...
@@ -15,6 +17,8 @@ define([
...
@@ -15,6 +17,8 @@ define([
product_class
:
'Seat'
product_class
:
'Seat'
},
},
course
:
null
,
validation
:
{
validation
:
{
price
:
{
price
:
{
required
:
true
,
required
:
true
,
...
@@ -23,6 +27,21 @@ define([
...
@@ -23,6 +27,21 @@ define([
},
},
product_class
:
{
product_class
:
{
oneOf
:
[
'Seat'
]
oneOf
:
[
'Seat'
]
},
expires
:
function
(
value
)
{
var
verificationDeadline
,
course
=
this
.
course
;
// No validation is needed for empty values or seats not linked to courses.
if
(
_
.
isEmpty
(
value
)
||
!
course
)
{
return
;
}
// Determine if the supplied expiration date occurs after the course verification deadline.
verificationDeadline
=
course
.
get
(
'verification_deadline'
);
if
(
verificationDeadline
&&
!
moment
(
value
).
isBefore
(
verificationDeadline
))
{
return
gettext
(
'The upgrade deadline must occur BEFORE the verification deadline.'
);
}
}
}
},
},
...
...
ecommerce/static/js/test/specs/models/course_seats/course_seat_spec.js
View file @
3ce4d09e
define
([
define
([
'underscore'
,
'underscore'
,
'models/course_model'
,
'models/course_seats/course_seat'
'models/course_seats/course_seat'
],
],
function
(
_
,
function
(
_
,
Course
,
CourseSeat
)
{
CourseSeat
)
{
'use strict'
;
'use strict'
;
...
@@ -114,6 +116,38 @@ define([
...
@@ -114,6 +116,38 @@ define([
});
});
});
});
});
});
describe
(
'expires validation'
,
function
()
{
function
assertExpiresInvalid
(
expires
,
verification_deadline
)
{
var
msg
=
'The upgrade deadline must occur BEFORE the verification deadline.'
;
model
.
set
(
'expires'
,
expires
);
model
.
course
=
Course
.
findOrCreate
({
id
:
'a/b/c'
,
verification_deadline
:
verification_deadline
});
expect
(
model
.
validate
().
expires
).
toEqual
(
msg
);
expect
(
model
.
isValid
(
true
)).
toBeFalsy
();
}
it
(
'should do nothing if the CourseSeat has no associated Course'
,
function
()
{
model
.
course
=
null
;
expect
(
model
.
validation
.
expires
(
'2015-01-01'
)).
toBeUndefined
();
});
it
(
'should do nothing if the CourseSeat has no expiration value set'
,
function
()
{
expect
(
model
.
validation
.
expires
(
null
)).
toBeUndefined
();
expect
(
model
.
validation
.
expires
(
undefined
)).
toBeUndefined
();
});
it
(
'should return a message if the CourseSeat expires after the Course verification deadline'
,
function
()
{
assertExpiresInvalid
(
'2016-01-01'
,
'2014-01-01'
);
}
);
it
(
'should return a message if the CourseSeat expires at the same time verification closes'
,
function
()
{
assertExpiresInvalid
(
'2016-01-01'
,
'2016-01-01'
);
}
);
});
});
});
}
}
);
);
ecommerce/static/js/views/course_seat_form_fields/course_seat_form_field_view.js
View file @
3ce4d09e
...
@@ -29,7 +29,12 @@ define([
...
@@ -29,7 +29,12 @@ define([
validate
:
true
validate
:
true
}
}
},
},
'input[name=expires]'
:
'expires'
,
'input[name=expires]'
:
{
observe
:
'expires'
,
setOptions
:
{
validate
:
true
}
},
'input[name=id_verification_required]'
:
{
'input[name=id_verification_required]'
:
{
observe
:
'id_verification_required'
,
observe
:
'id_verification_required'
,
onSet
:
'cleanIdVerificationRequired'
onSet
:
'cleanIdVerificationRequired'
...
...
ecommerce/static/js/views/course_seat_form_fields/credit_course_seat_form_field_row_view.js
View file @
3ce4d09e
...
@@ -36,7 +36,12 @@ define([
...
@@ -36,7 +36,12 @@ define([
validate
:
true
validate
:
true
}
}
},
},
'input[name=expires]'
:
'expires'
'input[name=expires]'
:
{
observe
:
'expires'
,
setOptions
:
{
validate
:
true
}
}
},
},
initialize
:
function
(
options
)
{
initialize
:
function
(
options
)
{
...
...
ecommerce/static/templates/audit_course_seat_form_field.html
View file @
3ce4d09e
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
<div
class=
"col-sm-4"
>
<div
class=
"col-sm-4"
>
<span
class=
"price-label"
><
%=
gettext
('
Price
(
in
USD
)')
%
>
:
</span>
<span
class=
"seat-price"
>
$0.00
</span>
<span
class=
"price-label"
><
%=
gettext
('
Price
(
in
USD
)')
%
>
:
</span>
<span
class=
"seat-price"
>
$0.00
</span>
<input
type=
"hidden"
name=
"price"
value=
"0"
>
<input
type=
"hidden"
name=
"price"
value=
"0"
>
<input
type=
"hidden"
name=
"certificate_type"
value=
""
>
<input
type=
"hidden"
name=
"certificate_type"
>
<input
type=
"hidden"
name=
"id_verification_required"
value=
"false"
>
<input
type=
"hidden"
name=
"id_verification_required"
value=
"false"
>
</div>
</div>
<div
class=
"col-sm-4 seat-certificate-type"
>
<div
class=
"col-sm-4 seat-certificate-type"
>
...
...
ecommerce/static/templates/professional_course_seat_form_field.html
View file @
3ce4d09e
...
@@ -19,16 +19,21 @@
...
@@ -19,16 +19,21 @@
</div>
</div>
<div
class=
"expires"
>
<div
class=
"expires"
>
<label
for=
"expires"
><
%=
gettext
('
Upgrade
Deadline
')
%
></label>
<div
class=
"form-group"
>
<label
for=
"expires"
><
%=
gettext
('
Upgrade
Deadline
')
%
></label>
<div
class=
"input-group"
data-toggle=
"tooltip"
title=
"<%= gettext('Professional education courses have no upgrade deadline.') %>"
>
<div
class=
"input-group"
data-toggle=
"tooltip"
<div
class=
"input-group-addon"
><i
class=
"fa fa-calendar"
aria-hidden=
"true"
></i></div>
title=
"<%= gettext('Professional education courses have no upgrade deadline.') %>"
>
<input
type=
"datetime-local"
id=
"expires"
name=
"expires"
class=
"form-control"
value=
""
<div
class=
"input-group-addon"
><i
class=
"fa fa-calendar"
aria-hidden=
"true"
></i></div>
aria-describedby=
"expiresHelpBlock"
disabled=
"disabled"
>
<input
type=
"datetime-local"
id=
"expires"
name=
"expires"
class=
"form-control"
</div>
aria-describedby=
"expiresHelpBlock"
disabled=
"disabled"
>
</div>
<!-- NOTE: This help-block is here for validation messages. -->
<span
class=
"help-block"
></span>
<span
id=
"expiresHelpBlock"
class=
"help-block"
>
<span
id=
"expiresHelpBlock"
class=
"help-block"
>
<
%=
gettext
('
After
this
date
/
time
,
students
can
no
longer
enroll
in
this
track
.')
%
>
<
%=
gettext
('
After
this
date
/
time
,
students
can
no
longer
enroll
in
this
track
.')
%
>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
<div
class=
"col-sm-4 seat-certificate-type"
>
<div
class=
"col-sm-4 seat-certificate-type"
>
...
...
ecommerce/static/templates/verified_course_seat_form_field.html
View file @
3ce4d09e
...
@@ -20,16 +20,20 @@
...
@@ -20,16 +20,20 @@
</div>
</div>
<div
class=
"expires"
>
<div
class=
"expires"
>
<label
for=
"expires"
><
%=
gettext
('
Upgrade
Deadline
')
%
></label>
<div
class=
"form-group"
>
<label
for=
"expires"
><
%=
gettext
('
Upgrade
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>
<input
type=
"datetime-local"
id=
"expires"
name=
"expires"
class=
"form-control"
value=
""
<input
type=
"datetime-local"
id=
"expires"
name=
"expires"
class=
"form-control"
aria-describedby=
"expiresHelpBlock"
>
aria-describedby=
"expiresHelpBlock"
>
</div>
</div>
<!-- NOTE: This help-block is here for validation messages. -->
<span
class=
"help-block"
></span>
<span
id=
"expiresHelpBlock"
class=
"help-block"
>
<span
id=
"expiresHelpBlock"
class=
"help-block"
>
<
%=
gettext
('
After
this
date
/
time
,
students
can
no
longer
enroll
in
this
track
.')
%
>
<
%=
gettext
('
After
this
date
/
time
,
students
can
no
longer
enroll
in
this
track
.')
%
>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
<div
class=
"col-sm-4 seat-certificate-type"
>
<div
class=
"col-sm-4 seat-certificate-type"
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment