Esempio n. 1
0
class LibraryContentTestBase(UniqueCourseTest):
    """ Base class for library content block tests """
    USERNAME = "******"
    EMAIL = "*****@*****.**"

    STAFF_USERNAME = "******"
    STAFF_EMAIL = "*****@*****.**"
    shard = 10

    def populate_library_fixture(self, library_fixture):
        """
        To be overwritten by subclassed tests. Used to install a library to
        run tests on.
        """

    def setUp(self):
        """
        Set up library, course and library content XBlock
        """
        super(LibraryContentTestBase, self).setUp()

        self.courseware_page = CoursewarePage(self.browser, self.course_id)

        self.studio_course_outline = StudioCourseOutlinePage(
            self.browser, self.course_info['org'], self.course_info['number'],
            self.course_info['run'])

        self.library_fixture = LibraryFixture(
            'test_org', self.unique_id,
            u'Test Library {}'.format(self.unique_id))
        self.populate_library_fixture(self.library_fixture)

        self.library_fixture.install()
        self.library_info = self.library_fixture.library_info
        self.library_key = self.library_fixture.library_key

        # Install a course with library content xblock
        self.course_fixture = CourseFixture(self.course_info['org'],
                                            self.course_info['number'],
                                            self.course_info['run'],
                                            self.course_info['display_name'])

        library_content_metadata = {
            'source_library_id': six.text_type(self.library_key),
            'mode': 'random',
            'max_count': 1,
        }

        self.lib_block = XBlockFixtureDesc('library_content',
                                           "Library Content",
                                           metadata=library_content_metadata)

        self.course_fixture.add_children(
            XBlockFixtureDesc('chapter', SECTION_NAME).add_children(
                XBlockFixtureDesc('sequential', SUBSECTION_NAME).add_children(
                    XBlockFixtureDesc('vertical', UNIT_NAME).add_children(
                        self.lib_block))))

        self.course_fixture.install()

    def _change_library_content_settings(self, count=1, capa_type=None):
        """
        Performs library block refresh in Studio, configuring it to show {count} children
        """
        unit_page = self._go_to_unit_page(True)
        library_container_block = StudioLibraryContainerXBlockWrapper.from_xblock_wrapper(
            unit_page.xblocks[1])
        library_container_block.edit()
        editor = StudioLibraryContentEditor(self.browser,
                                            library_container_block.locator)
        editor.count = count
        if capa_type is not None:
            editor.capa_type = capa_type
        editor.save()
        self._go_to_unit_page(change_login=False)
        unit_page.wait_for_page()
        unit_page.publish()
        self.assertIn("Published and Live", unit_page.publish_title)

    @property
    def library_xblocks_texts(self):
        """
        Gets texts of all xblocks in library
        """
        return frozenset(child.data for child in self.library_fixture.children)

    def _go_to_unit_page(self, change_login=True):
        """
        Open unit page in Studio
        """
        if change_login:
            LogoutPage(self.browser).visit()
            self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)
        self.studio_course_outline.visit()

        subsection = self.studio_course_outline.section(
            SECTION_NAME).subsection(SUBSECTION_NAME)
        return subsection.expand_subsection().unit(UNIT_NAME).go_to()

    def _goto_library_block_page(self, block_id=None):
        """
        Open library page in LMS
        """
        self.courseware_page.visit()
        paragraphs = self.courseware_page.q(css='.course-content p').results
        if not paragraphs:
            course_home_page = CourseHomePage(self.browser, self.course_id)
            course_home_page.visit()
            course_home_page.outline.go_to_section_by_index(0, 0)
        block_id = block_id if block_id is not None else self.lib_block.locator
        #pylint: disable=attribute-defined-outside-init
        self.library_content_page = LibraryContentXBlockWrapper(
            self.browser, block_id)
        self.library_content_page.wait_for_page()

    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()
