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
e63cf7ff
Unverified
Commit
e63cf7ff
authored
Nov 03, 2017
by
Nimisha Asthagiri
Committed by
GitHub
Nov 03, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #16446 from edx/naa/course-highlights-4
Course Week Highlights accessor
parents
535d39d5
4f2fdde2
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 @
e63cf7ff
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 @
e63cf7ff
...
...
@@ -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 @
e63cf7ff
...
...
@@ -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 @
e63cf7ff
# -*- 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 @
e63cf7ff
...
...
@@ -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 @
e63cf7ff
...
...
@@ -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