Commit caa5a0ac by Tasawer

ECOM-4334 Update learner dashboard

parent 18cddf6e
...@@ -174,6 +174,12 @@ class DashboardPage(PageObject): ...@@ -174,6 +174,12 @@ class DashboardPage(PageObject):
""" """
self.q(css='.dropdown').first.click() self.q(css='.dropdown').first.click()
def click_username(self):
"""
Click username.
"""
self.q(css='.label-username').first.click()
@property @property
def username_dropdown_link_text(self): def username_dropdown_link_text(self):
""" """
......
...@@ -266,21 +266,17 @@ class OwnLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest): ...@@ -266,21 +266,17 @@ class OwnLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
def test_dashboard_learner_profile_link(self): def test_dashboard_learner_profile_link(self):
""" """
Scenario: Verify that my profile link is present on dashboard page and we can navigate to correct page. Scenario: Verify that when user click on username it will leads to profile page.
Given that I am a registered user. Given that I am a registered user.
When I go to Dashboard page. When I go to Dashboard page.
And I click on username dropdown. And I click on username.
Then I see Profile link in the dropdown menu.
When I click on Profile link.
Then I will be navigated to Profile page. Then I will be navigated to Profile page.
""" """
username, user_id = self.log_in_as_unique_user() username, user_id = self.log_in_as_unique_user()
dashboard_page = DashboardPage(self.browser) dashboard_page = DashboardPage(self.browser)
dashboard_page.visit() dashboard_page.visit()
dashboard_page.click_username_dropdown() dashboard_page.click_username()
self.assertIn('Profile', dashboard_page.username_dropdown_link_text)
dashboard_page.click_my_profile_link()
my_profile_page = LearnerProfilePage(self.browser, username) my_profile_page = LearnerProfilePage(self.browser, username)
my_profile_page.wait_for_page() my_profile_page.wait_for_page()
......
...@@ -19,6 +19,7 @@ from django.test.utils import override_settings ...@@ -19,6 +19,7 @@ from django.test.utils import override_settings
from django.http import HttpRequest from django.http import HttpRequest
from course_modes.models import CourseMode from course_modes.models import CourseMode
from openedx.core.djangoapps.programs.tests.mixins import ProgramsApiConfigMixin
from openedx.core.djangoapps.user_api.accounts.api import activate_account, create_account from openedx.core.djangoapps.user_api.accounts.api import activate_account, create_account
from openedx.core.djangoapps.user_api.accounts import EMAIL_MAX_LENGTH from openedx.core.djangoapps.user_api.accounts import EMAIL_MAX_LENGTH
from openedx.core.djangolib.js_utils import dump_js_escaped_json from openedx.core.djangolib.js_utils import dump_js_escaped_json
...@@ -442,7 +443,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi ...@@ -442,7 +443,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
}) })
class AccountSettingsViewTest(ThirdPartyAuthTestMixin, TestCase): class AccountSettingsViewTest(ThirdPartyAuthTestMixin, TestCase, ProgramsApiConfigMixin):
""" Tests for the account settings view. """ """ Tests for the account settings view. """
USERNAME = 'student' USERNAME = 'student'
...@@ -456,6 +457,7 @@ class AccountSettingsViewTest(ThirdPartyAuthTestMixin, TestCase): ...@@ -456,6 +457,7 @@ class AccountSettingsViewTest(ThirdPartyAuthTestMixin, TestCase):
'year_of_birth', 'year_of_birth',
'preferred_language', 'preferred_language',
] ]
view_path = reverse('account_settings')
@mock.patch("django.conf.settings.MESSAGE_STORAGE", 'django.contrib.messages.storage.cookie.CookieStorage') @mock.patch("django.conf.settings.MESSAGE_STORAGE", 'django.contrib.messages.storage.cookie.CookieStorage')
def setUp(self): def setUp(self):
...@@ -502,12 +504,29 @@ class AccountSettingsViewTest(ThirdPartyAuthTestMixin, TestCase): ...@@ -502,12 +504,29 @@ class AccountSettingsViewTest(ThirdPartyAuthTestMixin, TestCase):
def test_view(self): def test_view(self):
view_path = reverse('account_settings') response = self.client.get(path=self.view_path)
response = self.client.get(path=view_path)
for attribute in self.FIELDS: for attribute in self.FIELDS:
self.assertIn(attribute, response.content) self.assertIn(attribute, response.content)
def test_header_with_programs_listing_enabled(self):
"""
Verify that tabs header will be shown while program listing is enabled.
"""
self.create_programs_config(program_listing_enabled=True)
response = self.client.get(path=self.view_path)
self.assertContains(response, '<li class="tab-nav-item">')
def test_header_with_programs_listing_disabled(self):
"""
Verify that nav header will be shown while program listing is disabled.
"""
self.create_programs_config(program_listing_enabled=False)
response = self.client.get(path=self.view_path)
self.assertContains(response, '<li class="item nav-global-01">')
@override_settings(SITE_NAME=settings.MICROSITE_LOGISTRATION_HOSTNAME) @override_settings(SITE_NAME=settings.MICROSITE_LOGISTRATION_HOSTNAME)
class MicrositeLogistrationTests(TestCase): class MicrositeLogistrationTests(TestCase):
......
...@@ -36,6 +36,7 @@ from third_party_auth import pipeline ...@@ -36,6 +36,7 @@ from third_party_auth import pipeline
from third_party_auth.decorators import xframe_allow_whitelisted from third_party_auth.decorators import xframe_allow_whitelisted
from util.bad_request_rate_limiter import BadRequestRateLimiter from util.bad_request_rate_limiter import BadRequestRateLimiter
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from openedx.core.djangoapps.theming.helpers import is_request_in_themed_site, get_value as get_themed_value from openedx.core.djangoapps.theming.helpers import is_request_in_themed_site, get_value as get_themed_value
from openedx.core.djangoapps.user_api.accounts.api import request_password_change from openedx.core.djangoapps.user_api.accounts.api import request_password_change
from openedx.core.djangoapps.user_api.errors import UserNotFound from openedx.core.djangoapps.user_api.errors import UserNotFound
...@@ -394,6 +395,7 @@ def account_settings_context(request): ...@@ -394,6 +395,7 @@ def account_settings_context(request):
'user_accounts_api_url': reverse("accounts_api", kwargs={'username': user.username}), 'user_accounts_api_url': reverse("accounts_api", kwargs={'username': user.username}),
'user_preferences_api_url': reverse('preferences_api', kwargs={'username': user.username}), 'user_preferences_api_url': reverse('preferences_api', kwargs={'username': user.username}),
'disable_courseware_js': True, 'disable_courseware_js': True,
'show_program_listing': ProgramsApiConfig.current().show_program_listing,
} }
if third_party_auth.is_enabled(): if third_party_auth.is_enabled():
......
...@@ -6,13 +6,13 @@ from django.core.urlresolvers import reverse ...@@ -6,13 +6,13 @@ from django.core.urlresolvers import reverse
from django.test import TestCase from django.test import TestCase
from django.test.client import RequestFactory from django.test.client import RequestFactory
from util.testing import UrlResetMixin from openedx.core.djangoapps.programs.tests.mixins import ProgramsApiConfigMixin
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from student_profile.views import learner_profile_context from student_profile.views import learner_profile_context
from util.testing import UrlResetMixin
class LearnerProfileViewTest(UrlResetMixin, TestCase): class LearnerProfileViewTest(UrlResetMixin, TestCase, ProgramsApiConfigMixin):
""" Tests for the student profile view. """ """ Tests for the student profile view. """
USERNAME = "username" USERNAME = "username"
...@@ -101,3 +101,23 @@ class LearnerProfileViewTest(UrlResetMixin, TestCase): ...@@ -101,3 +101,23 @@ class LearnerProfileViewTest(UrlResetMixin, TestCase):
profile_path = reverse('learner_profile', kwargs={'username': "no_such_user"}) profile_path = reverse('learner_profile', kwargs={'username': "no_such_user"})
response = self.client.get(path=profile_path) response = self.client.get(path=profile_path)
self.assertEqual(404, response.status_code) self.assertEqual(404, response.status_code)
def test_header_with_programs_listing_enabled(self):
"""
Verify that tabs header will be shown while program listing is enabled.
"""
self.create_programs_config(program_listing_enabled=True)
profile_path = reverse('learner_profile', kwargs={'username': self.USERNAME})
response = self.client.get(path=profile_path)
self.assertContains(response, '<li class="tab-nav-item">')
def test_header_with_programs_listing_disabled(self):
"""
Verify that nav header will be shown while program listing is disabled.
"""
self.create_programs_config(program_listing_enabled=False)
profile_path = reverse('learner_profile', kwargs={'username': self.USERNAME})
response = self.client.get(path=profile_path)
self.assertContains(response, '<li class="item nav-global-01">')
...@@ -12,6 +12,7 @@ from django.contrib.staticfiles.storage import staticfiles_storage ...@@ -12,6 +12,7 @@ from django.contrib.staticfiles.storage import staticfiles_storage
from badges.utils import badges_enabled from badges.utils import badges_enabled
from edxmako.shortcuts import render_to_response, marketing_link from edxmako.shortcuts import render_to_response, marketing_link
from microsite_configuration import microsite from microsite_configuration import microsite
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from openedx.core.djangoapps.user_api.accounts.api import get_account_settings from openedx.core.djangoapps.user_api.accounts.api import get_account_settings
from openedx.core.djangoapps.user_api.errors import UserNotFound, UserNotAuthorized from openedx.core.djangoapps.user_api.errors import UserNotFound, UserNotAuthorized
from openedx.core.djangoapps.user_api.preferences.api import get_user_preferences from openedx.core.djangoapps.user_api.preferences.api import get_user_preferences
...@@ -95,6 +96,7 @@ def learner_profile_context(request, profile_username, user_is_staff): ...@@ -95,6 +96,7 @@ def learner_profile_context(request, profile_username, user_is_staff):
'platform_name': microsite.get_value('platform_name', settings.PLATFORM_NAME), 'platform_name': microsite.get_value('platform_name', settings.PLATFORM_NAME),
}, },
'disable_courseware_js': True, 'disable_courseware_js': True,
'show_program_listing': ProgramsApiConfig.current().show_program_listing,
} }
if badges_enabled(): if badges_enabled():
......
...@@ -49,13 +49,21 @@ site_status_msg = get_site_status_msg(course_id) ...@@ -49,13 +49,21 @@ site_status_msg = get_site_status_msg(course_id)
</%block> </%block>
<header id="global-navigation" class="header-global ${"slim" if course else ""}" > <header id="global-navigation" class="header-global ${"slim" if course else ""}" >
<nav class="wrapper-header" aria-label="${_('Global')}"> <nav class="wrapper-header" aria-label="${_('Global')}">
<h1 class="logo"> <h1 class="logo">
<a href="${marketing_link('ROOT')}">
<%block name="navigation_logo"> <%block name="navigation_logo">
<img src="${static.url(branding_api.get_logo_url())}" alt="${_("{platform_name} Home Page").format(platform_name=static.get_platform_name())}"/> % if user.is_authenticated():
</%block> <a href="${reverse('dashboard')}">
</a> <img src="${static.url(branding_api.get_logo_url())}" alt=${_("Your Dashboard")}/>
</h1> </a>
% else:
<a href="${marketing_link('ROOT')}">
<img src="${static.url(branding_api.get_logo_url())}"
alt="${_("{platform_name} Home Page").format(platform_name=static.get_platform_name())}"/>
</a>
% endif
</%block>
</h1>
% if course: % if course:
<h2 class="course-header"><span class="provider">${course.display_org_with_default}:</span> <h2 class="course-header"><span class="provider">${course.display_org_with_default}:</span>
......
...@@ -28,8 +28,6 @@ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_ ...@@ -28,8 +28,6 @@ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_
</button> </button>
<ul class="dropdown-menu list-divided is-hidden" id="${_("Usermenu")}" tabindex="-1"> <ul class="dropdown-menu list-divided is-hidden" id="${_("Usermenu")}" tabindex="-1">
<%block name="navigation_dropdown_menu_links" > <%block name="navigation_dropdown_menu_links" >
<li class="dropdown-item item has-block-link"><a href="${reverse('dashboard')}" class="action">${_("Dashboard")}</a></li>
<li class="dropdown-item item has-block-link"><a href="${reverse('learner_profile', kwargs={'username': user.username})}" class="action">${_("Profile")}</a></li>
<li class="dropdown-item item has-block-link"><a href="${reverse('account_settings')}" class="action">${_("Account")}</a></li> <li class="dropdown-item item has-block-link"><a href="${reverse('account_settings')}" class="action">${_("Account")}</a></li>
</%block> </%block>
<li class="dropdown-item item has-block-link"><a href="${reverse('logout')}" role="menuitem" class="action">${_("Sign Out")}</a></li> <li class="dropdown-item item has-block-link"><a href="${reverse('logout')}" role="menuitem" class="action">${_("Sign Out")}</a></li>
...@@ -38,19 +36,19 @@ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_ ...@@ -38,19 +36,19 @@ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_
% else: % else:
<ol class="user"> <ol class="user">
<li class="primary"> <li class="primary">
<a href="${reverse('dashboard')}" class="user-link"> <a href="${reverse('learner_profile', kwargs={'username': user.username})}" class="user-link">
<span class="sr">${_("Dashboard for:")}</span> <span class="sr">${_("Profile for:")}</span>
<% <%
username = user.username username = user.username
profile_image_url = get_profile_image_urls_for_user(user)['medium'] profile_image_url = get_profile_image_urls_for_user(user)['medium']
%> %>
<img class="user-image-frame" src="${profile_image_url}" alt="${_('Profile image for {username}').format(username=username)}"> <img class="user-image-frame" src="${profile_image_url}" alt="">
<div class="label-username">${username}</div> <div class="label-username">${username}</div>
</a> </a>
</li> </li>
<li class="primary"> <li class="primary">
<button class="dropdown" aria-haspopup="true" aria-expanded="false"><span class="sr">${_("More options dropdown")}</span><span class="fa fa-sort-desc" aria-hidden="true"></span></button> <button class="dropdown" aria-haspopup="true" aria-expanded="false" title=${_("Account settings menu")}><span class="fa fa-sort-desc" aria-hidden="true"></span></button>
<ul class="dropdown-menu" aria-label="More Options" role="menu"> <ul class="dropdown-menu" aria-label=${_("Account settings")} role="menu">
${navigation_dropdown_menu_links()} ${navigation_dropdown_menu_links()}
<li class="item"><a href="${reverse('logout')}" role="menuitem">${_("Sign Out")}</a></li> <li class="item"><a href="${reverse('logout')}" role="menuitem">${_("Sign Out")}</a></li>
</ul> </ul>
......
...@@ -51,11 +51,18 @@ site_status_msg = get_site_status_msg(course_id) ...@@ -51,11 +51,18 @@ site_status_msg = get_site_status_msg(course_id)
% endif % endif
<div class="${"rwd" if responsive else ""} wrapper-header nav-container"> <div class="${"rwd" if responsive else ""} wrapper-header nav-container">
<h1 class="logo" itemscope="" itemtype="http://schema.org/Organization"> <h1 class="logo" itemscope="" itemtype="http://schema.org/Organization">
<a href="${marketing_link('ROOT')}" itemprop="url"> <%block name="navigation_logo">
<%block name="navigation_logo"> % if user.is_authenticated():
<img src="${static.url("images/logo.png")}" alt="${_("{platform_name} Home Page").format(platform_name=static.get_platform_name())}" itemprop="logo" /> <a href="${reverse('dashboard')}">
</%block> <img src="${static.url("images/logo.png")}" alt=${_("Your Dashboard")}/>
</a> </a>
% else:
<a href="${marketing_link('ROOT')}" itemprop="url">
<img src="${static.url("images/logo.png")}" itemprop="logo"
alt="${_("{platform_name} Home Page").format(platform_name=static.get_platform_name())}"/>
</a>
% endif
</%block>
</h1> </h1>
% if course and not disable_courseware_header: % if course and not disable_courseware_header:
...@@ -69,22 +76,8 @@ site_status_msg = get_site_status_msg(course_id) ...@@ -69,22 +76,8 @@ site_status_msg = get_site_status_msg(course_id)
% if user.is_authenticated(): % if user.is_authenticated():
% if not course or disable_courseware_header: % if not course or disable_courseware_header:
% if not nav_hidden or show_program_listing:
<nav aria-label="Main" class="nav-main"> <nav aria-label="Main" class="nav-main">
<ul class="left list-inline nav-global authenticated"> <ul class="left list-inline nav-global authenticated">
% if not nav_hidden:
<%block name="navigation_global_links_authenticated">
<li class="item nav-global-01">
<a href="${marketing_link('HOW_IT_WORKS')}">${_("How it Works")}</a>
</li>
<li class="item nav-global-02">
<a href="${marketing_link('COURSES')}">${_("Find Courses")}</a>
</li>
<li class="item nav-global-03">
<a href="${marketing_link('SCHOOLS')}">${_("Schools & Partners")}</a>
</li>
</%block>
% endif
% if show_program_listing: % if show_program_listing:
<li class="tab-nav-item"> <li class="tab-nav-item">
<a class="${'active ' if reverse('dashboard') == request.path else ''}tab-nav-link" href="${reverse('dashboard')}"> <a class="${'active ' if reverse('dashboard') == request.path else ''}tab-nav-link" href="${reverse('dashboard')}">
...@@ -96,10 +89,21 @@ site_status_msg = get_site_status_msg(course_id) ...@@ -96,10 +89,21 @@ site_status_msg = get_site_status_msg(course_id)
${_("Programs")} ${_("Programs")}
</a> </a>
</li> </li>
% elif not nav_hidden:
<%block name="navigation_global_links_authenticated">
<li class="item nav-global-01">
<a href="${marketing_link('HOW_IT_WORKS')}">${_("How it Works")}</a>
</li>
<li class="item nav-global-02">
<a href="${marketing_link('COURSES')}">${_("Find Courses")}</a>
</li>
<li class="item nav-global-03">
<a href="${marketing_link('SCHOOLS')}">${_("Schools & Partners")}</a>
</li>
</%block>
% endif % endif
</ul> </ul>
</nav> </nav>
% endif
% endif % endif
<%include file="user_dropdown.html"/> <%include file="user_dropdown.html"/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment