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
bc5daffc
Commit
bc5daffc
authored
May 09, 2016
by
AlasdairSwan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ECOM-4215 adding setup for new program details page
parent
91d04979
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
213 additions
and
10 deletions
+213
-10
common/test/acceptance/pages/lms/programs.py
+8
-0
common/test/acceptance/tests/lms/test_programs.py
+30
-6
lms/djangoapps/learner_dashboard/tests/test_programs.py
+37
-1
lms/djangoapps/learner_dashboard/urls.py
+1
-0
lms/djangoapps/learner_dashboard/views.py
+17
-0
lms/static/js/learner_dashboard/program_details_factory.js
+13
-0
lms/static/js/learner_dashboard/views/program_details_view.js
+38
-0
lms/static/lms/js/build.js
+1
-0
lms/templates/learner_dashboard/program_details.html
+24
-0
lms/templates/learner_dashboard/program_details_view.underscore
+9
-0
lms/templates/navigation.html
+1
-1
openedx/core/djangoapps/programs/migrations/0008_programsapiconfig_program_details_enabled.py
+19
-0
openedx/core/djangoapps/programs/models.py
+12
-0
openedx/core/djangoapps/programs/tests/mixins.py
+1
-0
themes/edx.org/lms/templates/header.html
+1
-1
themes/red-theme/lms/templates/header.html
+1
-1
No files found.
common/test/acceptance/pages/lms/programs.py
View file @
bc5daffc
...
...
@@ -20,3 +20,11 @@ class ProgramListingPage(PageObject):
def
is_sidebar_present
(
self
):
"""Check whether sidebar is present."""
return
self
.
q
(
css
=
'.sidebar'
)
.
present
class
ProgramDetailsPage
(
PageObject
):
"""Program details page."""
url
=
BASE_URL
+
'/dashboard/programs/123'
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
'.js-program-details-wrapper'
)
.
present
common/test/acceptance/tests/lms/test_programs.py
View file @
bc5daffc
...
...
@@ -5,16 +5,15 @@ from ...fixtures.programs import FakeProgram, ProgramsFixture, ProgramsConfigMix
from
...fixtures.course
import
CourseFixture
from
..helpers
import
UniqueCourseTest
from
...pages.lms.auto_auth
import
AutoAuthPage
from
...pages.lms.programs
import
ProgramListingPage
from
...pages.lms.programs
import
ProgramListingPage
,
ProgramDetailsPage
class
Program
Listing
PageBase
(
ProgramsConfigMixin
,
UniqueCourseTest
):
class
ProgramPageBase
(
ProgramsConfigMixin
,
UniqueCourseTest
):
"""Base class used for program listing page tests."""
def
setUp
(
self
):
super
(
Program
Listing
PageBase
,
self
)
.
setUp
()
super
(
ProgramPageBase
,
self
)
.
setUp
()
self
.
set_programs_api_configuration
(
is_enabled
=
True
)
self
.
listing_page
=
ProgramListingPage
(
self
.
browser
)
def
stub_api
(
self
,
course_id
=
None
):
"""Stub out the programs API with fake data."""
...
...
@@ -35,8 +34,13 @@ class ProgramListingPageBase(ProgramsConfigMixin, UniqueCourseTest):
AutoAuthPage
(
self
.
browser
,
course_id
=
course_id
)
.
visit
()
class
ProgramListingPageTest
(
Program
Listing
PageBase
):
class
ProgramListingPageTest
(
ProgramPageBase
):
"""Verify user-facing behavior of the program listing page."""
def
setUp
(
self
):
super
(
ProgramListingPageTest
,
self
)
.
setUp
()
self
.
listing_page
=
ProgramListingPage
(
self
.
browser
)
def
test_no_enrollments
(
self
):
"""Verify that no cards appear when the user has no enrollments."""
self
.
stub_api
()
...
...
@@ -76,8 +80,12 @@ class ProgramListingPageTest(ProgramListingPageBase):
@attr
(
'a11y'
)
class
ProgramListingPageA11yTest
(
Program
Listing
PageBase
):
class
ProgramListingPageA11yTest
(
ProgramPageBase
):
"""Test program listing page accessibility."""
def
setUp
(
self
):
super
(
ProgramListingPageA11yTest
,
self
)
.
setUp
()
self
.
listing_page
=
ProgramListingPage
(
self
.
browser
)
def
test_empty_a11y
(
self
):
"""Test a11y of the page's empty state."""
...
...
@@ -100,3 +108,19 @@ class ProgramListingPageA11yTest(ProgramListingPageBase):
self
.
assertTrue
(
self
.
listing_page
.
are_cards_present
)
self
.
listing_page
.
a11y_audit
.
check_for_accessibility_errors
()
@attr
(
'a11y'
)
class
ProgramDetailsPageA11yTest
(
ProgramPageBase
):
"""Test program details page accessibility."""
def
setUp
(
self
):
super
(
ProgramDetailsPageA11yTest
,
self
)
.
setUp
()
self
.
details_page
=
ProgramDetailsPage
(
self
.
browser
)
def
test_a11y
(
self
):
"""Test a11y of the page's state."""
self
.
auth
(
enroll
=
False
)
self
.
details_page
.
visit
()
self
.
details_page
.
a11y_audit
.
check_for_accessibility_errors
()
lms/djangoapps/learner_dashboard/tests/test_programs.py
View file @
bc5daffc
...
...
@@ -8,7 +8,7 @@ from urlparse import urljoin
from
django.conf
import
settings
from
django.core.urlresolvers
import
reverse
from
django.test
import
override_settings
from
django.test
import
override_settings
,
TestCase
from
edx_oauth2_provider.tests.factories
import
ClientFactory
from
opaque_keys.edx
import
locator
from
provider.constants
import
CONFIDENTIAL
...
...
@@ -205,3 +205,39 @@ class TestProgramListing(
for
certificate
in
self
.
_expected_credentials_data
():
self
.
assertNotContains
(
response
,
certificate
[
'display_name'
])
self
.
assertNotContains
(
response
,
certificate
[
'credential_url'
])
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
@override_settings
(
MKTG_URLS
=
{
'ROOT'
:
'http://edx.org'
})
class
TestProgramDetails
(
ProgramsApiConfigMixin
,
TestCase
):
"""
Unit tests for the program details page
"""
def
setUp
(
self
):
super
(
TestProgramDetails
,
self
)
.
setUp
()
self
.
user
=
UserFactory
()
self
.
details_page
=
reverse
(
'program_details_view'
,
args
=
[
'123'
])
def
test_login_required
(
self
):
"""
Verify that login is required to access the page.
"""
self
.
create_programs_config
()
response
=
self
.
client
.
get
(
self
.
details_page
)
self
.
assertRedirects
(
response
,
'{}?next={}'
.
format
(
reverse
(
'signin_user'
),
self
.
details_page
)
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
'test'
)
response
=
self
.
client
.
get
(
self
.
details_page
)
self
.
assertEquals
(
response
.
status_code
,
200
)
def
test_404_if_disabled
(
self
):
"""
Verify that the page 404s if disabled.
"""
self
.
create_programs_config
(
program_details_enabled
=
False
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
'test'
)
response
=
self
.
client
.
get
(
self
.
details_page
)
self
.
assertEquals
(
response
.
status_code
,
404
)
lms/djangoapps/learner_dashboard/urls.py
View file @
bc5daffc
...
...
@@ -6,5 +6,6 @@ from django.conf.urls import url
from
.
import
views
urlpatterns
=
[
url
(
r'^programs/(?P<program_uuid>[0-9a-f-]+)/$'
,
views
.
program_details
,
name
=
'program_details_view'
),
url
(
r'^programs/$'
,
views
.
view_programs
,
name
=
'program_listing_view'
),
]
lms/djangoapps/learner_dashboard/views.py
View file @
bc5daffc
...
...
@@ -45,3 +45,20 @@ def view_programs(request):
}
return
render_to_response
(
'learner_dashboard/programs.html'
,
context
)
@login_required
@require_GET
def
program_details
(
request
,
program_uuid
):
# pylint: disable=unused-argument
"""View programs in which the user is engaged."""
show_program_details
=
ProgramsApiConfig
.
current
()
.
show_program_details
if
not
show_program_details
:
raise
Http404
context
=
{
'nav_hidden'
:
True
,
'disable_courseware_js'
:
True
,
'uses_pattern_library'
:
True
}
return
render_to_response
(
'learner_dashboard/program_details.html'
,
context
)
lms/static/js/learner_dashboard/program_details_factory.js
0 → 100644
View file @
bc5daffc
;(
function
(
define
)
{
'use strict'
;
define
([
'js/learner_dashboard/views/program_details_view'
],
function
(
ProgramDetailsView
)
{
return
function
(
options
)
{
var
ProgramDetails
=
new
ProgramDetailsView
(
options
);
return
ProgramDetails
;
};
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/learner_dashboard/views/program_details_view.js
0 → 100644
View file @
bc5daffc
;(
function
(
define
)
{
'use strict'
;
define
([
'backbone'
,
'jquery'
,
'underscore'
,
'gettext'
,
'text!../../../templates/learner_dashboard/program_details_view.underscore'
],
function
(
Backbone
,
$
,
_
,
gettext
,
pageTpl
)
{
return
Backbone
.
View
.
extend
({
el
:
'.js-program-details-wrapper'
,
tpl
:
_
.
template
(
pageTpl
),
initialize
:
function
(
data
)
{
this
.
context
=
data
.
context
;
this
.
render
();
},
render
:
function
()
{
this
.
$el
.
html
(
this
.
tpl
(
this
.
context
));
this
.
postRender
();
},
postRender
:
function
()
{
// Add subviews
}
});
}
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/lms/js/build.js
View file @
bc5daffc
...
...
@@ -35,6 +35,7 @@
'support/js/certificates_factory'
,
'support/js/enrollment_factory'
,
'js/bookmarks/bookmarks_factory'
,
'js/learner_dashboard/program_details_factory'
,
'js/learner_dashboard/program_list_factory'
,
'js/api_admin/catalog_preview_factory'
]),
...
...
lms/templates/learner_dashboard/program_details.html
0 → 100644
View file @
bc5daffc
## Override the default styles_version to the Pattern Library version (version 2)
<
%!
main_css =
"style-learner-dashboard"
%
>
<
%
page
expression_filter=
"h"
/>
<
%
inherit
file=
"../main.html"
/>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
from
openedx
.
core
.
djangolib
.
js_utils
import
(
dump_js_escaped_json
,
js_escaped_string
)
%
>
<
%
block
name=
"js_extra"
>
<
%
static:require_module
module_name=
"js/learner_dashboard/program_details_factory"
class_name=
"ProgramDetailsFactory"
>
ProgramDetailsFactory({});
</
%
static:require
_module
>
</
%
block>
<
%
block
name=
"pagetitle"
>
${_("Program Details")}
</
%
block>
<main
id=
"main"
aria-label=
"Content"
tabindex=
"-1"
>
<div
class=
"js-program-details-wrapper grid-container"
></div>
</main>
lms/templates/learner_dashboard/program_details_view.underscore
0 → 100644
View file @
bc5daffc
<header class="program-header">
<div>
<h2 class="hd-2">Program Title</h2>
<p>Program Subtitle</p>
</div>
</header>
<div class="js-program-progress-view"></div>
<div class="js-course-list"></div>
<aside class="js-course-sidebar"></aside>
lms/templates/navigation.html
View file @
bc5daffc
...
...
@@ -85,7 +85,7 @@ site_status_msg = get_site_status_msg(course_id)
</a>
</li>
<li
class=
"tab-nav-item"
>
<a
class=
"${'active ' if reverse('program_listing_view')
==
request.path else ''}tab-nav-link"
href=
"${reverse('program_listing_view')}"
>
<a
class=
"${'active ' if reverse('program_listing_view')
in
request.path else ''}tab-nav-link"
href=
"${reverse('program_listing_view')}"
>
${_("Programs")}
</a>
</li>
...
...
openedx/core/djangoapps/programs/migrations/0008_programsapiconfig_program_details_enabled.py
0 → 100644
View file @
bc5daffc
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'programs'
,
'0007_programsapiconfig_program_listing_enabled'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'programsapiconfig'
,
name
=
'program_details_enabled'
,
field
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
'Do we want to show program details pages'
),
),
]
openedx/core/djangoapps/programs/models.py
View file @
bc5daffc
...
...
@@ -84,6 +84,11 @@ class ProgramsApiConfig(ConfigurationModel):
default
=
False
)
program_details_enabled
=
models
.
BooleanField
(
verbose_name
=
_
(
"Do we want to show program details pages"
),
default
=
False
)
@property
def
internal_api_url
(
self
):
"""
...
...
@@ -156,3 +161,10 @@ class ProgramsApiConfig(ConfigurationModel):
Indicates whether we want to show program listing page
"""
return
self
.
enabled
and
self
.
program_listing_enabled
@property
def
show_program_details
(
self
):
"""
Indicates whether we want to show program details pages
"""
return
self
.
enabled
and
self
.
program_details_enabled
openedx/core/djangoapps/programs/tests/mixins.py
View file @
bc5daffc
...
...
@@ -22,6 +22,7 @@ class ProgramsApiConfigMixin(object):
'enable_studio_tab'
:
True
,
'enable_certification'
:
True
,
'xseries_ad_enabled'
:
True
,
'program_details_enabled'
:
True
,
}
def
create_programs_config
(
self
,
**
kwargs
):
...
...
themes/edx.org/lms/templates/header.html
View file @
bc5daffc
...
...
@@ -92,7 +92,7 @@ site_status_msg = get_site_status_msg(course_id)
</a>
</li>
<li
class=
"tab-nav-item"
>
<a
class=
"${'active ' if reverse('program_listing_view')
==
request.path else ''}tab-nav-link"
href=
"${reverse('program_listing_view')}"
>
<a
class=
"${'active ' if reverse('program_listing_view')
in
request.path else ''}tab-nav-link"
href=
"${reverse('program_listing_view')}"
>
${_("Programs")}
</a>
</li>
...
...
themes/red-theme/lms/templates/header.html
View file @
bc5daffc
...
...
@@ -81,7 +81,7 @@ site_status_msg = get_site_status_msg(course_id)
</a>
</li>
<li
class=
"tab-nav-item"
>
<a
class=
"${'active ' if reverse('program_listing_view')
==
request.path else ''}tab-nav-link"
href=
"${reverse('program_listing_view')}"
>
<a
class=
"${'active ' if reverse('program_listing_view')
in
request.path else ''}tab-nav-link"
href=
"${reverse('program_listing_view')}"
>
${_("Programs")}
</a>
</li>
...
...
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