Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
course-discovery
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
course-discovery
Commits
2d669183
Commit
2d669183
authored
Nov 13, 2017
by
Matthew Piatetsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Boost current upgradeable runs over future runs whose start date is closer
LEARNER-2935
parent
519f9189
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
161 additions
and
37 deletions
+161
-37
course_discovery/apps/api/tests/test_serializers.py
+30
-37
course_discovery/apps/course_metadata/models.py
+17
-0
course_discovery/apps/course_metadata/search_indexes.py
+4
-0
course_discovery/apps/course_metadata/tests/test_models.py
+26
-0
course_discovery/apps/edx_haystack_extensions/elasticsearch_boost_config.py
+14
-0
course_discovery/apps/edx_haystack_extensions/tests/test_boosting.py
+70
-0
No files found.
course_discovery/apps/api/tests/test_serializers.py
View file @
2d669183
...
@@ -6,33 +6,28 @@ from urllib.parse import urlencode
...
@@ -6,33 +6,28 @@ from urllib.parse import urlencode
import
ddt
import
ddt
import
mock
import
mock
import
pytest
import
pytest
import
pytz
import
responses
import
responses
from
django.test
import
TestCase
from
django.test
import
TestCase
from
django.utils.text
import
slugify
from
django.utils.text
import
slugify
from
haystack.query
import
SearchQuerySet
from
haystack.query
import
SearchQuerySet
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
pytz
import
UTC
from
rest_framework.test
import
APIRequestFactory
from
rest_framework.test
import
APIRequestFactory
from
waffle.models
import
Switch
from
waffle.models
import
Switch
from
waffle.testutils
import
override_switch
from
waffle.testutils
import
override_switch
from
course_discovery.apps.api.fields
import
ImageField
,
StdImageSerializerField
from
course_discovery.apps.api.fields
import
ImageField
,
StdImageSerializerField
from
course_discovery.apps.api.serializers
import
(
AffiliateWindowSerializer
,
CatalogSerializer
,
from
course_discovery.apps.api.serializers
import
(
ContainedCourseRunsSerializer
,
ContainedCoursesSerializer
,
AffiliateWindowSerializer
,
CatalogSerializer
,
ContainedCourseRunsSerializer
,
ContainedCoursesSerializer
,
CorporateEndorsementSerializer
,
CourseEntitlementSerializer
,
CorporateEndorsementSerializer
,
CourseEntitlementSerializer
,
CourseRunSearchSerializer
,
CourseRunSerializer
,
CourseRunSearchSerializer
,
CourseRunSerializer
,
CourseRunWithProgramsSerializer
,
CourseSearchSerializer
,
CourseSerializer
,
CourseWithProgramsSerializer
,
CourseRunWithProgramsSerializer
,
CourseSearchSerializer
,
EndorsementSerializer
,
FAQSerializer
,
FlattenedCourseRunWithCourseSerializer
,
ImageSerializer
,
CourseSerializer
,
CourseWithProgramsSerializer
,
MinimalCourseRunSerializer
,
MinimalCourseSerializer
,
MinimalOrganizationSerializer
,
MinimalProgramCourseSerializer
,
EndorsementSerializer
,
FAQSerializer
,
MinimalProgramSerializer
,
NestedProgramSerializer
,
OrganizationSerializer
,
PersonSerializer
,
PositionSerializer
,
FlattenedCourseRunWithCourseSerializer
,
ImageSerializer
,
PrerequisiteSerializer
,
ProgramSearchSerializer
,
ProgramSerializer
,
ProgramTypeSerializer
,
SeatSerializer
,
MinimalCourseRunSerializer
,
MinimalCourseSerializer
,
SubjectSerializer
,
TypeaheadCourseRunSearchSerializer
,
TypeaheadProgramSearchSerializer
,
VideoSerializer
,
MinimalOrganizationSerializer
,
MinimalProgramCourseSerializer
,
get_utm_source_for_user
MinimalProgramSerializer
,
NestedProgramSerializer
,
)
OrganizationSerializer
,
PersonSerializer
,
PositionSerializer
,
PrerequisiteSerializer
,
ProgramSearchSerializer
,
ProgramSerializer
,
ProgramTypeSerializer
,
SeatSerializer
,
SubjectSerializer
,
TypeaheadCourseRunSearchSerializer
,
TypeaheadProgramSearchSerializer
,
VideoSerializer
,
get_utm_source_for_user
)
from
course_discovery.apps.api.tests.mixins
import
SiteMixin
from
course_discovery.apps.api.tests.mixins
import
SiteMixin
from
course_discovery.apps.catalogs.tests.factories
import
CatalogFactory
from
course_discovery.apps.catalogs.tests.factories
import
CatalogFactory
from
course_discovery.apps.core.models
import
Partner
,
User
from
course_discovery.apps.core.models
import
Partner
,
User
...
@@ -41,13 +36,11 @@ from course_discovery.apps.core.tests.helpers import make_image_file
...
@@ -41,13 +36,11 @@ from course_discovery.apps.core.tests.helpers import make_image_file
from
course_discovery.apps.core.tests.mixins
import
ElasticsearchTestMixin
,
LMSAPIClientMixin
from
course_discovery.apps.core.tests.mixins
import
ElasticsearchTestMixin
,
LMSAPIClientMixin
from
course_discovery.apps.course_metadata.choices
import
CourseRunStatus
,
ProgramStatus
from
course_discovery.apps.course_metadata.choices
import
CourseRunStatus
,
ProgramStatus
from
course_discovery.apps.course_metadata.models
import
Course
,
CourseRun
,
Program
from
course_discovery.apps.course_metadata.models
import
Course
,
CourseRun
,
Program
from
course_discovery.apps.course_metadata.tests.factories
import
(
CorporateEndorsementFactory
,
CourseFactory
,
from
course_discovery.apps.course_metadata.tests.factories
import
(
CourseRunFactory
,
EndorsementFactory
,
CorporateEndorsementFactory
,
CourseFactory
,
CourseRunFactory
,
EndorsementFactory
,
ExpectedLearningItemFactory
,
ExpectedLearningItemFactory
,
ImageFactory
,
ImageFactory
,
JobOutlookItemFactory
,
OrganizationFactory
,
PersonFactory
,
PositionFactory
,
PrerequisiteFactory
,
JobOutlookItemFactory
,
OrganizationFactory
,
ProgramFactory
,
ProgramTypeFactory
,
SeatFactory
,
SeatTypeFactory
,
SubjectFactory
,
VideoFactory
PersonFactory
,
PositionFactory
,
PrerequisiteFactory
,
)
ProgramFactory
,
ProgramTypeFactory
,
SeatFactory
,
SeatTypeFactory
,
SubjectFactory
,
VideoFactory
)
from
course_discovery.apps.ietf_language_tags.models
import
LanguageTag
from
course_discovery.apps.ietf_language_tags.models
import
LanguageTag
...
@@ -615,7 +608,7 @@ class MinimalProgramSerializerTests(TestCase):
...
@@ -615,7 +608,7 @@ class MinimalProgramSerializerTests(TestCase):
courses
=
CourseFactory
.
create_batch
(
3
)
courses
=
CourseFactory
.
create_batch
(
3
)
for
course
in
courses
:
for
course
in
courses
:
CourseRunFactory
.
create_batch
(
2
,
course
=
course
,
staff
=
[
person
],
start
=
datetime
.
datetime
.
now
(
pytz
.
UTC
))
CourseRunFactory
.
create_batch
(
2
,
course
=
course
,
staff
=
[
person
],
start
=
datetime
.
datetime
.
now
(
UTC
))
return
ProgramFactory
(
return
ProgramFactory
(
courses
=
courses
,
courses
=
courses
,
...
@@ -730,21 +723,21 @@ class ProgramSerializerTests(MinimalProgramSerializerTests):
...
@@ -730,21 +723,21 @@ class ProgramSerializerTests(MinimalProgramSerializerTests):
CourseRunFactory
(
CourseRunFactory
(
course
=
course_list
[
2
],
course
=
course_list
[
2
],
enrollment_start
=
None
,
enrollment_start
=
None
,
start
=
datetime
.
datetime
(
2014
,
2
,
1
),
start
=
datetime
.
datetime
(
2014
,
2
,
1
,
tzinfo
=
UTC
),
)
)
# Create a second run with matching start, but later enrollment_start.
# Create a second run with matching start, but later enrollment_start.
CourseRunFactory
(
CourseRunFactory
(
course
=
course_list
[
1
],
course
=
course_list
[
1
],
enrollment_start
=
datetime
.
datetime
(
2014
,
1
,
2
),
enrollment_start
=
datetime
.
datetime
(
2014
,
1
,
2
),
start
=
datetime
.
datetime
(
2014
,
2
,
1
),
start
=
datetime
.
datetime
(
2014
,
2
,
1
,
tzinfo
=
UTC
),
)
)
# Create a third run with later start and enrollment_start.
# Create a third run with later start and enrollment_start.
CourseRunFactory
(
CourseRunFactory
(
course
=
course_list
[
0
],
course
=
course_list
[
0
],
enrollment_start
=
datetime
.
datetime
(
2014
,
2
,
1
),
enrollment_start
=
datetime
.
datetime
(
2014
,
2
,
1
,
tzinfo
=
UTC
),
start
=
datetime
.
datetime
(
2014
,
3
,
1
),
start
=
datetime
.
datetime
(
2014
,
3
,
1
,
tzinfo
=
UTC
),
)
)
program
=
ProgramFactory
(
courses
=
course_list
)
program
=
ProgramFactory
(
courses
=
course_list
)
...
@@ -772,28 +765,28 @@ class ProgramSerializerTests(MinimalProgramSerializerTests):
...
@@ -772,28 +765,28 @@ class ProgramSerializerTests(MinimalProgramSerializerTests):
excluded_run
=
CourseRunFactory
(
excluded_run
=
CourseRunFactory
(
course
=
course_list
[
0
],
course
=
course_list
[
0
],
enrollment_start
=
None
,
enrollment_start
=
None
,
start
=
datetime
.
datetime
(
2014
,
1
,
1
),
start
=
datetime
.
datetime
(
2014
,
1
,
1
,
tzinfo
=
UTC
),
)
)
# Create a run with later start and empty enrollment_start.
# Create a run with later start and empty enrollment_start.
CourseRunFactory
(
CourseRunFactory
(
course
=
course_list
[
2
],
course
=
course_list
[
2
],
enrollment_start
=
None
,
enrollment_start
=
None
,
start
=
datetime
.
datetime
(
2014
,
2
,
1
),
start
=
datetime
.
datetime
(
2014
,
2
,
1
,
tzinfo
=
UTC
),
)
)
# Create a run with matching start, but later enrollment_start.
# Create a run with matching start, but later enrollment_start.
CourseRunFactory
(
CourseRunFactory
(
course
=
course_list
[
1
],
course
=
course_list
[
1
],
enrollment_start
=
datetime
.
datetime
(
2014
,
1
,
2
),
enrollment_start
=
datetime
.
datetime
(
2014
,
1
,
2
),
start
=
datetime
.
datetime
(
2014
,
2
,
1
),
start
=
datetime
.
datetime
(
2014
,
2
,
1
,
tzinfo
=
UTC
),
)
)
# Create a run with later start and enrollment_start.
# Create a run with later start and enrollment_start.
CourseRunFactory
(
CourseRunFactory
(
course
=
course_list
[
0
],
course
=
course_list
[
0
],
enrollment_start
=
datetime
.
datetime
(
2014
,
2
,
1
),
enrollment_start
=
datetime
.
datetime
(
2014
,
2
,
1
,
tzinfo
=
UTC
),
start
=
datetime
.
datetime
(
2014
,
3
,
1
),
start
=
datetime
.
datetime
(
2014
,
3
,
1
,
tzinfo
=
UTC
),
)
)
program
=
ProgramFactory
(
courses
=
course_list
,
excluded_course_runs
=
[
excluded_run
])
program
=
ProgramFactory
(
courses
=
course_list
,
excluded_course_runs
=
[
excluded_run
])
...
@@ -819,14 +812,14 @@ class ProgramSerializerTests(MinimalProgramSerializerTests):
...
@@ -819,14 +812,14 @@ class ProgramSerializerTests(MinimalProgramSerializerTests):
CourseRunFactory
(
CourseRunFactory
(
course
=
course_list
[
2
],
course
=
course_list
[
2
],
enrollment_start
=
None
,
enrollment_start
=
None
,
start
=
datetime
.
datetime
(
2014
,
2
,
1
),
start
=
datetime
.
datetime
(
2014
,
2
,
1
,
tzinfo
=
UTC
),
)
)
# Create a second run with matching start, but later enrollment_start.
# Create a second run with matching start, but later enrollment_start.
CourseRunFactory
(
CourseRunFactory
(
course
=
course_list
[
1
],
course
=
course_list
[
1
],
enrollment_start
=
datetime
.
datetime
(
2014
,
1
,
2
),
enrollment_start
=
datetime
.
datetime
(
2014
,
1
,
2
),
start
=
datetime
.
datetime
(
2014
,
2
,
1
),
start
=
datetime
.
datetime
(
2014
,
2
,
1
,
tzinfo
=
UTC
),
)
)
# Create a third run with empty start and enrollment_start.
# Create a third run with empty start and enrollment_start.
...
@@ -867,7 +860,7 @@ class ProgramSerializerTests(MinimalProgramSerializerTests):
...
@@ -867,7 +860,7 @@ class ProgramSerializerTests(MinimalProgramSerializerTests):
CourseRunFactory
(
status
=
CourseRunStatus
.
Unpublished
,
course
=
course
)
CourseRunFactory
(
status
=
CourseRunStatus
.
Unpublished
,
course
=
course
)
marketable_enrollable_run
=
CourseRunFactory
(
marketable_enrollable_run
=
CourseRunFactory
(
status
=
CourseRunStatus
.
Published
,
status
=
CourseRunStatus
.
Published
,
end
=
datetime
.
datetime
.
now
(
pytz
.
UTC
)
+
datetime
.
timedelta
(
days
=
10
),
end
=
datetime
.
datetime
.
now
(
UTC
)
+
datetime
.
timedelta
(
days
=
10
),
enrollment_start
=
None
,
enrollment_start
=
None
,
enrollment_end
=
None
,
enrollment_end
=
None
,
course
=
course
course
=
course
...
...
course_discovery/apps/course_metadata/models.py
View file @
2d669183
...
@@ -484,6 +484,23 @@ class CourseRun(TimeStampedModel):
...
@@ -484,6 +484,23 @@ class CourseRun(TimeStampedModel):
"""
"""
return
len
(
self
.
_enrollable_paid_seats
()[:
1
])
>
0
return
len
(
self
.
_enrollable_paid_seats
()[:
1
])
>
0
def
is_current_and_still_upgradeable
(
self
):
"""
Return true if
1. Today is after the run start (or start is none) and two weeks from the run end (or end is none)
2. The run has a seat that is still enrollable and upgradeable
and false otherwise
"""
now
=
datetime
.
datetime
.
now
(
pytz
.
UTC
)
two_weeks
=
datetime
.
timedelta
(
days
=
14
)
after_start
=
(
not
self
.
start
)
or
(
self
.
start
and
self
.
start
<
now
)
ends_in_more_than_two_weeks
=
(
not
self
.
end
)
or
(
self
.
end
.
date
()
and
now
.
date
()
<=
self
.
end
.
date
()
-
two_weeks
)
if
after_start
and
ends_in_more_than_two_weeks
:
paid_seat_enrollment_end
=
self
.
get_paid_seat_enrollment_end
()
if
paid_seat_enrollment_end
and
now
<
paid_seat_enrollment_end
:
return
True
return
False
def
get_paid_seat_enrollment_end
(
self
):
def
get_paid_seat_enrollment_end
(
self
):
"""
"""
Return the final date for which an unenrolled user may enroll and purchase a paid Seat for this CourseRun, or
Return the final date for which an unenrolled user may enroll and purchase a paid Seat for this CourseRun, or
...
...
course_discovery/apps/course_metadata/search_indexes.py
View file @
2d669183
...
@@ -171,6 +171,7 @@ class CourseRunIndex(BaseCourseIndex, indexes.Indexable):
...
@@ -171,6 +171,7 @@ class CourseRunIndex(BaseCourseIndex, indexes.Indexable):
paid_seat_enrollment_end
=
indexes
.
DateTimeField
(
null
=
True
)
paid_seat_enrollment_end
=
indexes
.
DateTimeField
(
null
=
True
)
license
=
indexes
.
MultiValueField
(
model_attr
=
'license'
,
faceted
=
True
)
license
=
indexes
.
MultiValueField
(
model_attr
=
'license'
,
faceted
=
True
)
has_enrollable_seats
=
indexes
.
BooleanField
(
model_attr
=
'has_enrollable_seats'
,
null
=
False
)
has_enrollable_seats
=
indexes
.
BooleanField
(
model_attr
=
'has_enrollable_seats'
,
null
=
False
)
is_current_and_still_upgradeable
=
indexes
.
BooleanField
(
null
=
False
)
def
prepare_aggregation_key
(
self
,
obj
):
def
prepare_aggregation_key
(
self
,
obj
):
# Aggregate CourseRuns by Course key since that is how we plan to dedup CourseRuns on the marketing site.
# Aggregate CourseRuns by Course key since that is how we plan to dedup CourseRuns on the marketing site.
...
@@ -179,6 +180,9 @@ class CourseRunIndex(BaseCourseIndex, indexes.Indexable):
...
@@ -179,6 +180,9 @@ class CourseRunIndex(BaseCourseIndex, indexes.Indexable):
def
prepare_has_enrollable_paid_seats
(
self
,
obj
):
def
prepare_has_enrollable_paid_seats
(
self
,
obj
):
return
obj
.
has_enrollable_paid_seats
()
return
obj
.
has_enrollable_paid_seats
()
def
prepare_is_current_and_still_upgradeable
(
self
,
obj
):
return
obj
.
is_current_and_still_upgradeable
()
def
prepare_paid_seat_enrollment_end
(
self
,
obj
):
def
prepare_paid_seat_enrollment_end
(
self
,
obj
):
return
obj
.
get_paid_seat_enrollment_end
()
return
obj
.
get_paid_seat_enrollment_end
()
...
...
course_discovery/apps/course_metadata/tests/test_models.py
View file @
2d669183
...
@@ -7,6 +7,7 @@ import mock
...
@@ -7,6 +7,7 @@ import mock
import
pytest
import
pytest
import
pytz
import
pytz
from
dateutil.parser
import
parse
from
dateutil.parser
import
parse
from
dateutil.relativedelta
import
relativedelta
from
django.conf
import
settings
from
django.conf
import
settings
from
django.core.exceptions
import
ValidationError
from
django.core.exceptions
import
ValidationError
from
django.db
import
IntegrityError
from
django.db
import
IntegrityError
...
@@ -284,6 +285,31 @@ class CourseRunTests(TestCase):
...
@@ -284,6 +285,31 @@ class CourseRunTests(TestCase):
expected_result
=
parse
(
expected_result
)
if
expected_result
else
None
expected_result
=
parse
(
expected_result
)
if
expected_result
else
None
self
.
assertEqual
(
course_run
.
get_paid_seat_enrollment_end
(),
expected_result
)
self
.
assertEqual
(
course_run
.
get_paid_seat_enrollment_end
(),
expected_result
)
now
=
datetime
.
datetime
.
now
(
pytz
.
timezone
(
'utc'
))
one_month
=
relativedelta
(
months
=
1
)
two_weeks
=
relativedelta
(
days
=
14
)
@ddt.data
(
(
None
,
None
,
None
,
False
),
(
now
-
one_month
,
None
,
None
,
False
),
(
now
-
one_month
,
now
+
one_month
,
None
,
True
),
(
now
-
one_month
,
now
-
one_month
,
now
-
two_weeks
,
False
),
(
now
-
one_month
,
now
+
one_month
,
now
-
two_weeks
,
False
),
(
now
-
one_month
,
now
+
one_month
,
now
+
two_weeks
,
True
),
(
now
+
one_month
,
now
+
one_month
,
now
+
two_weeks
,
False
),
)
@ddt.unpack
def
test_is_current_and_still_upgradeable
(
self
,
start
,
end
,
deadline
,
is_current
):
"""
Verify that is_current_and_still_upgradeable returns true if
1. Today is after the run start (or start is none) and two weeks from the run end (or end is none)
2. The run has a seat that is still enrollable and upgradeable
and false otherwise
"""
course_run
=
factories
.
CourseRunFactory
.
create
(
start
=
start
,
end
=
end
,
enrollment_end
=
end
)
factories
.
SeatFactory
.
create
(
course_run
=
course_run
,
upgrade_deadline
=
deadline
,
type
=
'verified'
,
price
=
1
)
assert
course_run
.
is_current_and_still_upgradeable
()
==
is_current
def
test_publication_disabled
(
self
):
def
test_publication_disabled
(
self
):
"""
"""
Verify that the publisher is not initialized when publication is disabled.
Verify that the publisher is not initialized when publication is disabled.
...
...
course_discovery/apps/edx_haystack_extensions/elasticsearch_boost_config.py
View file @
2d669183
...
@@ -79,6 +79,20 @@ def get_elasticsearch_boost_config():
...
@@ -79,6 +79,20 @@ def get_elasticsearch_boost_config():
'weight'
:
5.0
'weight'
:
5.0
},
},
# Reward course runs that are currently running and still upgradeable
{
'filter'
:
{
'bool'
:
{
'must'
:
{
'term'
:
{
'is_current_and_still_upgradeable'
:
True
}
}
}
},
'weight'
:
10.0
},
# Reward course runs with enrollable, paid seats.
# Reward course runs with enrollable, paid seats.
{
{
'filter'
:
{
'filter'
:
{
...
...
course_discovery/apps/edx_haystack_extensions/tests/test_boosting.py
View file @
2d669183
...
@@ -2,6 +2,7 @@ import datetime
...
@@ -2,6 +2,7 @@ import datetime
import
pytest
import
pytest
import
pytz
import
pytz
from
dateutil.relativedelta
import
relativedelta
from
haystack.query
import
SearchQuerySet
from
haystack.query
import
SearchQuerySet
from
mock
import
patch
from
mock
import
patch
...
@@ -167,3 +168,72 @@ class TestSearchBoosting:
...
@@ -167,3 +168,72 @@ class TestSearchBoosting:
assert
test_record
.
title
==
search_results
[
0
]
.
title
assert
test_record
.
title
==
search_results
[
0
]
.
title
else
:
else
:
assert
search_results
[
0
]
.
score
==
search_results
[
1
]
.
score
assert
search_results
[
0
]
.
score
==
search_results
[
1
]
.
score
now
=
datetime
.
datetime
.
now
(
pytz
.
timezone
(
'utc'
))
one_day
=
relativedelta
(
days
=
1
)
one_month
=
relativedelta
(
months
=
1
)
two_months
=
relativedelta
(
months
=
2
)
three_months
=
relativedelta
(
months
=
3
)
six_months
=
relativedelta
(
months
=
6
)
one_week
=
relativedelta
(
days
=
7
)
two_weeks
=
relativedelta
(
days
=
14
)
one_year
=
relativedelta
(
year
=
1
)
thirteen_months
=
relativedelta
(
months
=
13
)
@pytest.mark.parametrize
(
'runadates, runbdates, pacing_type, boosted'
,
[
# Current Self Paced Course (A) vs Future Self Paced Course (B)
((
now
-
one_month
,
now
+
one_month
),
(
now
+
one_month
,
now
+
two_months
),
'self_paced'
,
'a'
),
# Further Start Current Self Paced Course (A)
# vs Closer Start Current Self Paced Course (B)
((
now
-
two_months
,
now
+
one_month
),
(
now
-
one_month
,
now
+
two_months
),
'self_paced'
,
'b'
),
# Closer Start Future Self Paced Course (A)
# vs Further Start Future Self Paced Course (B)
((
now
+
one_month
,
now
+
one_year
),
(
now
+
two_months
,
now
+
thirteen_months
),
'self_paced'
,
'a'
),
# Current Self Paced Course (A) that ends in two weeks
# vs Future Self Paced Course that starts in two weeks (B)
((
now
-
six_months
,
now
+
two_weeks
),
(
now
+
two_weeks
,
now
+
six_months
),
'self_paced'
,
'a'
),
# Current Instructor Paced Course that ends in one week (A)
# vs Future Instructor Paced Course that starts in one day (B)
((
now
-
six_months
,
now
+
one_week
),
(
now
+
one_day
,
now
+
six_months
),
'instructor_paced'
,
'b'
),
# Current Instructor Paced Course that ends in two weeks (A)
# vs Future Instructor Paced Course that starts in one week (B)
((
now
-
six_months
,
now
+
two_weeks
),
(
now
+
one_week
,
now
+
six_months
),
'instructor_paced'
,
'a'
),
# Future Instructor Paced Course that starts tomorrow (A)
# vs Current Instructor Paced Course that is 2/3rds of the way done (B)
((
now
+
one_day
,
now
+
six_months
),
(
now
-
six_months
,
now
+
three_months
),
'instructor_paced'
,
'b'
),
]
)
def
test_current_run_boosting
(
self
,
runadates
,
runbdates
,
pacing_type
,
boosted
):
"""Verify that "current" CourseRuns are boosted.
See the is_current_and_still_upgradeable CourseRun property to understand what this means."""
(
starta
,
enda
)
=
runadates
(
startb
,
endb
)
=
runbdates
now
=
datetime
.
datetime
.
now
(
pytz
.
timezone
(
'utc'
))
upgrade_deadline_tomorrow
=
now
+
relativedelta
(
days
=
1
)
with
patch
.
object
(
CourseRun
,
'get_paid_seat_enrollment_end'
,
return_value
=
upgrade_deadline_tomorrow
):
runa
=
self
.
build_normalized_course_run
(
title
=
'test1'
,
start
=
starta
,
end
=
enda
,
pacing_type
=
pacing_type
)
runb
=
self
.
build_normalized_course_run
(
title
=
'test2'
,
start
=
startb
,
end
=
endb
,
pacing_type
=
pacing_type
)
search_results
=
SearchQuerySet
()
.
models
(
CourseRun
)
.
all
()
assert
len
(
search_results
)
==
2
if
boosted
==
'a'
:
assert
search_results
[
0
]
.
score
>
search_results
[
1
]
.
score
assert
runa
.
title
==
search_results
[
0
]
.
title
else
:
assert
search_results
[
0
]
.
score
>
search_results
[
1
]
.
score
assert
runb
.
title
==
search_results
[
0
]
.
title
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