class GatingTest(UniqueCourseTest):
    """
    Test gating feature in LMS.
    """
    STAFF_USERNAME = "******"
    STAFF_EMAIL = "*****@*****.**"

    STUDENT_USERNAME = "******"
    STUDENT_EMAIL = "*****@*****.**"

    def setUp(self):
        super(GatingTest, self).setUp()

        self.logout_page = LogoutPage(self.browser)
        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']
        )

        xml = dedent("""
        <problem>
        <p>What is height of eiffel tower without the antenna?.</p>
        <multiplechoiceresponse>
          <choicegroup label="What is height of eiffel tower without the antenna?" type="MultipleChoice">
            <choice correct="false">324 meters<choicehint>Antenna is 24 meters high</choicehint></choice>
            <choice correct="true">300 meters</choice>
            <choice correct="false">224 meters</choice>
            <choice correct="false">400 meters</choice>
          </choicegroup>
        </multiplechoiceresponse>
        </problem>
        """)
        self.problem1 = XBlockFixtureDesc('problem', 'HEIGHT OF EIFFEL TOWER', data=xml)

        # Install a course with sections/problems
        course_fixture = CourseFixture(
            self.course_info['org'],
            self.course_info['number'],
            self.course_info['run'],
            self.course_info['display_name']
        )
        course_fixture.add_advanced_settings({
            "enable_subsection_gating": {"value": "true"}
        })

        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section 1').add_children(
                XBlockFixtureDesc('sequential', 'Test Subsection 1').add_children(
                    self.problem1
                ),
                XBlockFixtureDesc('sequential', 'Test Subsection 2').add_children(
                    XBlockFixtureDesc('problem', 'Test Problem 2')
                )
            )
        ).install()

    def _auto_auth(self, username, email, staff):
        """
        Logout and login with given credentials.
        """
        self.logout_page.visit()
        AutoAuthPage(self.browser, username=username, email=email,
                     course_id=self.course_id, staff=staff).visit()

    def _setup_prereq(self):
        """
        Make the first subsection a prerequisite
        """
        # Login as staff
        self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)

        # Make the first subsection a prerequisite
        self.course_outline.visit()
        self.course_outline.open_subsection_settings_dialog(0)
        self.course_outline.select_advanced_tab(desired_item='gated_content')
        self.course_outline.make_gating_prerequisite()

    def _setup_gated_subsection(self):
        """
        Gate the second subsection on the first subsection
        """
        # Login as staff
        self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)

        # Gate the second subsection based on the score achieved in the first subsection
        self.course_outline.visit()
        self.course_outline.open_subsection_settings_dialog(1)
        self.course_outline.select_advanced_tab(desired_item='gated_content')
        self.course_outline.add_prerequisite_to_subsection("80")

    def _fulfill_prerequisite(self):
        """
        Fulfill the prerequisite needed to see gated content
        """
        problem_page = ProblemPage(self.browser)
        self.assertEqual(problem_page.wait_for_page().problem_name, 'HEIGHT OF EIFFEL TOWER')
        problem_page.click_choice('choice_1')
        problem_page.click_check()

    def test_subsection_gating_in_studio(self):
        """
        Given that I am a staff member
        When I visit the course outline page in studio.
        And open the subsection edit dialog
        Then I can view all settings related to Gating
        And update those settings to gate a subsection
        """
        self._setup_prereq()

        # Assert settings are displayed correctly for a prerequisite subsection
        self.course_outline.visit()
        self.course_outline.open_subsection_settings_dialog(0)
        self.course_outline.select_advanced_tab(desired_item='gated_content')
        self.assertTrue(self.course_outline.gating_prerequisite_checkbox_is_visible())
        self.assertTrue(self.course_outline.gating_prerequisite_checkbox_is_checked())
        self.assertFalse(self.course_outline.gating_prerequisites_dropdown_is_visible())
        self.assertFalse(self.course_outline.gating_prerequisite_min_score_is_visible())

        self._setup_gated_subsection()

        # Assert settings are displayed correctly for a gated subsection
        self.course_outline.visit()
        self.course_outline.open_subsection_settings_dialog(1)
        self.course_outline.select_advanced_tab(desired_item='gated_content')
        self.assertTrue(self.course_outline.gating_prerequisite_checkbox_is_visible())
        self.assertTrue(self.course_outline.gating_prerequisites_dropdown_is_visible())
        self.assertTrue(self.course_outline.gating_prerequisite_min_score_is_visible())

    def test_gated_subsection_in_lms_for_student(self):
        """
        Given that I am a student
        When I visit the LMS Courseware
        Then I cannot see a gated subsection
        When I fulfill the gating Prerequisite
        Then I can see the gated subsection
        """
        self._setup_prereq()
        self._setup_gated_subsection()

        self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False)

        self.courseware_page.visit()
        self.assertEqual(self.courseware_page.num_subsections, 1)

        # Fulfill prerequisite and verify that gated subsection is shown
        self._fulfill_prerequisite()
        self.courseware_page.visit()
        self.assertEqual(self.courseware_page.num_subsections, 2)

    def test_gated_subsection_in_lms_for_staff(self):
        """
        Given that I am a staff member
        When I visit the LMS Courseware
        Then I can see all gated subsections
        Displayed along with notification banners
        Then if I masquerade as a student
        Then I cannot see a gated subsection
        When I fufill the gating prerequisite
        Then I can see the gated subsection (without a banner)
        """
        self._setup_prereq()
        self._setup_gated_subsection()

        # Fulfill prerequisites for specific student
        self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False)
        self.courseware_page.visit()
        self._fulfill_prerequisite()

        self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)

        self.courseware_page.visit()
        staff_page = StaffPage(self.browser, self.course_id)
        self.assertEqual(staff_page.staff_view_mode, 'Staff')
        self.assertEqual(self.courseware_page.num_subsections, 2)

        # Click on gated section and check for banner
        self.courseware_page.q(css='.chapter-content-container a').nth(1).click()
        self.courseware_page.wait_for_page()
        self.assertTrue(self.courseware_page.has_banner())

        self.courseware_page.q(css='.chapter-content-container a').nth(0).click()
        self.courseware_page.wait_for_page()

        staff_page.set_staff_view_mode('Student')

        self.assertEqual(self.courseware_page.num_subsections, 1)
        self.assertFalse(self.courseware_page.has_banner())

        staff_page.set_staff_view_mode_specific_student(self.STUDENT_USERNAME)

        self.assertEqual(self.courseware_page.num_subsections, 2)
        self.courseware_page.q(css='.chapter-content-container a').nth(1).click()
        self.courseware_page.wait_for_page()
        self.assertFalse(self.courseware_page.has_banner())
class VideoLicenseTest(StudioCourseTest):
    """
    Tests for video module-level licensing (that is, setting the license,
    for a specific video module, to All Rights Reserved or Creative Commons)
    """
    def setUp(self):  # pylint: disable=arguments-differ
        super(VideoLicenseTest, self).setUp()

        self.lms_courseware = CoursewarePage(
            self.browser,
            self.course_id,
        )
        self.studio_course_outline = CourseOutlinePage(
            self.browser,
            self.course_info['org'],
            self.course_info['number'],
            self.course_info['run']
        )

    # used by StudioCourseTest.setUp()
    def populate_course_fixture(self, course_fixture):
        """
        Create a course with a single chapter.
        That chapter has a single section.
        That section has a single vertical.
        That vertical has a single video element.
        """
        video_block = XBlockFixtureDesc('video', "Test Video")
        vertical = XBlockFixtureDesc('vertical', "Test Vertical")
        vertical.add_children(video_block)
        sequential = XBlockFixtureDesc('sequential', "Test Section")
        sequential.add_children(vertical)
        chapter = XBlockFixtureDesc('chapter', "Test Chapter")
        chapter.add_children(sequential)
        self.course_fixture.add_children(chapter)

    def test_empty_license(self):
        """
        When I visit the LMS courseware,
        I can see that the video is present
        but it has no license displayed by default.
        """
        self.lms_courseware.visit()
        video = self.lms_courseware.q(css=".vert .xblock .video")
        self.assertTrue(video.is_present())
        video_license = self.lms_courseware.q(css=".vert .xblock.xmodule_VideoModule .xblock-license")
        self.assertFalse(video_license.is_present())

    def test_arr_license(self):
        """
        When I edit a video element in Studio,
        I can set an "All Rights Reserved" license on that video element.
        When I visit the LMS courseware,
        I can see that the video is present
        and that it has "All Rights Reserved" displayed for the license.
        """
        self.studio_course_outline.visit()
        subsection = self.studio_course_outline.section_at(0).subsection_at(0)
        subsection.expand_subsection()
        unit = subsection.unit_at(0)
        container_page = unit.go_to()
        container_page.edit()
        video = [xb for xb in container_page.xblocks if xb.name == "Test Video"][0]
        video.open_advanced_tab()
        video.set_license('all-rights-reserved')
        video.save_settings()
        container_page.publish_action.click()

        self.lms_courseware.visit()
        video = self.lms_courseware.q(css=".vert .xblock .video")
        self.assertTrue(video.is_present())
        video_license_css = ".vert .xblock.xmodule_VideoModule .xblock-license"
        self.lms_courseware.wait_for_element_presence(
            video_license_css, "Video module license block is present"
        )
        video_license = self.lms_courseware.q(css=video_license_css)
        self.assertEqual(video_license.text[0], "© All Rights Reserved")

    def test_cc_license(self):
        """
        When I edit a video element in Studio,
        I can set a "Creative Commons" license on that video element.
        When I visit the LMS courseware,
        I can see that the video is present
        and that it has "Some Rights Reserved" displayed for the license.
        """
        self.studio_course_outline.visit()
        subsection = self.studio_course_outline.section_at(0).subsection_at(0)
        subsection.expand_subsection()
        unit = subsection.unit_at(0)
        container_page = unit.go_to()
        container_page.edit()
        video = [xb for xb in container_page.xblocks if xb.name == "Test Video"][0]
        video.open_advanced_tab()
        video.set_license('creative-commons')
        video.save_settings()
        container_page.publish_action.click()

        self.lms_courseware.visit()
        video = self.lms_courseware.q(css=".vert .xblock .video")
        self.assertTrue(video.is_present())
        video_license_css = ".vert .xblock.xmodule_VideoModule .xblock-license"
        self.lms_courseware.wait_for_element_presence(
            video_license_css, "Video module license block is present"
        )
        video_license = self.lms_courseware.q(css=video_license_css)
        self.assertIn("Some Rights Reserved", video_license.text[0])
Esempio n. 4
0
class LibraryContentTestBase(UniqueCourseTest):
    """ Base class for library content block tests """
    USERNAME = "******"
    EMAIL = "*****@*****.**"

    STAFF_USERNAME = "******"
    STAFF_EMAIL = "*****@*****.**"

    def populate_library_fixture(self, library_fixture):
        """
        To be overwritten by subclassed tests. Used to install a library to
        run tests on.
        """

    def setUp(self):
        """
        Set up library, course and library content XBlock
        """
        super(LibraryContentTestBase, self).setUp()

        self.courseware_page = CoursewarePage(self.browser, self.course_id)

        self.studio_course_outline = StudioCourseOutlinePage(
            self.browser,
            self.course_info['org'],
            self.course_info['number'],
            self.course_info['run']
        )

        self.library_fixture = LibraryFixture('test_org', self.unique_id, 'Test Library {}'.format(self.unique_id))
        self.populate_library_fixture(self.library_fixture)

        self.library_fixture.install()
        self.library_info = self.library_fixture.library_info
        self.library_key = self.library_fixture.library_key

        # Install a course with library content xblock
        self.course_fixture = CourseFixture(
            self.course_info['org'], self.course_info['number'],
            self.course_info['run'], self.course_info['display_name']
        )

        library_content_metadata = {
            'source_library_id': unicode(self.library_key),
            'mode': 'random',
            'max_count': 1,
        }

        self.lib_block = XBlockFixtureDesc('library_content', "Library Content", metadata=library_content_metadata)

        self.course_fixture.add_children(
            XBlockFixtureDesc('chapter', SECTION_NAME).add_children(
                XBlockFixtureDesc('sequential', SUBSECTION_NAME).add_children(
                    XBlockFixtureDesc('vertical', UNIT_NAME).add_children(
                        self.lib_block
                    )
                )
            )
        )

        self.course_fixture.install()

    def _change_library_content_settings(self, count=1, capa_type=None):
        """
        Performs library block refresh in Studio, configuring it to show {count} children
        """
        unit_page = self._go_to_unit_page(True)
        library_container_block = StudioLibraryContainerXBlockWrapper.from_xblock_wrapper(unit_page.xblocks[1])
        library_container_block.edit()
        editor = StudioLibraryContentEditor(self.browser, library_container_block.locator)
        editor.count = count
        if capa_type is not None:
            editor.capa_type = capa_type
        editor.save()
        self._go_to_unit_page(change_login=False)
        unit_page.wait_for_page()
        unit_page.publish_action.click()
        unit_page.wait_for_ajax()
        self.assertIn("Published and Live", unit_page.publish_title)

    @property
    def library_xblocks_texts(self):
        """
        Gets texts of all xblocks in library
        """
        return frozenset(child.data for child in self.library_fixture.children)

    def _go_to_unit_page(self, change_login=True):
        """
        Open unit page in Studio
        """
        if change_login:
            LogoutPage(self.browser).visit()
            self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)
        self.studio_course_outline.visit()

        subsection = self.studio_course_outline.section(SECTION_NAME).subsection(SUBSECTION_NAME)
        return subsection.expand_subsection().unit(UNIT_NAME).go_to()

    def _goto_library_block_page(self, block_id=None):
        """
        Open library page in LMS
        """
        self.courseware_page.visit()
        paragraphs = self.courseware_page.q(css='.course-content p').results
        if not paragraphs:
            course_home_page = CourseHomePage(self.browser, self.course_id)
            course_home_page.visit()
            course_home_page.outline.go_to_section_by_index(0, 0)
        block_id = block_id if block_id is not None else self.lib_block.locator
        #pylint: disable=attribute-defined-outside-init
        self.library_content_page = LibraryContentXBlockWrapper(self.browser, block_id)
        self.library_content_page.wait_for_page()

    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()
