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
f5de0bbf
Commit
f5de0bbf
authored
Apr 27, 2015
by
muzaffaryousaf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enable unit preview by default.
TNL-1261
parent
d60b4eed
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
93 additions
and
58 deletions
+93
-58
cms/static/js/spec/views/pages/container_subviews_spec.js
+4
-16
cms/static/js/views/pages/container.js
+2
-2
cms/static/js/views/pages/container_subviews.js
+5
-12
cms/templates/container.html
+3
-3
cms/templates/js/mock/mock-container-page.underscore
+3
-3
cms/templates/ux/reference/container.html
+1
-1
common/test/acceptance/pages/studio/container.py
+1
-1
lms/djangoapps/courseware/access.py
+10
-1
lms/djangoapps/courseware/tests/test_access.py
+58
-16
lms/djangoapps/courseware/views.py
+3
-3
lms/envs/common.py
+3
-0
No files found.
cms/static/js/spec/views/pages/container_subviews_spec.js
View file @
f5de0bbf
...
...
@@ -78,15 +78,16 @@ define(["jquery", "underscore", "underscore.string", "js/common_helpers/ajax_hel
respondWithJson
(
json
);
};
describe
(
"
PreviewActi
onController"
,
function
()
{
describe
(
"
ViewLiveButt
onController"
,
function
()
{
var
viewPublishedCss
=
'.button-view'
,
previewCss
=
'.button-preview'
,
visibilityNoteCss
=
'.note-visibility'
;
it
(
'renders correctly for unscheduled unit'
,
function
()
{
renderContainerPage
(
this
,
mockContainerXBlockHtml
);
expect
(
containerPage
.
$
(
viewPublishedCss
)).
toHaveClass
(
disabledCss
);
expect
(
containerPage
.
$
(
previewCss
)).
not
.
toHaveClass
(
disabledCss
);
expect
(
containerPage
.
$
(
viewPublishedCss
).
attr
(
'title'
)).
toBe
(
"Open the courseware in the LMS"
);
expect
(
containerPage
.
$
(
'.button-preview'
)).
not
.
toHaveClass
(
disabledCss
);
expect
(
containerPage
.
$
(
'.button-preview'
).
attr
(
'title'
)).
toBe
(
"Preview the courseware in the LMS"
);
});
it
(
'updates when publish state changes'
,
function
()
{
...
...
@@ -98,19 +99,6 @@ define(["jquery", "underscore", "underscore.string", "js/common_helpers/ajax_hel
expect
(
containerPage
.
$
(
viewPublishedCss
)).
toHaveClass
(
disabledCss
);
});
it
(
'updates when has_changes attribute changes'
,
function
()
{
renderContainerPage
(
this
,
mockContainerXBlockHtml
);
fetch
({
has_changes
:
true
});
expect
(
containerPage
.
$
(
previewCss
)).
not
.
toHaveClass
(
disabledCss
);
fetch
({
published
:
true
,
has_changes
:
false
});
expect
(
containerPage
.
$
(
previewCss
)).
toHaveClass
(
disabledCss
);
// If published is false, preview is always enabled.
fetch
({
published
:
false
,
has_changes
:
false
});
expect
(
containerPage
.
$
(
previewCss
)).
not
.
toHaveClass
(
disabledCss
);
});
it
(
'updates when has_content_group_components attribute changes'
,
function
()
{
renderContainerPage
(
this
,
mockContainerXBlockHtml
);
fetch
({
has_content_group_components
:
false
});
...
...
cms/static/js/views/pages/container.js
View file @
f5de0bbf
...
...
@@ -68,11 +68,11 @@ define(["jquery", "underscore", "gettext", "js/views/pages/base_page", "js/views
});
this
.
publishHistory
.
render
();
this
.
previewActions
=
new
ContainerSubviews
.
PreviewActi
onController
({
this
.
viewLiveActions
=
new
ContainerSubviews
.
ViewLiveButt
onController
({
el
:
this
.
$
(
'.nav-actions'
),
model
:
this
.
model
});
this
.
preview
Actions
.
render
();
this
.
viewLive
Actions
.
render
();
this
.
unitOutlineView
=
new
UnitOutlineView
({
el
:
this
.
$
(
'.wrapper-unit-overview'
),
...
...
cms/static/js/views/pages/container_subviews.js
View file @
f5de0bbf
...
...
@@ -50,28 +50,21 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/
});
/**
* A controller for updating the "View Live"
and "Preview" buttons
.
* A controller for updating the "View Live"
button
.
*/
var
PreviewActi
onController
=
ContainerStateListenerView
.
extend
({
var
ViewLiveButt
onController
=
ContainerStateListenerView
.
extend
({
shouldRefresh
:
function
(
model
)
{
return
ViewUtils
.
hasChangedAttributes
(
model
,
[
'
has_changes'
,
'
published'
]);
return
ViewUtils
.
hasChangedAttributes
(
model
,
[
'published'
]);
},
render
:
function
()
{
var
previewAction
=
this
.
$el
.
find
(
'.button-preview'
),
viewLiveAction
=
this
.
$el
.
find
(
'.button-view'
);
var
viewLiveAction
=
this
.
$el
.
find
(
'.button-view'
);
if
(
this
.
model
.
get
(
'published'
))
{
viewLiveAction
.
removeClass
(
disabledCss
).
attr
(
'aria-disabled'
,
false
);
}
else
{
viewLiveAction
.
addClass
(
disabledCss
).
attr
(
'aria-disabled'
,
true
);
}
if
(
this
.
model
.
get
(
'has_changes'
)
||
!
this
.
model
.
get
(
'published'
))
{
previewAction
.
removeClass
(
disabledCss
).
attr
(
'aria-disabled'
,
false
);
}
else
{
previewAction
.
addClass
(
disabledCss
).
attr
(
'aria-disabled'
,
true
);
}
}
});
...
...
@@ -256,7 +249,7 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/
return
{
'MessageView'
:
MessageView
,
'
PreviewActionController'
:
PreviewActi
onController
,
'
ViewLiveButtonController'
:
ViewLiveButt
onController
,
'Publisher'
:
Publisher
,
'PublishHistory'
:
PublishHistory
};
...
...
cms/templates/container.html
View file @
f5de0bbf
...
...
@@ -69,13 +69,13 @@ from django.utils.translation import ugettext as _
<ul>
% if is_unit_page:
<li
class=
"action-item action-view nav-item"
>
<a
href=
"${published_preview_link}"
class=
"button button-view action-button is-disabled"
aria-disabled=
"true"
rel=
"external"
>
<a
href=
"${published_preview_link}"
class=
"button button-view action-button is-disabled"
aria-disabled=
"true"
rel=
"external"
title=
"${_('Open the courseware in the LMS')}"
>
<span
class=
"action-button-text"
>
${_("View Live Version")}
</span>
</a>
</li>
<li
class=
"action-item action-preview nav-item"
>
<a
href=
"${draft_preview_link}"
class=
"button button-preview action-button
is-disabled"
aria-disabled=
"true"
rel=
"external
"
>
<span
class=
"action-button-text"
>
${_("Preview
Changes
")}
</span>
<a
href=
"${draft_preview_link}"
class=
"button button-preview action-button
"
rel=
"external"
title=
"${_('Preview the courseware in the LMS')}
"
>
<span
class=
"action-button-text"
>
${_("Preview")}
</span>
</a>
</li>
% else:
...
...
cms/templates/js/mock/mock-container-page.underscore
View file @
f5de0bbf
...
...
@@ -16,13 +16,13 @@
<ul>
% if is_unit_page:
<li class="action-item action-view nav-item">
<a href="${published_preview_link}" class="button button-view action-button is-disabled" aria-disabled="true">
<a href="${published_preview_link}" class="button button-view action-button is-disabled" aria-disabled="true"
title="Open the courseware in the LMS"
>
<span class="action-button-text">View Live Version</span>
</a>
</li>
<li class="action-item action-preview nav-item">
<a href="${draft_preview_link}" class="button button-preview action-button
is-disabled" aria-disabled="true
">
<span class="action-button-text">Preview
Changes
</span>
<a href="${draft_preview_link}" class="button button-preview action-button
" title="Preview the courseware in the LMS
">
<span class="action-button-text">Preview</span>
</a>
</li>
% else:
...
...
cms/templates/ux/reference/container.html
View file @
f5de0bbf
...
...
@@ -46,7 +46,7 @@
</li>
<li
class=
"action-item action-preview nav-item"
>
<a
href=
"#"
class=
"button preview-button action-button"
>
<span
class=
"action-button-text"
>
Preview
Changes
</span>
<span
class=
"action-button-text"
>
Preview
</span>
</a>
</li>
<!-- end publishing changes -->
...
...
common/test/acceptance/pages/studio/container.py
View file @
f5de0bbf
...
...
@@ -209,7 +209,7 @@ class ContainerPage(PageObject):
def
preview
(
self
):
"""
Clicks "Preview
Changes
", which will open the draft version of the unit page in the LMS.
Clicks "Preview", which will open the draft version of the unit page in the LMS.
Switches the browser to the newly opened LMS window.
"""
...
...
lms/djangoapps/courseware/access.py
View file @
f5de0bbf
...
...
@@ -22,6 +22,7 @@ from xmodule.error_module import ErrorDescriptor
from
xmodule.x_module
import
XModule
,
DEPRECATION_VSCOMPAT_EVENT
from
xmodule.split_test_module
import
get_split_user_partitions
from
xmodule.partitions.partitions
import
NoSuchUserPartitionError
,
NoSuchUserPartitionGroupError
from
xmodule.util.django
import
get_current_request_hostname
from
external_auth.models
import
ExternalAuthMap
from
courseware.masquerade
import
get_masquerade_role
,
is_masquerading_as_student
...
...
@@ -436,7 +437,7 @@ def _has_access_descriptor(user, action, descriptor, course_key=None):
descriptor
,
course_key
=
course_key
)
if
now
>
effective_start
:
if
in_preview_mode
()
or
now
>
effective_start
:
# after start date, everyone can see it
debug
(
"Allow: now > effective start date"
)
return
True
...
...
@@ -687,3 +688,11 @@ def get_user_role(user, course_key):
return
'staff'
else
:
return
'student'
def
in_preview_mode
():
"""
Returns whether the user is in preview mode or not.
"""
hostname
=
get_current_request_hostname
()
return
hostname
and
settings
.
PREVIEW_DOMAIN
in
hostname
.
split
(
'.'
)
lms/djangoapps/courseware/tests/test_access.py
View file @
f5de0bbf
...
...
@@ -42,6 +42,16 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase):
self
.
course_staff
=
StaffFactory
(
course_key
=
self
.
course
.
course_key
)
self
.
course_instructor
=
InstructorFactory
(
course_key
=
self
.
course
.
course_key
)
def
verify_access
(
self
,
mock_unit
,
student_should_have_access
):
""" Verify the expected result from _has_access_descriptor """
self
.
assertEqual
(
student_should_have_access
,
access
.
_has_access_descriptor
(
self
.
anonymous_user
,
'load'
,
mock_unit
,
course_key
=
self
.
course
.
course_key
)
)
self
.
assertTrue
(
access
.
_has_access_descriptor
(
self
.
course_staff
,
'load'
,
mock_unit
,
course_key
=
self
.
course
.
course_key
)
)
def
test_has_access_to_course
(
self
):
self
.
assertFalse
(
access
.
_has_access_to_course
(
None
,
'staff'
,
self
.
course
.
course_key
...
...
@@ -132,41 +142,73 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase):
mock_unit
=
Mock
(
user_partitions
=
[])
mock_unit
.
_class_tags
=
{}
# Needed for detached check in _has_access_descriptor
def
verify_access
(
student_should_have_access
):
""" Verify the expected result from _has_access_descriptor """
self
.
assertEqual
(
student_should_have_access
,
access
.
_has_access_descriptor
(
self
.
anonymous_user
,
'load'
,
mock_unit
,
course_key
=
self
.
course
.
course_key
)
)
# staff always has access
self
.
assertTrue
(
access
.
_has_access_descriptor
(
self
.
course_staff
,
'load'
,
mock_unit
,
course_key
=
self
.
course
.
course_key
)
)
# No start date, staff lock on
mock_unit
.
visible_to_staff_only
=
True
verify_access
(
False
)
self
.
verify_access
(
mock_unit
,
False
)
# No start date, staff lock off.
mock_unit
.
visible_to_staff_only
=
False
verify_access
(
True
)
self
.
verify_access
(
mock_unit
,
True
)
# Start date in the past, staff lock on.
mock_unit
.
start
=
datetime
.
datetime
.
now
(
pytz
.
utc
)
-
datetime
.
timedelta
(
days
=
1
)
mock_unit
.
visible_to_staff_only
=
True
verify_access
(
False
)
self
.
verify_access
(
mock_unit
,
False
)
# Start date in the past, staff lock off.
mock_unit
.
visible_to_staff_only
=
False
verify_access
(
True
)
self
.
verify_access
(
mock_unit
,
True
)
# Start date in the future, staff lock on.
mock_unit
.
start
=
datetime
.
datetime
.
now
(
pytz
.
utc
)
+
datetime
.
timedelta
(
days
=
1
)
# release date in the future
mock_unit
.
visible_to_staff_only
=
True
verify_access
(
False
)
self
.
verify_access
(
mock_unit
,
False
)
# Start date in the future, staff lock off.
mock_unit
.
visible_to_staff_only
=
False
verify_access
(
False
)
self
.
verify_access
(
mock_unit
,
False
)
@patch.dict
(
'django.conf.settings.FEATURES'
,
{
'DISABLE_START_DATES'
:
False
})
@patch
(
'courseware.access.get_current_request_hostname'
,
Mock
(
return_value
=
'preview.localhost'
))
def
test__has_access_descriptor_in_preview_mode
(
self
):
"""
Tests that descriptor has access in preview mode.
"""
mock_unit
=
Mock
(
user_partitions
=
[])
mock_unit
.
_class_tags
=
{}
# Needed for detached check in _has_access_descriptor
# No start date.
mock_unit
.
visible_to_staff_only
=
False
self
.
verify_access
(
mock_unit
,
True
)
# Start date in the past.
mock_unit
.
start
=
datetime
.
datetime
.
now
(
pytz
.
utc
)
-
datetime
.
timedelta
(
days
=
1
)
self
.
verify_access
(
mock_unit
,
True
)
# Start date in the future.
mock_unit
.
start
=
datetime
.
datetime
.
now
(
pytz
.
utc
)
+
datetime
.
timedelta
(
days
=
1
)
# release date in the future
self
.
verify_access
(
mock_unit
,
True
)
@patch.dict
(
'django.conf.settings.FEATURES'
,
{
'DISABLE_START_DATES'
:
False
})
@patch
(
'courseware.access.get_current_request_hostname'
,
Mock
(
return_value
=
'localhost'
))
def
test__has_access_descriptor_when_not_in_preview_mode
(
self
):
"""
Tests that descriptor has no access when start date in future & without preview.
"""
mock_unit
=
Mock
(
user_partitions
=
[])
mock_unit
.
_class_tags
=
{}
# Needed for detached check in _has_access_descriptor
# No start date.
mock_unit
.
visible_to_staff_only
=
False
self
.
verify_access
(
mock_unit
,
True
)
# Start date in the past.
mock_unit
.
start
=
datetime
.
datetime
.
now
(
pytz
.
utc
)
-
datetime
.
timedelta
(
days
=
1
)
self
.
verify_access
(
mock_unit
,
True
)
# Start date in the future.
mock_unit
.
start
=
datetime
.
datetime
.
now
(
pytz
.
utc
)
+
datetime
.
timedelta
(
days
=
1
)
# release date in the future
self
.
verify_access
(
mock_unit
,
False
)
def
test__has_access_course_desc_can_enroll
(
self
):
yesterday
=
datetime
.
datetime
.
now
(
pytz
.
utc
)
-
datetime
.
timedelta
(
days
=
1
)
...
...
lms/djangoapps/courseware/views.py
View file @
f5de0bbf
...
...
@@ -31,7 +31,7 @@ from django.db import transaction
from
markupsafe
import
escape
from
courseware
import
grades
from
courseware.access
import
has_access
,
_adjust_start_date_for_beta_testers
from
courseware.access
import
has_access
,
in_preview_mode
,
_adjust_start_date_for_beta_testers
from
courseware.courses
import
(
get_courses
,
get_course
,
get_studio_url
,
get_course_with_access
,
...
...
@@ -427,7 +427,7 @@ def _index_bulk_op(request, course_key, chapter, section, position):
now
=
datetime
.
now
(
UTC
())
effective_start
=
_adjust_start_date_for_beta_testers
(
user
,
course
,
course_key
)
if
staff_access
and
now
<
effective_start
:
if
not
in_preview_mode
()
and
staff_access
and
now
<
effective_start
:
# Disable student view button if user is staff and
# course is not yet visible to students.
context
[
'disable_student_access'
]
=
True
...
...
@@ -702,7 +702,7 @@ def course_info(request, course_id):
now
=
datetime
.
now
(
UTC
())
effective_start
=
_adjust_start_date_for_beta_testers
(
request
.
user
,
course
,
course_key
)
if
staff_access
and
now
<
effective_start
:
if
not
in_preview_mode
()
and
staff_access
and
now
<
effective_start
:
# Disable student view button if user is staff and
# course is not yet visible to students.
context
[
'disable_student_access'
]
=
True
...
...
lms/envs/common.py
View file @
f5de0bbf
...
...
@@ -2295,3 +2295,6 @@ PROFILE_IMAGE_DEFAULT_FILE_EXTENSION = 'png'
PROFILE_IMAGE_SECRET_KEY
=
'placeholder secret key'
PROFILE_IMAGE_MAX_BYTES
=
1024
*
1024
PROFILE_IMAGE_MIN_BYTES
=
100
# This is to check the domain in case of preview.
PREVIEW_DOMAIN
=
'preview'
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