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
7449f685
Commit
7449f685
authored
Jul 14, 2015
by
jsa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support setting email opt-in in calls to the Otto shim
XCOM-499
parent
d4a5ad48
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
56 additions
and
6 deletions
+56
-6
lms/djangoapps/commerce/api/v0/tests/test_views.py
+31
-4
lms/djangoapps/commerce/api/v0/views.py
+25
-2
No files found.
lms/djangoapps/commerce/api/v0/tests/test_views.py
View file @
7449f685
""" Commerce API v0 view tests. """
""" Commerce API v0 view tests. """
import
json
import
json
import
itertools
from
uuid
import
uuid4
from
uuid
import
uuid4
from
nose.plugins.attrib
import
attr
import
ddt
import
ddt
from
django.conf
import
settings
from
django.conf
import
settings
...
@@ -9,6 +9,7 @@ from django.core.urlresolvers import reverse
...
@@ -9,6 +9,7 @@ from django.core.urlresolvers import reverse
from
django.test
import
TestCase
from
django.test
import
TestCase
from
django.test.utils
import
override_settings
from
django.test.utils
import
override_settings
import
mock
import
mock
from
nose.plugins.attrib
import
attr
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
...
@@ -33,7 +34,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
...
@@ -33,7 +34,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
"""
"""
Tests for the commerce orders view.
Tests for the commerce orders view.
"""
"""
def
_post_to_view
(
self
,
course_id
=
None
):
def
_post_to_view
(
self
,
course_id
=
None
,
marketing_email_opt_in
=
False
):
"""
"""
POST to the view being tested.
POST to the view being tested.
...
@@ -42,8 +43,12 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
...
@@ -42,8 +43,12 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
:return: Response
:return: Response
"""
"""
course_id
=
unicode
(
course_id
or
self
.
course
.
id
)
payload
=
{
return
self
.
client
.
post
(
self
.
url
,
{
'course_id'
:
course_id
})
"course_id"
:
unicode
(
course_id
or
self
.
course
.
id
)
}
if
marketing_email_opt_in
:
payload
[
"email_opt_in"
]
=
True
return
self
.
client
.
post
(
self
.
url
,
payload
)
def
assertResponseMessage
(
self
,
response
,
expected_msg
):
def
assertResponseMessage
(
self
,
response
,
expected_msg
):
""" Asserts the detail field in the response's JSON body equals the expected message. """
""" Asserts the detail field in the response's JSON body equals the expected message. """
...
@@ -297,6 +302,28 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
...
@@ -297,6 +302,28 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
with
mock_create_basket
():
with
mock_create_basket
():
self
.
_test_successful_ecommerce_api_call
(
False
)
self
.
_test_successful_ecommerce_api_call
(
False
)
@mock.patch
(
'commerce.api.v0.views.update_email_opt_in'
)
@ddt.data
(
*
itertools
.
product
((
False
,
True
),
(
False
,
True
),
(
False
,
True
)))
@ddt.unpack
def
test_marketing_email_opt_in
(
self
,
is_opt_in
,
has_sku
,
is_exception
,
mock_update
):
"""
Ensures the email opt-in flag is handled, if present, and that problems handling the
flag don't cause the rest of the enrollment transaction to fail.
"""
if
not
has_sku
:
for
course_mode
in
CourseMode
.
objects
.
filter
(
course_id
=
self
.
course
.
id
):
course_mode
.
sku
=
None
course_mode
.
save
()
if
is_exception
:
mock_update
.
side_effect
=
Exception
(
"boink"
)
return_value
=
{
'id'
:
TEST_BASKET_ID
,
'payment_data'
:
None
,
'order'
:
{
'number'
:
TEST_ORDER_NUMBER
}}
with
mock_create_basket
(
response
=
return_value
,
expect_called
=
has_sku
):
response
=
self
.
_post_to_view
(
marketing_email_opt_in
=
is_opt_in
)
self
.
assertEqual
(
mock_update
.
called
,
is_opt_in
)
self
.
assertEqual
(
response
.
status_code
,
200
)
@attr
(
'shard_1'
)
@attr
(
'shard_1'
)
@override_settings
(
ECOMMERCE_API_URL
=
TEST_API_URL
,
ECOMMERCE_API_SIGNING_KEY
=
TEST_API_SIGNING_KEY
)
@override_settings
(
ECOMMERCE_API_URL
=
TEST_API_URL
,
ECOMMERCE_API_SIGNING_KEY
=
TEST_API_SIGNING_KEY
)
...
...
lms/djangoapps/commerce/api/v0/views.py
View file @
7449f685
...
@@ -19,6 +19,7 @@ from courseware import courses
...
@@ -19,6 +19,7 @@ from courseware import courses
from
embargo
import
api
as
embargo_api
from
embargo
import
api
as
embargo_api
from
enrollment.api
import
add_enrollment
from
enrollment.api
import
add_enrollment
from
enrollment.views
import
EnrollmentCrossDomainSessionAuth
from
enrollment.views
import
EnrollmentCrossDomainSessionAuth
from
openedx.core.djangoapps.user_api.preferences.api
import
update_email_opt_in
from
openedx.core.lib.api.authentication
import
OAuth2AuthenticationAllowInactiveUser
from
openedx.core.lib.api.authentication
import
OAuth2AuthenticationAllowInactiveUser
from
student.models
import
CourseEnrollment
from
student.models
import
CourseEnrollment
from
util.json_request
import
JsonResponse
from
util.json_request
import
JsonResponse
...
@@ -62,6 +63,22 @@ class BasketsView(APIView):
...
@@ -62,6 +63,22 @@ class BasketsView(APIView):
""" Enroll the user in the course. """
""" Enroll the user in the course. """
add_enrollment
(
user
.
username
,
unicode
(
course_key
))
add_enrollment
(
user
.
username
,
unicode
(
course_key
))
def
_handle_marketing_opt_in
(
self
,
request
,
course_key
,
user
):
"""
Handle the marketing email opt-in flag, if it was set.
Errors here aren't expected, but should not break the outer enrollment transaction.
"""
email_opt_in
=
request
.
DATA
.
get
(
'email_opt_in'
,
None
)
if
email_opt_in
is
not
None
:
try
:
update_email_opt_in
(
user
,
course_key
.
org
,
email_opt_in
)
except
Exception
:
# pylint: disable=broad-except
# log the error, return silently
log
.
exception
(
'Failed to handle marketing opt-in flag: user="
%
s", course="
%
s"'
,
user
.
username
,
course_key
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
# pylint: disable=unused-argument
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
# pylint: disable=unused-argument
"""
"""
Attempt to create the basket and enroll the user.
Attempt to create the basket and enroll the user.
...
@@ -96,6 +113,7 @@ class BasketsView(APIView):
...
@@ -96,6 +113,7 @@ class BasketsView(APIView):
username
=
user
.
username
)
username
=
user
.
username
)
log
.
debug
(
msg
)
log
.
debug
(
msg
)
self
.
_enroll
(
course_key
,
user
)
self
.
_enroll
(
course_key
,
user
)
self
.
_handle_marketing_opt_in
(
request
,
course_key
,
user
)
return
DetailResponse
(
msg
)
return
DetailResponse
(
msg
)
# Setup the API
# Setup the API
...
@@ -108,6 +126,8 @@ class BasketsView(APIView):
...
@@ -108,6 +126,8 @@ class BasketsView(APIView):
log
.
debug
(
msg
)
log
.
debug
(
msg
)
return
DetailResponse
(
msg
)
return
DetailResponse
(
msg
)
response
=
None
# Make the API call
# Make the API call
try
:
try
:
response_data
=
api
.
baskets
.
post
({
response_data
=
api
.
baskets
.
post
({
...
@@ -118,12 +138,12 @@ class BasketsView(APIView):
...
@@ -118,12 +138,12 @@ class BasketsView(APIView):
payment_data
=
response_data
[
"payment_data"
]
payment_data
=
response_data
[
"payment_data"
]
if
payment_data
:
if
payment_data
:
# Pass data to the client to begin the payment flow.
# Pass data to the client to begin the payment flow.
re
turn
JsonResponse
(
payment_data
)
re
sponse
=
JsonResponse
(
payment_data
)
elif
response_data
[
'order'
]:
elif
response_data
[
'order'
]:
# The order was completed immediately because there is no charge.
# The order was completed immediately because there is no charge.
msg
=
Messages
.
ORDER_COMPLETED
.
format
(
order_number
=
response_data
[
'order'
][
'number'
])
msg
=
Messages
.
ORDER_COMPLETED
.
format
(
order_number
=
response_data
[
'order'
][
'number'
])
log
.
debug
(
msg
)
log
.
debug
(
msg
)
re
turn
DetailResponse
(
msg
)
re
sponse
=
DetailResponse
(
msg
)
else
:
else
:
msg
=
u'Unexpected response from basket endpoint.'
msg
=
u'Unexpected response from basket endpoint.'
log
.
error
(
log
.
error
(
...
@@ -143,6 +163,9 @@ class BasketsView(APIView):
...
@@ -143,6 +163,9 @@ class BasketsView(APIView):
user_id
=
user
.
id
user_id
=
user
.
id
)
)
self
.
_handle_marketing_opt_in
(
request
,
course_key
,
user
)
return
response
class
BasketOrderView
(
APIView
):
class
BasketOrderView
(
APIView
):
""" Retrieve the order associated with a basket. """
""" Retrieve the order associated with a basket. """
...
...
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