class VideoLicenseTest(StudioCourseTest):
    """
    Tests for video module-level licensing (that is, setting the license,
    for a specific video module, to All Rights Reserved or Creative Commons)
    """
    def setUp(self):  # pylint: disable=arguments-differ
        super(VideoLicenseTest, self).setUp()

        self.lms_courseware = CoursewarePage(
            self.browser,
            self.course_id,
        )
        self.studio_course_outline = CourseOutlinePage(
            self.browser,
            self.course_info['org'],
            self.course_info['number'],
            self.course_info['run']
        )

    # used by StudioCourseTest.setUp()
    def populate_course_fixture(self, course_fixture):
        """
        Create a course with a single chapter.
        That chapter has a single section.
        That section has a single vertical.
        That vertical has a single video element.
        """
        video_block = XBlockFixtureDesc('video', "Test Video")
        vertical = XBlockFixtureDesc('vertical', "Test Vertical")
        vertical.add_children(video_block)
        sequential = XBlockFixtureDesc('sequential', "Test Section")
        sequential.add_children(vertical)
        chapter = XBlockFixtureDesc('chapter', "Test Chapter")
        chapter.add_children(sequential)
        self.course_fixture.add_children(chapter)

    def test_empty_license(self):
        """
        When I visit the LMS courseware,
        I can see that the video is present
        but it has no license displayed by default.
        """
        self.lms_courseware.visit()
        video = self.lms_courseware.q(css=".vert .xblock .video")
        self.assertTrue(video.is_present())
        video_license = self.lms_courseware.q(css=".vert .xblock.xmodule_VideoModule .xblock-license")
        self.assertFalse(video_license.is_present())

    def test_arr_license(self):
        """
        When I edit a video element in Studio,
        I can set an "All Rights Reserved" license on that video element.
        When I visit the LMS courseware,
        I can see that the video is present
        and that it has "All Rights Reserved" displayed for the license.
        """
        self.studio_course_outline.visit()
        subsection = self.studio_course_outline.section_at(0).subsection_at(0)
        subsection.expand_subsection()
        unit = subsection.unit_at(0)
        container_page = unit.go_to()
        container_page.edit()
        video = [xb for xb in container_page.xblocks if xb.name == "Test Video"][0]
        video.open_advanced_tab()
        video.set_license('all-rights-reserved')
        video.save_settings()
        container_page.publish_action.click()

        self.lms_courseware.visit()
        video = self.lms_courseware.q(css=".vert .xblock .video")
        self.assertTrue(video.is_present())
        video_license_css = ".vert .xblock.xmodule_VideoModule .xblock-license"
        self.lms_courseware.wait_for_element_presence(
            video_license_css, "Video module license block is present"
        )
        video_license = self.lms_courseware.q(css=video_license_css)
        self.assertEqual(video_license.text[0], "© All Rights Reserved")

    def test_cc_license(self):
        """
        When I edit a video element in Studio,
        I can set a "Creative Commons" license on that video element.
        When I visit the LMS courseware,
        I can see that the video is present
        and that it has "Some Rights Reserved" displayed for the license.
        """
        self.studio_course_outline.visit()
        subsection = self.studio_course_outline.section_at(0).subsection_at(0)
        subsection.expand_subsection()
        unit = subsection.unit_at(0)
        container_page = unit.go_to()
        container_page.edit()
        video = [xb for xb in container_page.xblocks if xb.name == "Test Video"][0]
        video.open_advanced_tab()
        video.set_license('creative-commons')
        video.save_settings()
        container_page.publish_action.click()

        self.lms_courseware.visit()
        video = self.lms_courseware.q(css=".vert .xblock .video")
        self.assertTrue(video.is_present())
        video_license_css = ".vert .xblock.xmodule_VideoModule .xblock-license"
        self.lms_courseware.wait_for_element_presence(
            video_license_css, "Video module license block is present"
        )
        video_license = self.lms_courseware.q(css=video_license_css)
        self.assertIn("Some Rights Reserved", video_license.text[0])
