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
a51d35ff
Commit
a51d35ff
authored
Feb 27, 2017
by
Matthew Piatetsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add upgradeable filter to course runs
ECOM-7336
parent
49038df3
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
50 additions
and
7 deletions
+50
-7
course_discovery/apps/api/serializers.py
+1
-1
course_discovery/apps/api/tests/test_serializers.py
+4
-4
course_discovery/apps/api/v1/views/courses.py
+1
-1
course_discovery/apps/course_metadata/query.py
+16
-0
course_discovery/apps/course_metadata/tests/test_query.py
+28
-1
No files found.
course_discovery/apps/api/serializers.py
View file @
a51d35ff
...
...
@@ -542,7 +542,7 @@ class CourseWithProgramsSerializer(CourseSerializer):
if
self
.
context
.
get
(
'marketable_enrollable_course_runs_with_archived'
):
# Same as "marketable_course_runs_only", but includes courses with an end date in the past
course_runs
=
course_runs
.
marketable
()
.
enrollable
()
course_runs
=
course_runs
.
marketable
()
.
enrollable
()
.
upgradeable
()
if
self
.
context
.
get
(
'published_course_runs_only'
):
course_runs
=
course_runs
.
filter
(
status
=
CourseRunStatus
.
Published
)
...
...
course_discovery/apps/api/tests/test_serializers.py
View file @
a51d35ff
...
...
@@ -26,7 +26,7 @@ from course_discovery.apps.core.tests.factories import UserFactory
from
course_discovery.apps.core.tests.helpers
import
make_image_file
from
course_discovery.apps.core.tests.mixins
import
ElasticsearchTestMixin
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
,
Seat
from
course_discovery.apps.course_metadata.tests.factories
import
(
CorporateEndorsementFactory
,
CourseFactory
,
CourseRunFactory
,
EndorsementFactory
,
ExpectedLearningItemFactory
,
ImageFactory
,
JobOutlookItemFactory
,
OrganizationFactory
,
PersonFactory
,
PositionFactory
,
PrerequisiteFactory
,
...
...
@@ -260,9 +260,9 @@ class CourseWithProgramsSerializerTests(CourseSerializerTests):
enrollment_end
=
None
,
course
=
self
.
course
)
SeatFactory
(
course_run
=
unpublished_course_run
)
SeatFactory
(
course_run
=
enrollable_course_run
)
SeatFactory
(
course_run
=
archived_course_run
)
SeatFactory
(
course_run
=
unpublished_course_run
,
upgrade_deadline
=
None
,
type
=
Seat
.
VERIFIED
)
SeatFactory
(
course_run
=
enrollable_course_run
,
upgrade_deadline
=
None
,
type
=
Seat
.
VERIFIED
)
SeatFactory
(
course_run
=
archived_course_run
,
upgrade_deadline
=
None
,
type
=
Seat
.
VERIFIED
)
context
=
{
'request'
:
self
.
request
,
...
...
course_discovery/apps/api/v1/views/courses.py
View file @
a51d35ff
...
...
@@ -76,7 +76,7 @@ class CourseViewSet(viewsets.ReadOnlyModelViewSet):
mulitple: false
- name: marketable_enrollable_course_runs_with_archived
description: Restrict returned course runs to those that are published, have seats,
and can be enrolled in now
. Includes archived courses.
can be enrolled in now and can be upgraded
. Includes archived courses.
required: false
type: integer
paramType: query
...
...
course_discovery/apps/course_metadata/query.py
View file @
a51d35ff
...
...
@@ -83,6 +83,22 @@ class CourseRunQuerySet(models.QuerySet):
status
=
CourseRunStatus
.
Published
)
def
upgradeable
(
self
):
""" Returns course runs which have a verified or professional seat and do not have
an expired upgrade deadline.
Returns:
QuerySet
"""
now
=
datetime
.
datetime
.
now
(
pytz
.
UTC
)
# Nested to avoid circular import.
from
course_discovery.apps.course_metadata.models
import
Seat
return
self
.
filter
(
Q
(
seats__type__contains
=
Seat
.
VERIFIED
)
|
Q
(
seats__type__contains
=
Seat
.
PROFESSIONAL
)
)
.
exclude
(
Q
(
seats__upgrade_deadline__lt
=
now
)
)
class
ProgramQuerySet
(
models
.
QuerySet
):
def
marketable
(
self
):
...
...
course_discovery/apps/course_metadata/tests/test_query.py
View file @
a51d35ff
...
...
@@ -5,7 +5,7 @@ import pytz
from
django.test
import
TestCase
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
,
Seat
from
course_discovery.apps.course_metadata.tests.factories
import
CourseRunFactory
,
ProgramFactory
,
SeatFactory
...
...
@@ -120,6 +120,33 @@ class CourseRunQuerySetTests(TestCase):
self
.
assertEqual
(
CourseRun
.
objects
.
marketable
()
.
exists
(),
is_published
)
def
test_upgradeable
(
self
):
""" Verify the method returns only course runs whose upgrade deadline has not passed
or is not defined for verified/professional modes. """
past
=
datetime
.
datetime
.
now
(
pytz
.
UTC
)
-
datetime
.
timedelta
(
days
=
2
)
future
=
datetime
.
datetime
.
now
(
pytz
.
UTC
)
+
datetime
.
timedelta
(
days
=
2
)
audit_mode
=
CourseRunFactory
()
SeatFactory
(
upgrade_deadline
=
future
,
course_run
=
audit_mode
,
type
=
Seat
.
AUDIT
)
upgrade_deadline_passed
=
CourseRunFactory
()
SeatFactory
(
upgrade_deadline
=
past
,
course_run
=
upgrade_deadline_passed
,
type
=
Seat
.
VERIFIED
)
upgrade_deadline_not_passed
=
CourseRunFactory
()
SeatFactory
(
upgrade_deadline
=
future
,
course_run
=
upgrade_deadline_not_passed
,
type
=
Seat
.
VERIFIED
)
upgrade_deadline_not_defined
=
CourseRunFactory
()
SeatFactory
(
upgrade_deadline
=
None
,
course_run
=
upgrade_deadline_not_defined
,
type
=
Seat
.
VERIFIED
)
SeatFactory
(
upgrade_deadline
=
future
,
course_run
=
upgrade_deadline_not_defined
,
type
=
Seat
.
AUDIT
)
upgrade_deadline_not_defined_professional
=
CourseRunFactory
()
SeatFactory
(
upgrade_deadline
=
None
,
course_run
=
upgrade_deadline_not_defined_professional
,
type
=
Seat
.
PROFESSIONAL
)
# order doesn't matter
assert
sorted
(
CourseRun
.
objects
.
upgradeable
(),
key
=
lambda
x
:
x
.
id
)
==
\
sorted
([
upgrade_deadline_not_passed
,
upgrade_deadline_not_defined
,
upgrade_deadline_not_defined_professional
],
key
=
lambda
x
:
x
.
id
)
@ddt.ddt
class
ProgramQuerySetTests
(
TestCase
):
...
...
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