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
6ddbbf41
Commit
6ddbbf41
authored
Aug 01, 2017
by
Jesse Shapiro
Committed by
Jesse Shapiro
Aug 18, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New consent API
parent
d4f5c78d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
93 additions
and
138 deletions
+93
-138
ecommerce/core/models.py
+4
-0
ecommerce/coupons/tests/test_views.py
+8
-2
ecommerce/enterprise/tests/mixins.py
+54
-0
ecommerce/enterprise/tests/test_utils.py
+19
-58
ecommerce/enterprise/utils.py
+7
-77
ecommerce/extensions/fulfillment/modules.py
+1
-1
No files found.
ecommerce/core/models.py
View file @
6ddbbf41
...
@@ -409,6 +409,10 @@ class SiteConfiguration(models.Model):
...
@@ -409,6 +409,10 @@ class SiteConfiguration(models.Model):
return
EdxRestApiClient
(
self
.
enterprise_api_url
,
jwt
=
self
.
access_token
)
return
EdxRestApiClient
(
self
.
enterprise_api_url
,
jwt
=
self
.
access_token
)
@cached_property
@cached_property
def
consent_api_client
(
self
):
return
EdxRestApiClient
(
self
.
build_lms_url
(
'/consent/api/v1/'
),
jwt
=
self
.
access_token
,
append_slash
=
False
)
@cached_property
def
user_api_client
(
self
):
def
user_api_client
(
self
):
"""
"""
Returns the API client to access the user API endpoint on LMS.
Returns the API client to access the user API endpoint on LMS.
...
...
ecommerce/coupons/tests/test_views.py
View file @
6ddbbf41
...
@@ -465,8 +465,14 @@ class CouponRedeemViewTests(CouponMixin, DiscoveryTestMixin, LmsApiMockMixin, En
...
@@ -465,8 +465,14 @@ class CouponRedeemViewTests(CouponMixin, DiscoveryTestMixin, LmsApiMockMixin, En
catalog
=
catalog
catalog
=
catalog
)
)
self
.
request
.
user
=
self
.
user
self
.
request
.
user
=
self
.
user
self
.
mock_enterprise_learner_api
(
consent_enabled
=
consent_enabled
,
consent_provided
=
consent_provided
)
self
.
mock_consent_response
(
self
.
mock_enterprise_course_enrollment_api
(
results_present
=
False
)
self
.
user
.
username
,
course_id
,
ENTERPRISE_CUSTOMER
,
granted
=
consent_provided
,
required
=
(
consent_enabled
and
not
consent_provided
),
exists
=
(
not
consent_provided
),
)
self
.
mock_account_api
(
self
.
request
,
self
.
user
.
username
,
data
=
{
'is_active'
:
True
})
self
.
mock_account_api
(
self
.
request
,
self
.
user
.
username
,
data
=
{
'is_active'
:
True
})
self
.
mock_access_token_response
()
self
.
mock_access_token_response
()
self
.
mock_specific_enterprise_customer_api
(
uuid
=
ENTERPRISE_CUSTOMER
,
consent_enabled
=
consent_enabled
)
self
.
mock_specific_enterprise_customer_api
(
uuid
=
ENTERPRISE_CUSTOMER
,
consent_enabled
=
consent_enabled
)
...
...
ecommerce/enterprise/tests/mixins.py
View file @
6ddbbf41
...
@@ -420,3 +420,57 @@ class EnterpriseServiceMockMixin(object):
...
@@ -420,3 +420,57 @@ class EnterpriseServiceMockMixin(object):
body
=
enterprise_enrollment_api_response_json
,
body
=
enterprise_enrollment_api_response_json
,
content_type
=
'application/json'
content_type
=
'application/json'
)
)
def
mock_consent_response
(
self
,
username
,
course_id
,
ec_uuid
,
method
=
httpretty
.
GET
,
granted
=
True
,
required
=
False
,
exists
=
True
,
response_code
=
None
):
response_body
=
{
'username'
:
username
,
'course_id'
:
course_id
,
'enterprise_customer_uuid'
:
ec_uuid
,
'consent_provided'
:
granted
,
'consent_required'
:
required
,
'exists'
:
exists
,
}
httpretty
.
register_uri
(
method
=
method
,
uri
=
self
.
site
.
siteconfiguration
.
build_lms_url
(
'/consent/api/v1/data_sharing_consent'
),
content_type
=
'application/json'
,
body
=
json
.
dumps
(
response_body
),
status
=
response_code
or
200
,
)
def
mock_consent_get
(
self
,
username
,
course_id
,
ec_uuid
):
self
.
mock_consent_response
(
username
,
course_id
,
ec_uuid
)
def
mock_consent_missing
(
self
,
username
,
course_id
,
ec_uuid
):
self
.
mock_consent_response
(
username
,
course_id
,
ec_uuid
,
exists
=
False
,
granted
=
False
,
required
=
True
,
)
def
mock_consent_not_required
(
self
,
username
,
course_id
,
ec_uuid
):
self
.
mock_consent_response
(
username
,
course_id
,
ec_uuid
,
exists
=
False
,
granted
=
False
,
required
=
False
,
)
ecommerce/enterprise/tests/test_utils.py
View file @
6ddbbf41
...
@@ -87,65 +87,26 @@ class EnterpriseUtilsTests(EnterpriseServiceMockMixin, TestCase):
...
@@ -87,65 +87,26 @@ class EnterpriseUtilsTests(EnterpriseServiceMockMixin, TestCase):
self
.
assertDictContainsSubset
(
expected_return
,
response
)
self
.
assertDictContainsSubset
(
expected_return
,
response
)
@ddt.data
(
@httpretty.activate
(
True
,
True
),
def
test_ecu_needs_consent
(
self
):
(
False
,
False
),
opts
=
{
)
'ec_uuid'
:
'fake-uuid'
,
@ddt.unpack
'course_id'
:
'course-v1:real+course+id'
,
def
test_ecu_needs_consent_no_link
(
self
,
ec_consent_enabled
,
expected_consent_requirement
):
'username'
:
'johnsmith'
,
"""
}
Test that when there's no EnterpriseCustomerUser, the consent requirement comes down
kw
=
{
to whether the EnterpriseCustomer wants consent.
'enterprise_customer_uuid'
:
'fake-uuid'
,
"""
'course_id'
:
'course-v1:real+course+id'
,
self
.
mock_access_token_response
()
'username'
:
'johnsmith'
,
self
.
mock_enterprise_learner_api_for_learner_with_no_enterprise
()
'site'
:
self
.
site
enterprise_customer_uuid
=
TEST_ENTERPRISE_CUSTOMER_UUID
}
self
.
mock_specific_enterprise_customer_api
(
enterprise_customer_uuid
,
consent_enabled
=
ec_consent_enabled
)
consent_needed
=
enterprise_customer_user_needs_consent
(
self
.
site
,
TEST_ENTERPRISE_CUSTOMER_UUID
,
'course-v1:edX+DemoX+Demo_Course'
,
'admin'
)
self
.
assertEqual
(
consent_needed
,
expected_consent_requirement
)
@ddt.data
(
(
True
,
False
,
True
,
True
,
False
),
(
False
,
True
,
True
,
True
,
False
),
(
False
,
False
,
True
,
True
,
True
),
(
False
,
False
,
True
,
False
,
True
),
(
False
,
False
,
False
,
True
,
False
),
(
False
,
False
,
False
,
False
,
False
),
)
@ddt.unpack
def
test_ecu_needs_consent_link_exists
(
self
,
account_consent_provided
,
course_consent_provided
,
consent_enabled
,
results_present
,
expected_consent_requirement
):
self
.
mock_access_token_response
()
self
.
mock_access_token_response
()
enterprise_customer_uuid
=
TEST_ENTERPRISE_CUSTOMER_UUID
self
.
mock_consent_get
(
**
opts
)
self
.
mock_enterprise_learner_api
(
self
.
assertEqual
(
enterprise_customer_user_needs_consent
(
**
kw
),
False
)
enterprise_customer_uuid
=
enterprise_customer_uuid
,
self
.
mock_consent_missing
(
**
opts
)
consent_provided
=
account_consent_provided
,
self
.
assertEqual
(
enterprise_customer_user_needs_consent
(
**
kw
),
True
)
consent_enabled
=
consent_enabled
,
self
.
mock_consent_not_required
(
**
opts
)
)
self
.
assertEqual
(
enterprise_customer_user_needs_consent
(
**
kw
),
False
)
self
.
mock_enterprise_course_enrollment_api
(
consent_granted
=
course_consent_provided
,
results_present
=
results_present
,
)
consent_needed
=
enterprise_customer_user_needs_consent
(
self
.
site
,
TEST_ENTERPRISE_CUSTOMER_UUID
,
'course-v1:edX+DemoX+Demo_Course'
,
'admin'
)
self
.
assertEqual
(
consent_needed
,
expected_consent_requirement
)
def
test_get_enterprise_customer_uuid
(
self
):
def
test_get_enterprise_customer_uuid
(
self
):
"""
"""
...
...
ecommerce/enterprise/utils.py
View file @
6ddbbf41
...
@@ -158,60 +158,6 @@ def get_or_create_enterprise_customer_user(site, enterprise_customer_uuid, usern
...
@@ -158,60 +158,6 @@ def get_or_create_enterprise_customer_user(site, enterprise_customer_uuid, usern
return
response
return
response
def
enterprise_customer_needs_consent
(
enterprise_customer_data
):
"""
Determine if consent should be prompted for on this enterprise customer.
Args:
enterprise_customer_data: A dictionary isomorphic with the EnterpriseCustomer
object returned by various endpoints of the Enterprise API.
Returns:
bool: Whether, in general, a user must provide consent to use offers provided by this EnterpriseCustomer.
"""
if
not
enterprise_customer_data
[
'enable_data_sharing_consent'
]:
return
False
return
enterprise_customer_data
[
'enforce_data_sharing_consent'
]
in
(
'at_login'
,
'at_enrollment'
)
def
enterprise_customer_user_consent_provided
(
ec_user_data
):
"""
Determine if the EnterpriseCustomerUser has provided consent at an account level.
Args:
ec_user_data: A dictionary isomorphic with the EnterpriseCustomerUser
object returned by various endpoints of the Enterprise API.
"""
return
ec_user_data
[
'data_sharing_consent'
]
and
ec_user_data
[
'data_sharing_consent'
][
0
][
'enabled'
]
def
get_enterprise_customer_user
(
site
,
username
,
enterprise_customer_uuid
):
"""
Get the EnterpriseCustomerUser with a particular username and linked to a particular
EnterpriseCustomer if it exists; otherwise, return None.
Args:
site (Site): The site which is handling the current request
username (str): The username of the user in the LMS
enterprise_customer_uuid (str): The UUID of the EnterpriseCustomer in the LMS
Returns:
dict: The single EnterpriseCustomerUser structure provided by the API
NoneType: Returns None if no EnterpriseCustomerUser is found
"""
api
=
site
.
siteconfiguration
.
enterprise_api_client
api_resource
=
'enterprise-learner'
endpoint
=
getattr
(
api
,
api_resource
)
response
=
endpoint
.
get
(
enterprise_customer
=
str
(
enterprise_customer_uuid
),
username
=
str
(
username
),
)
results
=
response
.
get
(
'results'
)
return
results
[
0
]
if
results
else
None
def
get_enterprise_course_enrollment
(
site
,
enterprise_customer_user
,
course_id
):
def
get_enterprise_course_enrollment
(
site
,
enterprise_customer_user
,
course_id
):
"""
"""
Get the EnterpriseCourseEnrollment between a particular EnterpriseCustomerUser and
Get the EnterpriseCourseEnrollment between a particular EnterpriseCustomerUser and
...
@@ -254,29 +200,13 @@ def enterprise_customer_user_needs_consent(site, enterprise_customer_uuid, cours
...
@@ -254,29 +200,13 @@ def enterprise_customer_user_needs_consent(site, enterprise_customer_uuid, cours
that the EnterpriseCustomer specified by the enterprise_customer_uuid
that the EnterpriseCustomer specified by the enterprise_customer_uuid
argument provides for the course specified by the course_id argument.
argument provides for the course specified by the course_id argument.
"""
"""
account_consent_provided
=
False
consent_client
=
site
.
siteconfiguration
.
consent_api_client
course_consent_provided
=
False
endpoint
=
consent_client
.
data_sharing_consent
return
endpoint
.
get
(
ec_user
=
get_enterprise_customer_user
(
site
,
username
,
enterprise_customer_uuid
)
username
=
username
,
enterprise_customer_uuid
=
enterprise_customer_uuid
,
if
ec_user
:
course_id
=
course_id
account_consent_provided
=
enterprise_customer_user_consent_provided
(
ec_user
)
)[
'consent_required'
]
enterprise_customer
=
ec_user
[
'enterprise_customer'
]
else
:
enterprise_customer
=
get_enterprise_customer
(
site
,
enterprise_customer_uuid
)
consent_needed
=
enterprise_customer_needs_consent
(
enterprise_customer
)
if
consent_needed
and
not
account_consent_provided
and
ec_user
:
existing_course_enrollment
=
get_enterprise_course_enrollment
(
site
,
course_id
=
str
(
course_id
),
enterprise_customer_user
=
ec_user
[
'id'
],
)
if
existing_course_enrollment
:
course_consent_provided
=
existing_course_enrollment
.
get
(
'consent_granted'
,
False
)
return
consent_needed
and
not
(
account_consent_provided
or
course_consent_provided
)
def
get_enterprise_customer_from_voucher
(
site
,
voucher
):
def
get_enterprise_customer_from_voucher
(
site
,
voucher
):
...
...
ecommerce/extensions/fulfillment/modules.py
View file @
6ddbbf41
...
@@ -147,7 +147,7 @@ class EnrollmentFulfillmentModule(BaseFulfillmentModule):
...
@@ -147,7 +147,7 @@ class EnrollmentFulfillmentModule(BaseFulfillmentModule):
pass
pass
if
enterprise_customer_uuid
is
not
None
:
if
enterprise_customer_uuid
is
not
None
:
data
[
'
enterprise_course_consent'
]
=
True
data
[
'
linked_enterprise_customer'
]
=
str
(
enterprise_customer_uuid
)
break
break
# If an EnterpriseCustomer UUID is associated with the coupon, create an EnterpriseCustomerUser
# If an EnterpriseCustomer UUID is associated with the coupon, create an EnterpriseCustomerUser
...
...
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