class CertificateProgressPageTest(UniqueCourseTest):
    """
    Tests for verifying Certificate info on Progress tab of course page.
    """
    def setUp(self):
        super(CertificateProgressPageTest, self).setUp()

        # set same course number as we have in fixture json
        self.course_info['number'] = "3355358979513794782079645765720179311111"

        test_certificate_config = {
            'id': 1,
            'name': 'Certificate name',
            'description': 'Certificate description',
            'course_title': 'Course title override',
            'signatories': [],
            'version': 1,
            'is_active': True
        }
        course_settings = {'certificates': test_certificate_config}

        self.course_fixture = CourseFixture(self.course_info["org"],
                                            self.course_info["number"],
                                            self.course_info["run"],
                                            self.course_info["display_name"],
                                            settings=course_settings)

        self.course_fixture.add_advanced_settings({
            "cert_html_view_enabled": {
                "value": "true"
            },
            "certificates_show_before_end": {
                "value": "true"
            }
        })

        self.course_fixture.add_update(
            CourseUpdateDesc(date='January 29, 2014',
                             content='Test course update1'))

        self.course_fixture.add_children(
            XBlockFixtureDesc('static_tab', 'Test Static Tab'),
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc(
                    'sequential', 'Test Subsection',
                    grader_type='Final Exam').add_children(
                        XBlockFixtureDesc(
                            'problem',
                            'Test Problem 1',
                            data=load_data_str('multiple_choice.xml')),
                        XBlockFixtureDesc('html', 'Test HTML'),
                    )),
            XBlockFixtureDesc('chapter', 'Test Section 2').add_children(
                XBlockFixtureDesc(
                    'sequential',
                    'Test Subsection 2',
                    grader_type='Midterm Exam').add_children(
                        XBlockFixtureDesc(
                            'problem',
                            'Test Problem 2',
                            data=load_data_str('formula_problem.xml')), )))

        self.course_fixture.install()
        self.user_id = "99"  # we have created a user with this id in fixture
        self.cert_fixture = CertificateConfigFixture(self.course_id,
                                                     test_certificate_config)

        self.progress_page = ProgressPage(self.browser, self.course_id)
        self.courseware_page = CoursewarePage(self.browser, self.course_id)
        self.course_home_page = CourseHomePage(self.browser, self.course_id)
        self.tab_nav = TabNavPage(self.browser)

    def log_in_as_unique_user(self):
        """
        Log in as a valid lms user.
        """
        AutoAuthPage(self.browser,
                     username="******",
                     email="*****@*****.**",
                     password="******",
                     course_id=self.course_id).visit()

    def test_progress_page_has_view_certificate_button(self):
        """
        Scenario: View Certificate option should be present on Course Progress menu if the user is
        awarded a certificate.
        And there should be no padding around the box containing certificate info. (See SOL-1196 for details on this)

        As a Student
        Given there is a course with certificate configuration
        And I have passed the course and certificate is generated
        When I go on the Progress tab for the course
        Then I should see a 'View Certificate' button
        And their should be no padding around Certificate info box.
        """
        self.cert_fixture.install()
        self.log_in_as_unique_user()

        self.complete_course_problems()

        self.course_home_page.visit()
        self.tab_nav.go_to_tab('Progress')

        self.assertTrue(
            self.progress_page.q(css='.auto-cert-message').first.visible)

        actual_padding = get_element_padding(self.progress_page,
                                             '.wrapper-msg.wrapper-auto-cert')
        actual_padding = [
            int(padding) for padding in actual_padding.itervalues()
        ]
        expected_padding = [0, 0, 0, 0]

        # Verify that their is no padding around the box containing certificate info.
        self.assertEqual(actual_padding, expected_padding)

    def complete_course_problems(self):
        """
        Complete Course Problems.

        Problems were added in the setUp
        """
        self.course_home_page.visit()

        # Navigate to Test Subsection in Test Section Section
        self.course_home_page.outline.go_to_section('Test Section',
                                                    'Test Subsection')

        # Navigate to Test Problem 1
        self.courseware_page.nav.go_to_vertical('Test Problem 1')

        # Select correct value for from select menu
        self.courseware_page.q(
            css='select option[value="{}"]'.format('blue')).first.click()

        # Select correct radio button for the answer
        self.courseware_page.q(
            css='fieldset div.field:nth-child(4) input').nth(0).click()

        # Select correct radio buttons for the answer
        self.courseware_page.q(
            css='fieldset div.field:nth-child(2) input').nth(1).click()
        self.courseware_page.q(
            css='fieldset div.field:nth-child(4) input').nth(1).click()

        # Submit the answer
        self.courseware_page.q(css='button.submit').click()
        self.courseware_page.wait_for_ajax()

        # Navigate to the 'Test Subsection 2' of 'Test Section 2'
        self.course_home_page.visit()
        self.course_home_page.outline.go_to_section('Test Section 2',
                                                    'Test Subsection 2')

        # Navigate to Test Problem 2
        self.courseware_page.nav.go_to_vertical('Test Problem 2')

        # Fill in the answer of the problem
        self.courseware_page.q(
            css='input[id^=input_][id$=_2_1]').fill('A*x^2 + sqrt(y)')

        # Submit the answer
        self.courseware_page.q(css='button.submit').click()
        self.courseware_page.wait_for_ajax()
