Fixed 404 on courseware when users last visited subsection becomes unpublished.
LMS-6492
This commit is contained in:
7
common/test/acceptance/pages/common/__init__.py
Normal file
7
common/test/acceptance/pages/common/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import os
|
||||
|
||||
# Get the URL of the instance under test
|
||||
BASE_URL = os.environ.get('test_url', 'http://localhost:8003')
|
||||
|
||||
# The URL used for user auth in testing
|
||||
AUTH_BASE_URL = os.environ.get('test_url', 'http://localhost:8031')
|
||||
16
common/test/acceptance/pages/common/logout.py
Normal file
16
common/test/acceptance/pages/common/logout.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
Logout Page.
|
||||
"""
|
||||
from bok_choy.page_object import PageObject
|
||||
from . import BASE_URL
|
||||
|
||||
|
||||
class LogoutPage(PageObject):
|
||||
"""
|
||||
Logout page to logout current logged in user.
|
||||
"""
|
||||
|
||||
url = BASE_URL + "/logout"
|
||||
|
||||
def is_browser_on_page(self):
|
||||
return self.q(css='.cta-login').present
|
||||
22
common/test/acceptance/pages/lms/problem.py
Normal file
22
common/test/acceptance/pages/lms/problem.py
Normal file
@@ -0,0 +1,22 @@
|
||||
"""
|
||||
Problem Page.
|
||||
"""
|
||||
from bok_choy.page_object import PageObject
|
||||
|
||||
|
||||
class ProblemPage(PageObject):
|
||||
"""
|
||||
View of problem page.
|
||||
"""
|
||||
|
||||
url = None
|
||||
|
||||
def is_browser_on_page(self):
|
||||
return self.q(css='.xblock-student_view').present
|
||||
|
||||
@property
|
||||
def problem_name(self):
|
||||
"""
|
||||
Return the current problem name.
|
||||
"""
|
||||
return self.q(css='.problem-header').text[0]
|
||||
110
common/test/acceptance/tests/test_courseware.py
Normal file
110
common/test/acceptance/tests/test_courseware.py
Normal file
@@ -0,0 +1,110 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
E2E tests for the LMS.
|
||||
"""
|
||||
import time
|
||||
|
||||
from .helpers import UniqueCourseTest
|
||||
from ..pages.studio.auto_auth import AutoAuthPage
|
||||
from ..pages.studio.overview import CourseOutlinePage
|
||||
from ..pages.lms.courseware import CoursewarePage
|
||||
from ..pages.lms.problem import ProblemPage
|
||||
from ..pages.common.logout import LogoutPage
|
||||
from ..fixtures.course import CourseFixture, XBlockFixtureDesc
|
||||
|
||||
|
||||
class CoursewareTest(UniqueCourseTest):
|
||||
"""
|
||||
Test courseware.
|
||||
"""
|
||||
USERNAME = "STUDENT_TESTER"
|
||||
EMAIL = "student101@example.com"
|
||||
|
||||
def setUp(self):
|
||||
super(CoursewareTest, self).setUp()
|
||||
|
||||
self.courseware_page = CoursewarePage(self.browser, self.course_id)
|
||||
|
||||
self.course_outline = CourseOutlinePage(
|
||||
self.browser,
|
||||
self.course_info['org'],
|
||||
self.course_info['number'],
|
||||
self.course_info['run']
|
||||
)
|
||||
|
||||
# Install a course with sections/problems, tabs, updates, and handouts
|
||||
course_fix = CourseFixture(
|
||||
self.course_info['org'], self.course_info['number'],
|
||||
self.course_info['run'], self.course_info['display_name']
|
||||
)
|
||||
|
||||
course_fix.add_children(
|
||||
XBlockFixtureDesc('chapter', 'Test Section 1').add_children(
|
||||
XBlockFixtureDesc('sequential', 'Test Subsection 1').add_children(
|
||||
XBlockFixtureDesc('problem', 'Test Problem 1')
|
||||
)
|
||||
),
|
||||
XBlockFixtureDesc('chapter', 'Test Section 2').add_children(
|
||||
XBlockFixtureDesc('sequential', 'Test Subsection 2').add_children(
|
||||
XBlockFixtureDesc('problem', 'Test Problem 2')
|
||||
)
|
||||
)
|
||||
).install()
|
||||
|
||||
# Auto-auth register for the course.
|
||||
self._auto_auth(self.USERNAME, self.EMAIL, False)
|
||||
|
||||
def _goto_problem_page(self):
|
||||
"""
|
||||
Open problem page with assertion.
|
||||
"""
|
||||
self.courseware_page.visit()
|
||||
self.problem_page = ProblemPage(self.browser)
|
||||
self.assertEqual(self.problem_page.problem_name, 'TEST PROBLEM 1')
|
||||
|
||||
def _change_problem_release_date_in_studio(self):
|
||||
"""
|
||||
|
||||
"""
|
||||
self.course_outline.q(css=".subsection-header-actions .configure-button").first.click()
|
||||
self.course_outline.q(css="#start_date").fill("01/01/2015")
|
||||
self.course_outline.q(css=".action-save").first.click()
|
||||
|
||||
def _auto_auth(self, username, email, staff):
|
||||
"""
|
||||
Logout and login with given credentials.
|
||||
"""
|
||||
AutoAuthPage(self.browser, username=username, email=email,
|
||||
course_id=self.course_id, staff=staff).visit()
|
||||
|
||||
|
||||
def test_courseware(self):
|
||||
"""
|
||||
Test courseware if recent visited subsection become unpublished.
|
||||
"""
|
||||
|
||||
# Visit problem page as a student.
|
||||
self._goto_problem_page()
|
||||
|
||||
# Logout and login as a staff user.
|
||||
LogoutPage(self.browser).visit()
|
||||
self._auto_auth("STAFF_TESTER", "staff101@example.com", True)
|
||||
|
||||
# Visit course outline page in studio.
|
||||
self.course_outline.visit()
|
||||
|
||||
# Set release date for subsection in future.
|
||||
self._change_problem_release_date_in_studio()
|
||||
|
||||
# Wait for 2 seconds to save new date.
|
||||
time.sleep(2)
|
||||
|
||||
# Logout and login as a student.
|
||||
LogoutPage(self.browser).visit()
|
||||
self._auto_auth(self.USERNAME, self.EMAIL, False)
|
||||
|
||||
# Visit courseware as a student.
|
||||
self.courseware_page.visit()
|
||||
|
||||
# Problem name should be "TEST PROBLEM 2".
|
||||
self.assertEqual(self.problem_page.problem_name, 'TEST PROBLEM 2')
|
||||
@@ -45,10 +45,6 @@ class RegistrationTest(UniqueCourseTest):
|
||||
# Visit the main page with the list of courses
|
||||
self.find_courses_page.visit()
|
||||
|
||||
# Expect that the fixture course exists
|
||||
course_ids = self.find_courses_page.course_id_list
|
||||
self.assertIn(self.course_id, course_ids)
|
||||
|
||||
# Go to the course about page and click the register button
|
||||
self.course_about_page.visit()
|
||||
register_page = self.course_about_page.register()
|
||||
|
||||
@@ -159,7 +159,7 @@ def get_current_child(xmodule, min_depth=None):
|
||||
default_child = child_modules[0]
|
||||
else:
|
||||
content_children = [child for child in child_modules if
|
||||
child.has_children_at_depth(min_depth - 1)]
|
||||
child.has_children_at_depth(min_depth - 1) and child.get_display_items()]
|
||||
default_child = content_children[0] if content_children else None
|
||||
|
||||
return default_child
|
||||
@@ -432,8 +432,12 @@ def index(request, course_id, chapter=None, section=None,
|
||||
studio_url = get_studio_url(course, 'course')
|
||||
prev_section = get_current_child(chapter_module)
|
||||
if prev_section is None:
|
||||
# Something went wrong -- perhaps this chapter has no sections visible to the user
|
||||
raise Http404
|
||||
# Something went wrong -- perhaps this chapter has no sections visible to the user.
|
||||
# Clearing out the last-visited state and showing "first-time" view by redirecting
|
||||
# to courseware.
|
||||
course_module.position = None
|
||||
course_module.save()
|
||||
return redirect(reverse('courseware', args=[course.id.to_deprecated_string()]))
|
||||
prev_section_url = reverse('courseware_section', kwargs={
|
||||
'course_id': course_key.to_deprecated_string(),
|
||||
'chapter': chapter_descriptor.url_name,
|
||||
|
||||
Reference in New Issue
Block a user