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
004f4b75
Commit
004f4b75
authored
Aug 30, 2017
by
Albert St. Aubin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update to resolver complete my program purchase to work with no-id-professional
LEARNER-2420
parent
0c204e35
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
146 additions
and
105 deletions
+146
-105
openedx/core/djangoapps/programs/tests/test_utils.py
+124
-93
openedx/core/djangoapps/programs/utils.py
+22
-12
No files found.
openedx/core/djangoapps/programs/tests/test_utils.py
View file @
004f4b75
...
@@ -550,6 +550,27 @@ class TestProgramProgressMeter(TestCase):
...
@@ -550,6 +550,27 @@ class TestProgramProgressMeter(TestCase):
self
.
assertEqual
(
meter
.
_is_course_complete
(
course
),
True
)
self
.
assertEqual
(
meter
.
_is_course_complete
(
course
),
True
)
def
_create_course
(
self
,
course_price
):
"""
Creates the course in mongo and update it with the instructor data.
Also creates catalog course with respect to course run.
Returns:
Catalog course dict.
"""
course
=
ModuleStoreCourseFactory
()
course
.
start
=
datetime
.
datetime
.
now
(
utc
)
-
datetime
.
timedelta
(
days
=
1
)
course
.
end
=
datetime
.
datetime
.
now
(
utc
)
+
datetime
.
timedelta
(
days
=
1
)
course
.
instructor_info
=
self
.
instructors
course
=
self
.
update_course
(
course
,
self
.
user
.
id
)
course_run
=
CourseRunFactory
(
key
=
unicode
(
course
.
id
),
seats
=
[
SeatFactory
(
price
=
course_price
)]
)
return
CourseFactory
(
course_runs
=
[
course_run
])
@ddt.ddt
@ddt.ddt
@override_settings
(
ECOMMERCE_PUBLIC_URL_ROOT
=
ECOMMERCE_URL_ROOT
)
@override_settings
(
ECOMMERCE_PUBLIC_URL_ROOT
=
ECOMMERCE_URL_ROOT
)
@skip_unless_lms
@skip_unless_lms
...
@@ -558,6 +579,18 @@ class TestProgramDataExtender(ModuleStoreTestCase):
...
@@ -558,6 +579,18 @@ class TestProgramDataExtender(ModuleStoreTestCase):
maxDiff
=
None
maxDiff
=
None
sku
=
'abc123'
sku
=
'abc123'
checkout_path
=
'/basket'
checkout_path
=
'/basket'
instructors
=
{
'instructors'
:
[
{
'name'
:
'test-instructor1'
,
'organization'
:
'TextX'
,
},
{
'name'
:
'test-instructor2'
,
'organization'
:
'TextX'
,
}
]
}
def
setUp
(
self
):
def
setUp
(
self
):
super
(
TestProgramDataExtender
,
self
)
.
setUp
()
super
(
TestProgramDataExtender
,
self
)
.
setUp
()
...
@@ -570,6 +603,7 @@ class TestProgramDataExtender(ModuleStoreTestCase):
...
@@ -570,6 +603,7 @@ class TestProgramDataExtender(ModuleStoreTestCase):
self
.
course_run
=
CourseRunFactory
(
key
=
unicode
(
self
.
course
.
id
))
self
.
course_run
=
CourseRunFactory
(
key
=
unicode
(
self
.
course
.
id
))
self
.
catalog_course
=
CourseFactory
(
course_runs
=
[
self
.
course_run
])
self
.
catalog_course
=
CourseFactory
(
course_runs
=
[
self
.
course_run
])
self
.
program
=
ProgramFactory
(
courses
=
[
self
.
catalog_course
])
self
.
program
=
ProgramFactory
(
courses
=
[
self
.
catalog_course
])
self
.
course_price
=
100
def
_assert_supplemented
(
self
,
actual
,
**
kwargs
):
def
_assert_supplemented
(
self
,
actual
,
**
kwargs
):
"""DRY helper used to verify that program data is extended correctly."""
"""DRY helper used to verify that program data is extended correctly."""
...
@@ -746,6 +780,95 @@ class TestProgramDataExtender(ModuleStoreTestCase):
...
@@ -746,6 +780,95 @@ class TestProgramDataExtender(ModuleStoreTestCase):
self
.
_assert_supplemented
(
data
)
self
.
_assert_supplemented
(
data
)
def
test_learner_eligibility_for_one_click_purchase
(
self
):
"""
Learner should be eligible for one click purchase if:
- program is eligible for one click purchase
- There are courses remaining that have not been purchased and enrolled in.
"""
data
=
ProgramDataExtender
(
self
.
program
,
self
.
user
)
.
extend
()
self
.
assertFalse
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
courses
=
[
_create_course
(
self
,
self
.
course_price
)]
program
=
ProgramFactory
(
courses
=
courses
,
is_program_eligible_for_one_click_purchase
=
False
)
data
=
ProgramDataExtender
(
program
,
self
.
user
)
.
extend
()
self
.
assertFalse
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
course1
=
_create_course
(
self
,
self
.
course_price
)
course2
=
_create_course
(
self
,
self
.
course_price
)
CourseEnrollmentFactory
(
user
=
self
.
user
,
course_id
=
course1
[
'course_runs'
][
0
][
'key'
],
mode
=
'verified'
)
CourseEnrollmentFactory
(
user
=
self
.
user
,
course_id
=
course2
[
'course_runs'
][
0
][
'key'
],
mode
=
'audit'
)
program2
=
ProgramFactory
(
courses
=
[
course1
,
course2
],
is_program_eligible_for_one_click_purchase
=
True
,
applicable_seat_types
=
[
'verified'
],
)
data
=
ProgramDataExtender
(
program2
,
self
.
user
)
.
extend
()
self
.
assertTrue
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
def
test_learner_eligibility_for_one_click_purchase_professional_no_id
(
self
):
"""
Learner should not be eligible for one click purchase if:
- There are no courses remaining that have not been purchased and enrolled in.
This test is primarily for the case of no-id-professional enrollment modes
"""
course1
=
_create_course
(
self
,
self
.
course_price
)
CourseEnrollmentFactory
(
user
=
self
.
user
,
course_id
=
course1
[
'course_runs'
][
0
][
'key'
],
mode
=
'no-id-professional'
)
program2
=
ProgramFactory
(
courses
=
[
course1
],
is_program_eligible_for_one_click_purchase
=
True
,
applicable_seat_types
=
[
'professional'
],
# There is no seat type for no-id-professional, it
# instead uses professional
)
data
=
ProgramDataExtender
(
program2
,
self
.
user
)
.
extend
()
self
.
assertFalse
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
def
test_multiple_published_course_runs
(
self
):
"""
Learner should not be eligible for one click purchase if:
- program has a course with more than one published course run
"""
course_run_1
=
CourseRunFactory
(
key
=
str
(
ModuleStoreCourseFactory
()
.
id
),
status
=
'published'
)
course_run_2
=
CourseRunFactory
(
key
=
str
(
ModuleStoreCourseFactory
()
.
id
),
status
=
'published'
)
course
=
CourseFactory
(
course_runs
=
[
course_run_1
,
course_run_2
])
program
=
ProgramFactory
(
courses
=
[
CourseFactory
(
course_runs
=
[
CourseRunFactory
(
key
=
str
(
ModuleStoreCourseFactory
()
.
id
),
status
=
'published'
)
]),
course
,
CourseFactory
(
course_runs
=
[
CourseRunFactory
(
key
=
str
(
ModuleStoreCourseFactory
()
.
id
),
status
=
'published'
)
])
],
is_program_eligible_for_one_click_purchase
=
True
,
applicable_seat_types
=
[
'verified'
]
)
data
=
ProgramDataExtender
(
program
,
self
.
user
)
.
extend
()
self
.
assertFalse
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
course_run_2
[
'status'
]
=
'unpublished'
data
=
ProgramDataExtender
(
program
,
self
.
user
)
.
extend
()
self
.
assertTrue
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
@skip_unless_lms
@skip_unless_lms
@mock.patch
(
UTILS_MODULE
+
'.get_credentials'
)
@mock.patch
(
UTILS_MODULE
+
'.get_credentials'
)
...
@@ -873,30 +996,10 @@ class TestProgramMarketingDataExtender(ModuleStoreTestCase):
...
@@ -873,30 +996,10 @@ class TestProgramMarketingDataExtender(ModuleStoreTestCase):
self
.
course_price
=
100
self
.
course_price
=
100
self
.
number_of_courses
=
2
self
.
number_of_courses
=
2
self
.
program
=
ProgramFactory
(
self
.
program
=
ProgramFactory
(
courses
=
[
self
.
_create_course
(
self
.
course_price
)
for
__
in
range
(
self
.
number_of_courses
)],
courses
=
[
_create_course
(
self
,
self
.
course_price
)
for
__
in
range
(
self
.
number_of_courses
)],
applicable_seat_types
=
[
'verified'
]
applicable_seat_types
=
[
'verified'
]
)
)
def
_create_course
(
self
,
course_price
):
"""
Creates the course in mongo and update it with the instructor data.
Also creates catalog course with respect to course run.
Returns:
Catalog course dict.
"""
course
=
ModuleStoreCourseFactory
()
course
.
start
=
datetime
.
datetime
.
now
(
utc
)
-
datetime
.
timedelta
(
days
=
1
)
course
.
end
=
datetime
.
datetime
.
now
(
utc
)
+
datetime
.
timedelta
(
days
=
1
)
course
.
instructor_info
=
self
.
instructors
course
=
self
.
update_course
(
course
,
self
.
user
.
id
)
course_run
=
CourseRunFactory
(
key
=
unicode
(
course
.
id
),
seats
=
[
SeatFactory
(
price
=
course_price
)]
)
return
CourseFactory
(
course_runs
=
[
course_run
])
def
_prepare_program_for_discounted_price_calculation_endpoint
(
self
):
def
_prepare_program_for_discounted_price_calculation_endpoint
(
self
):
"""
"""
Program's applicable seat types should match some or all seat types of the seats that are a part of the program.
Program's applicable seat types should match some or all seat types of the seats that are a part of the program.
...
@@ -964,78 +1067,6 @@ class TestProgramMarketingDataExtender(ModuleStoreTestCase):
...
@@ -964,78 +1067,6 @@ class TestProgramMarketingDataExtender(ModuleStoreTestCase):
self
.
assertEqual
(
data
[
'courses'
][
0
][
'course_runs'
][
0
][
'can_enroll'
],
can_enroll
)
self
.
assertEqual
(
data
[
'courses'
][
0
][
'course_runs'
][
0
][
'can_enroll'
],
can_enroll
)
def
test_learner_eligibility_for_one_click_purchase
(
self
):
"""
Learner should be eligible for one click purchase if:
- program is eligible for one click purchase
- There are courses remaining that have not been purchased and enrolled in.
"""
data
=
ProgramMarketingDataExtender
(
self
.
program
,
self
.
user
)
.
extend
()
self
.
assertTrue
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
courses
=
[
self
.
_create_course
(
self
.
course_price
)]
program
=
ProgramFactory
(
courses
=
courses
,
is_program_eligible_for_one_click_purchase
=
False
)
data
=
ProgramMarketingDataExtender
(
program
,
self
.
user
)
.
extend
()
self
.
assertFalse
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
course1
=
self
.
_create_course
(
self
.
course_price
)
course2
=
self
.
_create_course
(
self
.
course_price
)
CourseEnrollmentFactory
(
user
=
self
.
user
,
course_id
=
course1
[
'course_runs'
][
0
][
'key'
],
mode
=
'verified'
)
CourseEnrollmentFactory
(
user
=
self
.
user
,
course_id
=
course2
[
'course_runs'
][
0
][
'key'
],
mode
=
'audit'
)
program2
=
ProgramFactory
(
courses
=
[
course1
,
course2
],
is_program_eligible_for_one_click_purchase
=
True
,
applicable_seat_types
=
[
'verified'
],
)
data
=
ProgramMarketingDataExtender
(
program2
,
self
.
user
)
.
extend
()
self
.
assertTrue
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
def
test_multiple_published_course_runs
(
self
):
"""
Learner should not be eligible for one click purchase if:
- program has a course with more than one published course run
"""
course_run_1
=
CourseRunFactory
(
key
=
str
(
ModuleStoreCourseFactory
()
.
id
),
status
=
'published'
)
course_run_2
=
CourseRunFactory
(
key
=
str
(
ModuleStoreCourseFactory
()
.
id
),
status
=
'published'
)
course
=
CourseFactory
(
course_runs
=
[
course_run_1
,
course_run_2
])
program
=
ProgramFactory
(
courses
=
[
CourseFactory
(
course_runs
=
[
CourseRunFactory
(
key
=
str
(
ModuleStoreCourseFactory
()
.
id
),
status
=
'published'
)
]),
course
,
CourseFactory
(
course_runs
=
[
CourseRunFactory
(
key
=
str
(
ModuleStoreCourseFactory
()
.
id
),
status
=
'published'
)
])
],
is_program_eligible_for_one_click_purchase
=
True
,
applicable_seat_types
=
[
'verified'
]
)
data
=
ProgramMarketingDataExtender
(
program
,
self
.
user
)
.
extend
()
self
.
assertFalse
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
course_run_2
[
'status'
]
=
'unpublished'
data
=
ProgramMarketingDataExtender
(
program
,
self
.
user
)
.
extend
()
self
.
assertTrue
(
data
[
'is_learner_eligible_for_one_click_purchase'
])
@httpretty.activate
@httpretty.activate
def
test_fetching_program_discounted_price
(
self
):
def
test_fetching_program_discounted_price
(
self
):
"""
"""
...
...
openedx/core/djangoapps/programs/utils.py
View file @
004f4b75
...
@@ -463,29 +463,39 @@ class ProgramDataExtender(object):
...
@@ -463,29 +463,39 @@ class ProgramDataExtender(object):
if
is_learner_eligible_for_one_click_purchase
:
if
is_learner_eligible_for_one_click_purchase
:
for
course
in
self
.
data
[
'courses'
]:
for
course
in
self
.
data
[
'courses'
]:
add_course_sku
=
False
add_course_sku
=
False
for
course_run
in
course
[
'course_runs'
]:
published_course_runs
=
filter
(
lambda
run
:
run
[
'status'
]
==
'published'
,
course
[
'course_runs'
])
if
len
(
published_course_runs
)
==
1
:
# Look at the course runs for a course and determine if the course SKU should be added.
course_run
=
published_course_runs
[
0
]
(
enrollment_mode
,
active
)
=
CourseEnrollment
.
enrollment_mode_for_user
(
(
enrollment_mode
,
active
)
=
CourseEnrollment
.
enrollment_mode_for_user
(
self
.
user
,
self
.
user
,
CourseKey
.
from_string
(
course_run
[
'key'
])
CourseKey
.
from_string
(
course_run
[
'key'
])
)
)
if
enrollment_mode
not
in
applicable_seat_types
or
not
active
:
if
enrollment_mode
is
not
None
and
active
is
not
None
:
# Check all the applicable seat types
# this will also check for no-id-professional as professional
applicable_seat
=
any
(
seat_type
in
enrollment_mode
for
seat_type
in
applicable_seat_types
)
# If no applicable seat is found add the course SKU to the list
if
not
applicable_seat
or
not
active
:
add_course_sku
=
True
else
:
# There is no enrollment information for the course add the course SKU
add_course_sku
=
True
add_course_sku
=
True
break
if
add_course_sku
:
if
add_course_sku
:
published_course_runs
=
filter
(
lambda
run
:
run
[
'status'
]
==
'published'
,
course
[
'course_runs'
])
if
len
(
published_course_runs
)
==
1
:
for
seat
in
published_course_runs
[
0
][
'seats'
]:
for
seat
in
published_course_runs
[
0
][
'seats'
]:
if
seat
[
'type'
]
in
applicable_seat_types
and
seat
[
'sku'
]:
if
seat
[
'type'
]
in
applicable_seat_types
and
seat
[
'sku'
]:
skus
.
append
(
seat
[
'sku'
])
skus
.
append
(
seat
[
'sku'
])
else
:
else
:
# If a course in the program has more than 1 published course run
bundle_variant
=
'partial'
# learner won't be eligible for a one click purchase.
is_learner_eligible_for_one_click_purchase
=
False
skus
=
[]
break
else
:
else
:
bundle_variant
=
'partial'
# If a course in the program has more than 1 published course run
# learner won't be eligible for a one click purchase.
is_learner_eligible_for_one_click_purchase
=
False
skus
=
[]
break
if
skus
:
if
skus
:
try
:
try
:
...
...
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