Esempio n. 7
0
class GatingTest(UniqueCourseTest):
    """
    Test gating feature in LMS.
    """
    STAFF_USERNAME = "******"
    STAFF_EMAIL = "*****@*****.**"

    STUDENT_USERNAME = "******"
    STUDENT_EMAIL = "*****@*****.**"

    def setUp(self):
        super(GatingTest, self).setUp()

        self.logout_page = LogoutPage(self.browser)
        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'])

        xml = dedent("""
        <problem>
        <p>What is height of eiffel tower without the antenna?.</p>
        <multiplechoiceresponse>
          <choicegroup label="What is height of eiffel tower without the antenna?" type="MultipleChoice">
            <choice correct="false">324 meters<choicehint>Antenna is 24 meters high</choicehint></choice>
            <choice correct="true">300 meters</choice>
            <choice correct="false">224 meters</choice>
            <choice correct="false">400 meters</choice>
          </choicegroup>
        </multiplechoiceresponse>
        </problem>
        """)
        self.problem1 = XBlockFixtureDesc('problem',
                                          'HEIGHT OF EIFFEL TOWER',
                                          data=xml)

        # Install a course with sections/problems
        course_fixture = CourseFixture(self.course_info['org'],
                                       self.course_info['number'],
                                       self.course_info['run'],
                                       self.course_info['display_name'])
        course_fixture.add_advanced_settings(
            {"enable_subsection_gating": {
                "value": "true"
            }})

        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section 1').add_children(
                XBlockFixtureDesc('sequential',
                                  'Test Subsection 1').add_children(
                                      self.problem1),
                XBlockFixtureDesc('sequential',
                                  'Test Subsection 2').add_children(
                                      XBlockFixtureDesc(
                                          'problem',
                                          'Test Problem 2')))).install()

    def _auto_auth(self, username, email, staff):
        """
        Logout and login with given credentials.
        """
        self.logout_page.visit()
        AutoAuthPage(self.browser,
                     username=username,
                     email=email,
                     course_id=self.course_id,
                     staff=staff).visit()

    def _setup_prereq(self):
        """
        Make the first subsection a prerequisite
        """
        # Login as staff
        self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)

        # Make the first subsection a prerequisite
        self.course_outline.visit()
        self.course_outline.open_subsection_settings_dialog(0)
        self.course_outline.select_advanced_tab(desired_item='gated_content')
        self.course_outline.make_gating_prerequisite()

    def _setup_gated_subsection(self):
        """
        Gate the second subsection on the first subsection
        """
        # Login as staff
        self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)

        # Gate the second subsection based on the score achieved in the first subsection
        self.course_outline.visit()
        self.course_outline.open_subsection_settings_dialog(1)
        self.course_outline.select_advanced_tab(desired_item='gated_content')
        self.course_outline.add_prerequisite_to_subsection("80")

    def _fulfill_prerequisite(self):
        """
        Fulfill the prerequisite needed to see gated content
        """
        problem_page = ProblemPage(self.browser)
        self.assertEqual(problem_page.wait_for_page().problem_name,
                         'HEIGHT OF EIFFEL TOWER')
        problem_page.click_choice('choice_1')
        problem_page.click_submit()

    def test_subsection_gating_in_studio(self):
        """
        Given that I am a staff member
        When I visit the course outline page in studio.
        And open the subsection edit dialog
        Then I can view all settings related to Gating
        And update those settings to gate a subsection
        """
        self._setup_prereq()

        # Assert settings are displayed correctly for a prerequisite subsection
        self.course_outline.visit()
        self.course_outline.open_subsection_settings_dialog(0)
        self.course_outline.select_advanced_tab(desired_item='gated_content')
        self.assertTrue(
            self.course_outline.gating_prerequisite_checkbox_is_visible())
        self.assertTrue(
            self.course_outline.gating_prerequisite_checkbox_is_checked())
        self.assertFalse(
            self.course_outline.gating_prerequisites_dropdown_is_visible())
        self.assertFalse(
            self.course_outline.gating_prerequisite_min_score_is_visible())

        self._setup_gated_subsection()

        # Assert settings are displayed correctly for a gated subsection
        self.course_outline.visit()
        self.course_outline.open_subsection_settings_dialog(1)
        self.course_outline.select_advanced_tab(desired_item='gated_content')
        self.assertTrue(
            self.course_outline.gating_prerequisite_checkbox_is_visible())
        self.assertTrue(
            self.course_outline.gating_prerequisites_dropdown_is_visible())
        self.assertTrue(
            self.course_outline.gating_prerequisite_min_score_is_visible())

    def test_gated_subsection_in_lms_for_student(self):
        """
        Given that I am a student
        When I visit the LMS Courseware
        Then I cannot see a gated subsection
        When I fulfill the gating Prerequisite
        Then I can see the gated subsection
        """
        self._setup_prereq()
        self._setup_gated_subsection()

        self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False)

        self.courseware_page.visit()
        self.assertEqual(self.courseware_page.num_subsections, 1)

        # Fulfill prerequisite and verify that gated subsection is shown
        self._fulfill_prerequisite()
        self.courseware_page.visit()
        self.assertEqual(self.courseware_page.num_subsections, 2)

    def test_gated_subsection_in_lms_for_staff(self):
        """
        Given that I am a staff member
        When I visit the LMS Courseware
        Then I can see all gated subsections
        Displayed along with notification banners
        Then if I masquerade as a student
        Then I cannot see a gated subsection
        When I fufill the gating prerequisite
        Then I can see the gated subsection (without a banner)
        """
        self._setup_prereq()
        self._setup_gated_subsection()

        # Fulfill prerequisites for specific student
        self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False)
        self.courseware_page.visit()
        self._fulfill_prerequisite()

        self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)

        self.courseware_page.visit()
        staff_page = StaffPage(self.browser, self.course_id)
        self.assertEqual(staff_page.staff_view_mode, 'Staff')
        self.assertEqual(self.courseware_page.num_subsections, 2)

        # Click on gated section and check for banner
        self.courseware_page.q(
            css='.chapter-content-container a').nth(1).click()
        self.courseware_page.wait_for_page()
        self.assertTrue(self.courseware_page.has_banner())

        self.courseware_page.q(
            css='.chapter-content-container a').nth(0).click()
        self.courseware_page.wait_for_page()

        staff_page.set_staff_view_mode('Student')

        self.assertEqual(self.courseware_page.num_subsections, 1)
        self.assertFalse(self.courseware_page.has_banner())

        staff_page.set_staff_view_mode_specific_student(self.STUDENT_USERNAME)

        self.assertEqual(self.courseware_page.num_subsections, 2)
        self.courseware_page.q(
            css='.chapter-content-container a').nth(1).click()
        self.courseware_page.wait_for_page()
        self.assertFalse(self.courseware_page.has_banner())
