Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx-platform
Commits
849ad8df
Commit
849ad8df
authored
Jul 27, 2015
by
jsa
Committed by
Clinton Blackburn
Jul 28, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
commerce/api: Don’t allow setting expiration of prof modes.
XCOM-497
parent
7d8fb739
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
80 additions
and
4 deletions
+80
-4
common/djangoapps/course_modes/models.py
+12
-0
common/djangoapps/course_modes/tests/test_models.py
+39
-4
lms/djangoapps/commerce/api/v1/tests/test_views.py
+29
-0
No files found.
common/djangoapps/course_modes/models.py
View file @
849ad8df
...
...
@@ -4,6 +4,7 @@ Add and create new modes for running courses on this particular LMS
import
pytz
from
datetime
import
datetime
from
django.core.exceptions
import
ValidationError
from
django.db
import
models
from
collections
import
namedtuple
,
defaultdict
from
django.utils.translation
import
ugettext_lazy
as
_
...
...
@@ -106,8 +107,19 @@ class CourseMode(models.Model):
""" meta attributes of this model """
unique_together
=
(
'course_id'
,
'mode_slug'
,
'currency'
)
def
clean
(
self
):
"""
Object-level validation - implemented in this method so DRF serializers
catch errors in advance of a save() attempt.
"""
if
self
.
is_professional_slug
(
self
.
mode_slug
)
and
self
.
expiration_datetime
is
not
None
:
raise
ValidationError
(
_
(
u"Professional education modes are not allowed to have expiration_datetime set."
)
)
def
save
(
self
,
force_insert
=
False
,
force_update
=
False
,
using
=
None
):
# Ensure currency is always lowercase.
self
.
clean
()
# ensure object-level validation is performed before we save.
self
.
currency
=
self
.
currency
.
lower
()
super
(
CourseMode
,
self
)
.
save
(
force_insert
,
force_update
,
using
)
...
...
common/djangoapps/course_modes/tests/test_models.py
View file @
849ad8df
...
...
@@ -6,12 +6,15 @@ Replace this with more appropriate tests for your application.
"""
from
datetime
import
datetime
,
timedelta
import
pytz
import
ddt
import
itertools
import
ddt
from
django.core.exceptions
import
ValidationError
from
django.test
import
TestCase
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
opaque_keys.edx.locator
import
CourseLocator
from
django.test
import
TestCase
import
pytz
from
course_modes.models
import
CourseMode
,
Mode
...
...
@@ -26,7 +29,15 @@ class CourseModeModelTest(TestCase):
self
.
course_key
=
SlashSeparatedCourseKey
(
'Test'
,
'TestCourse'
,
'TestCourseRun'
)
CourseMode
.
objects
.
all
()
.
delete
()
def
create_mode
(
self
,
mode_slug
,
mode_name
,
min_price
=
0
,
suggested_prices
=
''
,
currency
=
'usd'
):
def
create_mode
(
self
,
mode_slug
,
mode_name
,
min_price
=
0
,
suggested_prices
=
''
,
currency
=
'usd'
,
expiration_datetime
=
None
,
):
"""
Create a new course mode
"""
...
...
@@ -37,6 +48,7 @@ class CourseModeModelTest(TestCase):
min_price
=
min_price
,
suggested_prices
=
suggested_prices
,
currency
=
currency
,
expiration_datetime
=
expiration_datetime
,
)
def
test_save
(
self
):
...
...
@@ -264,6 +276,29 @@ class CourseModeModelTest(TestCase):
else
:
self
.
assertFalse
(
CourseMode
.
is_verified_slug
(
mode_slug
))
@ddt.data
(
*
itertools
.
product
(
(
CourseMode
.
HONOR
,
CourseMode
.
AUDIT
,
CourseMode
.
VERIFIED
,
CourseMode
.
PROFESSIONAL
,
CourseMode
.
NO_ID_PROFESSIONAL_MODE
),
(
datetime
.
now
(),
None
),
))
@ddt.unpack
def
test_invalid_mode_expiration
(
self
,
mode_slug
,
exp_dt
):
is_error_expected
=
CourseMode
.
is_professional_slug
(
mode_slug
)
and
exp_dt
is
not
None
try
:
self
.
create_mode
(
mode_slug
=
mode_slug
,
mode_name
=
mode_slug
.
title
(),
expiration_datetime
=
exp_dt
)
self
.
assertFalse
(
is_error_expected
,
"Expected a ValidationError to be thrown."
)
except
ValidationError
,
exc
:
self
.
assertTrue
(
is_error_expected
,
"Did not expect a ValidationError to be thrown."
)
self
.
assertEqual
(
exc
.
messages
,
[
u"Professional education modes are not allowed to have expiration_datetime set."
],
)
@ddt.data
(
(
"verified"
,
"verify_need_to_verify"
),
(
"verified"
,
"verify_submitted"
),
...
...
lms/djangoapps/commerce/api/v1/tests/test_views.py
View file @
849ad8df
""" Commerce API v1 view tests. """
from
datetime
import
datetime
import
itertools
import
json
import
ddt
...
...
@@ -158,6 +159,34 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
# The existing CourseMode should have been removed.
self
.
assertFalse
(
CourseMode
.
objects
.
filter
(
id
=
self
.
course_mode
.
id
)
.
exists
())
@ddt.data
(
*
itertools
.
product
(
(
'honor'
,
'audit'
,
'verified'
,
'professional'
,
'no-id-professional'
),
(
datetime
.
now
(),
None
),
))
@ddt.unpack
def
test_update_professional_expiration
(
self
,
mode_slug
,
expiration_datetime
):
""" Verify that pushing a mode with a professional certificate and an expiration datetime
will be rejected (this is not allowed). """
permission
=
Permission
.
objects
.
get
(
name
=
'Can change course mode'
)
self
.
user
.
user_permissions
.
add
(
permission
)
mode
=
self
.
_serialize_course_mode
(
CourseMode
(
mode_slug
=
mode_slug
,
min_price
=
500
,
currency
=
u'USD'
,
sku
=
u'ABC123'
,
expiration_datetime
=
expiration_datetime
)
)
course_id
=
unicode
(
self
.
course
.
id
)
payload
=
{
u'id'
:
course_id
,
u'modes'
:
[
mode
]}
path
=
reverse
(
'commerce_api:v1:courses:retrieve_update'
,
args
=
[
course_id
])
expected_status
=
400
if
CourseMode
.
is_professional_slug
(
mode_slug
)
and
expiration_datetime
is
not
None
else
200
response
=
self
.
client
.
put
(
path
,
json
.
dumps
(
payload
),
content_type
=
JSON_CONTENT_TYPE
)
self
.
assertEqual
(
response
.
status_code
,
expected_status
)
def
assert_can_create_course
(
self
,
**
request_kwargs
):
""" Verify a course can be created by the view. """
course
=
CourseFactory
.
create
()
...
...
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