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
4f2fdde2
Commit
4f2fdde2
authored
Nov 01, 2017
by
Nimisha Asthagiri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Course Week Highlights accessor
parent
c0d84c8f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
209 additions
and
26 deletions
+209
-26
openedx/core/djangoapps/schedules/content_highlights.py
+86
-0
openedx/core/djangoapps/schedules/resolvers.py
+4
-16
openedx/core/djangoapps/schedules/signals.py
+3
-5
openedx/core/djangoapps/schedules/tests/test_content_highlights.py
+112
-0
openedx/core/djangoapps/schedules/tests/test_resolvers.py
+1
-1
openedx/core/djangoapps/schedules/tests/test_signals.py
+3
-4
No files found.
openedx/core/djangoapps/schedules/content_highlights.py
0 → 100644
View file @
4f2fdde2
from
courseware.module_render
import
get_module_for_descriptor
from
courseware.model_data
import
FieldDataCache
from
openedx.core.djangoapps.schedules.config
import
COURSE_UPDATE_WAFFLE_FLAG
from
openedx.core.djangoapps.schedules.exceptions
import
CourseUpdateDoesNotExist
from
request_cache
import
get_request_or_stub
from
xmodule.modulestore.django
import
modulestore
def
course_has_highlights
(
course_key
):
"""
Does the course have any highlights for any section/week in it?
This ignores access checks, since highlights may be lurking in currently
inaccessible content.
"""
if
not
COURSE_UPDATE_WAFFLE_FLAG
.
is_enabled
(
course_key
):
return
False
course
=
modulestore
()
.
get_course
(
course_key
,
depth
=
1
)
return
any
(
section
.
highlights
for
section
in
course
.
get_children
()
if
not
section
.
hide_from_toc
)
def
get_week_highlights
(
user
,
course_key
,
week_num
):
"""
Get highlights (list of unicode strings) for a given week.
"""
if
not
COURSE_UPDATE_WAFFLE_FLAG
.
is_enabled
(
course_key
):
raise
CourseUpdateDoesNotExist
(
"
%
s does not have Course Updates enabled."
,
course_key
)
course_descriptor
=
_get_course_descriptor
(
course_key
)
course_module
=
_get_course_module
(
course_descriptor
,
user
)
sections_with_highlights
=
_get_sections_with_highlights
(
course_module
)
highlights
=
_get_highlights_for_week
(
sections_with_highlights
,
week_num
,
course_key
)
return
highlights
def
_get_course_descriptor
(
course_key
):
course_descriptor
=
modulestore
()
.
get_course
(
course_key
,
depth
=
1
)
if
course_descriptor
is
None
:
raise
CourseUpdateDoesNotExist
(
"Course {} not found."
.
format
(
course_key
)
)
return
course_descriptor
def
_get_course_module
(
course_descriptor
,
user
):
# Fake a request to fool parts of the courseware that want to inspect it.
request
=
get_request_or_stub
()
request
.
user
=
user
# Now evil modulestore magic to inflate our descriptor with user state and
# permissions checks.
field_data_cache
=
FieldDataCache
.
cache_for_descriptor_descendents
(
course_descriptor
.
id
,
user
,
course_descriptor
,
depth
=
1
,
read_only
=
True
,
)
return
get_module_for_descriptor
(
user
,
request
,
course_descriptor
,
field_data_cache
,
course_descriptor
.
id
,
course
=
course_descriptor
,
)
def
_get_sections_with_highlights
(
course_module
):
return
[
section
for
section
in
course_module
.
get_children
()
if
section
.
highlights
and
not
section
.
hide_from_toc
]
def
_get_highlights_for_week
(
sections
,
week_num
,
course_key
):
# assume each provided section maps to a single week
num_sections
=
len
(
sections
)
if
not
(
0
<=
week_num
<
num_sections
):
raise
CourseUpdateDoesNotExist
(
"Requested week {} but {} has only {} sections."
.
format
(
week_num
+
1
,
course_key
,
num_sections
)
)
section
=
sections
[
week_num
]
return
section
.
highlights
openedx/core/djangoapps/schedules/resolvers.py
View file @
4f2fdde2
...
...
@@ -16,7 +16,7 @@ from edx_ace.recipient import Recipient
from
courseware.date_summary
import
verified_upgrade_deadline_link
,
verified_upgrade_link_is_valid
from
openedx.core.djangoapps.monitoring_utils
import
function_trace
,
set_custom_metric
from
openedx.core.djangoapps.schedules.con
fig
import
COURSE_UPDATE_WAFFLE_FLAG
from
openedx.core.djangoapps.schedules.con
tent_highlights
import
get_week_highlights
from
openedx.core.djangoapps.schedules.exceptions
import
CourseUpdateDoesNotExist
from
openedx.core.djangoapps.schedules.models
import
Schedule
,
ScheduleExperience
from
openedx.core.djangoapps.schedules.utils
import
PrefixedDebugLoggerMixin
...
...
@@ -26,9 +26,6 @@ from openedx.core.djangoapps.schedules.template_context import (
)
from
openedx.core.djangoapps.site_configuration.models
import
SiteConfiguration
from
request_cache.middleware
import
request_cached
from
xmodule.modulestore.django
import
modulestore
LOG
=
logging
.
getLogger
(
__name__
)
...
...
@@ -358,14 +355,14 @@ class CourseUpdateResolver(BinnedSchedulesBaseResolver):
template_context
=
get_base_template_context
(
self
.
site
)
for
schedule
in
schedules
:
enrollment
=
schedule
.
enrollment
user
=
enrollment
.
user
try
:
week_highlights
=
get_week_highlights
(
enrollment
.
course_id
,
week_num
)
week_highlights
=
get_week_highlights
(
user
,
enrollment
.
course_id
,
week_num
)
except
CourseUpdateDoesNotExist
:
continue
user
=
enrollment
.
user
course_id_str
=
str
(
enrollment
.
course_id
)
template_context
.
update
({
'course_name'
:
schedule
.
enrollment
.
course
.
display_name
,
'course_url'
:
absolute_url
(
...
...
@@ -380,12 +377,3 @@ class CourseUpdateResolver(BinnedSchedulesBaseResolver):
template_context
.
update
(
_get_upsell_information_for_schedule
(
user
,
schedule
))
yield
(
user
,
schedule
.
enrollment
.
course
.
language
,
template_context
)
@request_cached
def
get_week_highlights
(
course_id
,
week_num
):
if
COURSE_UPDATE_WAFFLE_FLAG
.
is_enabled
(
course_id
):
course
=
modulestore
()
.
get_course
(
course_id
)
return
course
.
highlights_for_week
(
week_num
)
else
:
raise
CourseUpdateDoesNotExist
()
openedx/core/djangoapps/schedules/signals.py
View file @
4f2fdde2
...
...
@@ -12,9 +12,8 @@ from courseware.models import (
OrgDynamicUpgradeDeadlineConfiguration
)
from
edx_ace.utils
import
date
from
openedx.core.djangoapps.schedules.exceptions
import
CourseUpdateDoesNotExist
from
openedx.core.djangoapps.schedules.models
import
ScheduleExperience
from
openedx.core.djangoapps.schedules.
resolvers
import
get_week
_highlights
from
openedx.core.djangoapps.schedules.
content_highlights
import
course_has
_highlights
from
openedx.core.djangoapps.signals.signals
import
COURSE_START_DATE_CHANGED
from
openedx.core.djangoapps.theming.helpers
import
get_current_site
from
student.models
import
CourseEnrollment
...
...
@@ -62,10 +61,9 @@ def create_schedule(sender, **kwargs):
upgrade_deadline
=
upgrade_deadline
)
try
:
get_week_highlights
(
enrollment
.
course_id
,
1
)
if
course_has_highlights
(
enrollment
.
course_id
):
experience_type
=
ScheduleExperience
.
EXPERIENCES
.
course_updates
e
xcept
CourseUpdateDoesNotExist
:
e
lse
:
experience_type
=
ScheduleExperience
.
EXPERIENCES
.
default
ScheduleExperience
(
schedule
=
schedule
,
experience_type
=
experience_type
)
.
save
()
...
...
openedx/core/djangoapps/schedules/tests/test_content_highlights.py
0 → 100644
View file @
4f2fdde2
# -*- coding: utf-8 -*-
from
openedx.core.djangoapps.schedules.config
import
COURSE_UPDATE_WAFFLE_FLAG
from
openedx.core.djangoapps.schedules.content_highlights
import
get_week_highlights
,
course_has_highlights
from
openedx.core.djangoapps.schedules.exceptions
import
CourseUpdateDoesNotExist
from
openedx.core.djangolib.testing.utils
import
skip_unless_lms
from
openedx.core.djangoapps.waffle_utils.testutils
import
override_waffle_flag
from
xmodule.modulestore.tests.django_utils
import
TEST_DATA_SPLIT_MODULESTORE
,
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
from
student.tests.factories
import
UserFactory
from
student.models
import
CourseEnrollment
@skip_unless_lms
class
TestContentHighlights
(
ModuleStoreTestCase
):
MODULESTORE
=
TEST_DATA_SPLIT_MODULESTORE
def
setUp
(
self
):
super
(
TestContentHighlights
,
self
)
.
setUp
()
self
.
_setup_course
()
self
.
_setup_user
()
def
_setup_course
(
self
):
self
.
course
=
CourseFactory
.
create
()
self
.
course_key
=
self
.
course
.
id
def
_setup_user
(
self
):
self
.
user
=
UserFactory
.
create
()
CourseEnrollment
.
enroll
(
self
.
user
,
self
.
course_key
)
def
_create_chapter
(
self
,
**
kwargs
):
ItemFactory
.
create
(
parent
=
self
.
course
,
category
=
'chapter'
,
**
kwargs
)
@override_waffle_flag
(
COURSE_UPDATE_WAFFLE_FLAG
,
True
)
def
test_non_existent_course_raises_exception
(
self
):
nonexistent_course_key
=
self
.
course_key
.
replace
(
run
=
'no_such_run'
)
with
self
.
assertRaises
(
CourseUpdateDoesNotExist
):
get_week_highlights
(
self
.
user
,
nonexistent_course_key
,
0
)
@override_waffle_flag
(
COURSE_UPDATE_WAFFLE_FLAG
,
True
)
def
test_empty_course_raises_exception
(
self
):
with
self
.
assertRaises
(
CourseUpdateDoesNotExist
):
get_week_highlights
(
self
.
user
,
self
.
course_key
,
0
)
@override_waffle_flag
(
COURSE_UPDATE_WAFFLE_FLAG
,
False
)
def
test_flag_disabled
(
self
):
with
self
.
store
.
bulk_operations
(
self
.
course_key
):
self
.
_create_chapter
(
highlights
=
[
u'highlights'
])
self
.
assertFalse
(
course_has_highlights
(
self
.
course_key
))
with
self
.
assertRaises
(
CourseUpdateDoesNotExist
):
get_week_highlights
(
self
.
user
,
self
.
course_key
,
week_num
=
0
)
@override_waffle_flag
(
COURSE_UPDATE_WAFFLE_FLAG
,
True
)
def
test_flag_enabled
(
self
):
highlights
=
[
u'highlights'
]
with
self
.
store
.
bulk_operations
(
self
.
course_key
):
self
.
_create_chapter
(
highlights
=
highlights
)
self
.
assertTrue
(
course_has_highlights
(
self
.
course_key
))
self
.
assertEqual
(
get_week_highlights
(
self
.
user
,
self
.
course_key
,
week_num
=
0
),
highlights
,
)
@override_waffle_flag
(
COURSE_UPDATE_WAFFLE_FLAG
,
True
)
def
test_course_with_no_highlights
(
self
):
with
self
.
store
.
bulk_operations
(
self
.
course_key
):
self
.
_create_chapter
(
display_name
=
u"Week 1"
)
self
.
_create_chapter
(
display_name
=
u"Week 2"
)
self
.
course
=
self
.
store
.
get_course
(
self
.
course_key
)
self
.
assertEqual
(
len
(
self
.
course
.
get_children
()),
2
)
self
.
assertFalse
(
course_has_highlights
(
self
.
course_key
))
with
self
.
assertRaises
(
CourseUpdateDoesNotExist
):
get_week_highlights
(
self
.
user
,
self
.
course_key
,
week_num
=
0
)
@override_waffle_flag
(
COURSE_UPDATE_WAFFLE_FLAG
,
True
)
def
test_course_with_highlights
(
self
):
with
self
.
store
.
bulk_operations
(
self
.
course_key
):
self
.
_create_chapter
(
highlights
=
[
u'a'
,
u'b'
,
u'á'
])
self
.
_create_chapter
(
highlights
=
[])
self
.
_create_chapter
(
highlights
=
[
u'skipped a week'
])
self
.
assertTrue
(
course_has_highlights
(
self
.
course_key
))
self
.
assertEqual
(
get_week_highlights
(
self
.
user
,
self
.
course_key
,
week_num
=
0
),
[
u'a'
,
u'b'
,
u'á'
],
)
self
.
assertEqual
(
get_week_highlights
(
self
.
user
,
self
.
course_key
,
week_num
=
1
),
[
u'skipped a week'
],
)
with
self
.
assertRaises
(
CourseUpdateDoesNotExist
):
get_week_highlights
(
self
.
user
,
self
.
course_key
,
week_num
=
2
)
@override_waffle_flag
(
COURSE_UPDATE_WAFFLE_FLAG
,
True
)
def
test_staff_only
(
self
):
with
self
.
store
.
bulk_operations
(
self
.
course_key
):
self
.
_create_chapter
(
highlights
=
[
u"I'm a secret!"
],
visible_to_staff_only
=
True
,
)
self
.
assertTrue
(
course_has_highlights
(
self
.
course_key
))
with
self
.
assertRaises
(
CourseUpdateDoesNotExist
):
get_week_highlights
(
self
.
user
,
self
.
course_key
,
week_num
=
0
)
openedx/core/djangoapps/schedules/tests/test_resolvers.py
View file @
4f2fdde2
...
...
@@ -3,7 +3,7 @@ from unittest import skipUnless
import
ddt
from
django.conf
import
settings
from
mock
import
patch
,
DEFAULT
,
Mock
from
mock
import
Mock
from
openedx.core.djangoapps.schedules.resolvers
import
BinnedSchedulesBaseResolver
from
openedx.core.djangoapps.schedules.tests.factories
import
ScheduleConfigFactory
...
...
openedx/core/djangoapps/schedules/tests/test_signals.py
View file @
4f2fdde2
...
...
@@ -6,7 +6,6 @@ from pytz import utc
from
course_modes.models
import
CourseMode
from
course_modes.tests.factories
import
CourseModeFactory
from
courseware.models
import
DynamicUpgradeDeadlineConfiguration
from
openedx.core.djangoapps.content.course_overviews.models
import
CourseOverview
from
openedx.core.djangoapps.schedules.models
import
ScheduleExperience
from
openedx.core.djangoapps.schedules.signals
import
CREATE_SCHEDULE_WAFFLE_FLAG
from
openedx.core.djangoapps.site_configuration.tests.factories
import
SiteFactory
...
...
@@ -88,10 +87,10 @@ class CreateScheduleTests(SharedModuleStoreTestCase):
enrollment
.
schedule
@override_waffle_flag
(
CREATE_SCHEDULE_WAFFLE_FLAG
,
True
)
@patch
(
'openedx.core.djangoapps.schedules.signals.
get_week
_highlights'
)
def
test_create_schedule_course_updates_experience
(
self
,
mock_
get_week
_highlights
,
mock_get_current_site
):
@patch
(
'openedx.core.djangoapps.schedules.signals.
course_has
_highlights'
)
def
test_create_schedule_course_updates_experience
(
self
,
mock_
course_has
_highlights
,
mock_get_current_site
):
site
=
SiteFactory
.
create
()
mock_
get_week
_highlights
.
return_value
=
True
mock_
course_has
_highlights
.
return_value
=
True
mock_get_current_site
.
return_value
=
site
self
.
assert_schedule_created
(
experience_type
=
ScheduleExperience
.
EXPERIENCES
.
course_updates
)
...
...
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