class CertificateProgressPageTest(UniqueCourseTest):
    """
    Tests for verifying Certificate info on Progress tab of course page.
    """

    def setUp(self):
        super(CertificateProgressPageTest, self).setUp()

        # set same course number as we have in fixture json
        self.course_info['number'] = "3355358979513794782079645765720179311111"

        test_certificate_config = {
            'id': 1,
            'name': 'Certificate name',
            'description': 'Certificate description',
            'course_title': 'Course title override',
            'signatories': [],
            'version': 1,
            'is_active': True
        }
        course_settings = {'certificates': test_certificate_config}

        self.course_fixture = CourseFixture(
            self.course_info["org"],
            self.course_info["number"],
            self.course_info["run"],
            self.course_info["display_name"],
            settings=course_settings
        )

        self.course_fixture.add_advanced_settings({
            "cert_html_view_enabled": {"value": "true"},
            "certificates_show_before_end": {"value": "true"}
        })

        self.course_fixture.add_update(
            CourseUpdateDesc(date='January 29, 2014', content='Test course update1')
        )

        self.course_fixture.add_children(
            XBlockFixtureDesc('static_tab', 'Test Static Tab'),
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential', 'Test Subsection', grader_type='Final Exam').add_children(
                    XBlockFixtureDesc('problem', 'Test Problem 1', data=load_data_str('multiple_choice.xml')),
                    XBlockFixtureDesc('html', 'Test HTML'),
                )
            ),
            XBlockFixtureDesc('chapter', 'Test Section 2').add_children(
                XBlockFixtureDesc('sequential', 'Test Subsection 2', grader_type='Midterm Exam').add_children(
                    XBlockFixtureDesc('problem', 'Test Problem 2', data=load_data_str('formula_problem.xml')),
                )
            )
        )

        self.course_fixture.install()
        self.user_id = "99"  # we have created a user with this id in fixture
        self.cert_fixture = CertificateConfigFixture(self.course_id, test_certificate_config)

        self.progress_page = ProgressPage(self.browser, self.course_id)
        self.courseware_page = CoursewarePage(self.browser, self.course_id)
        self.course_home_page = CourseHomePage(self.browser, self.course_id)
        self.tab_nav = TabNavPage(self.browser)

    def log_in_as_unique_user(self):
        """
        Log in as a valid lms user.
        """
        AutoAuthPage(
            self.browser,
            username="******",
            email="*****@*****.**",
            password="******",
            course_id=self.course_id
        ).visit()

    def test_progress_page_has_view_certificate_button(self):
        """
        Scenario: View Certificate option should be present on Course Progress menu if the user is
        awarded a certificate.
        And there should be no padding around the box containing certificate info. (See SOL-1196 for details on this)

        As a Student
        Given there is a course with certificate configuration
        And I have passed the course and certificate is generated
        When I go on the Progress tab for the course
        Then I should see a 'View Certificate' button
        And their should be no padding around Certificate info box.
        """
        self.cert_fixture.install()
        self.log_in_as_unique_user()

        self.complete_course_problems()

        self.course_home_page.visit()
        self.tab_nav.go_to_tab('Progress')

        self.assertTrue(self.progress_page.q(css='.auto-cert-message').first.visible)

        actual_padding = get_element_padding(self.progress_page, '.wrapper-msg.wrapper-auto-cert')
        actual_padding = [int(padding) for padding in actual_padding.itervalues()]
        expected_padding = [0, 0, 0, 0]

        # Verify that their is no padding around the box containing certificate info.
        self.assertEqual(actual_padding, expected_padding)

    def complete_course_problems(self):
        """
        Complete Course Problems.

        Problems were added in the setUp
        """
        self.course_home_page.visit()

        # Navigate to Test Subsection in Test Section Section
        self.course_home_page.outline.go_to_section('Test Section', 'Test Subsection')

        # Navigate to Test Problem 1
        self.courseware_page.nav.go_to_vertical('Test Problem 1')

        # Select correct value for from select menu
        self.courseware_page.q(css='select option[value="{}"]'.format('blue')).first.click()

        # Select correct radio button for the answer
        self.courseware_page.q(css='fieldset div.field:nth-child(4) input').nth(0).click()

        # Select correct radio buttons for the answer
        self.courseware_page.q(css='fieldset div.field:nth-child(2) input').nth(1).click()
        self.courseware_page.q(css='fieldset div.field:nth-child(4) input').nth(1).click()

        # Submit the answer
        self.courseware_page.q(css='button.submit').click()
        self.courseware_page.wait_for_ajax()

        # Navigate to the 'Test Subsection 2' of 'Test Section 2'
        self.course_home_page.visit()
        self.course_home_page.outline.go_to_section('Test Section 2', 'Test Subsection 2')

        # Navigate to Test Problem 2
        self.courseware_page.nav.go_to_vertical('Test Problem 2')

        # Fill in the answer of the problem
        self.courseware_page.q(css='input[id^=input_][id$=_2_1]').fill('A*x^2 + sqrt(y)')

        # Submit the answer
        self.courseware_page.q(css='button.submit').click()
        self.courseware_page.wait_for_ajax()