def test_not_from_cron_and_not_admin(self):
     config.set_report_allowed(True)
     actions.logout()
     response = self.get(usage_reporting.StartReportingJobs.URL,
                         expect_errors=True)
     self.assertEquals(403, response.status_int)
     self.assertEquals('Forbidden.', response.body)
Esempio n. 2
0
    def test_lesson_access_title_only(self):
        actions.logout()

        self.unit.availability = courses.AVAILABILITY_AVAILABLE
        self.lesson.availability = courses.AVAILABILITY_UNAVAILABLE
        self.lesson.shown_when_unavailable = True
        self.course.save()
        expected_lesson = {'title': self.lesson.title, 'body': None}

        # Access single lesson
        response = self.get_response(
            '{course(id: "%s") {unit(id: "%s") {'
              'lesson(id: "%s") {title body}}}}' % (
                self.course_id, self.unit_id, self.lesson_id))
        _lesson = response['data']['course']['unit']['lesson']
        self.assertEquals(expected_lesson, _lesson)

        # Access lesson list
        response = self.get_response(
            '{course(id: "%s") {unit(id: "%s") {allLessons {edges {node {'
            '  ... on Lesson{title body}}}}}}}' % (
                self.course_id, self.unit_id))
        edges = response['data']['course']['unit']['allLessons']['edges']
        self.assertEquals(1, len(edges))
        self.assertEquals(expected_lesson, edges[0]['node'])
    def setUp(self):
        super(RolesTest, self).setUp()

        actions.login(COURSE_ADMIN_EMAIL, is_admin=True)
        payload_dict = {
            'name': COURSE_NAME,
            'title': 'Roles Test',
            'admin_email': COURSE_ADMIN_EMAIL}
        request = {
            'payload': transforms.dumps(payload_dict),
            'xsrf_token': crypto.XsrfTokenManager.create_xsrf_token(
                'add-course-put')}
        response = self.testapp.put('/rest/courses/item?%s' % urllib.urlencode(
            {'request': transforms.dumps(request)}), {})
        self.assertEquals(response.status_int, 200)
        sites.setup_courses('course:/%s::ns_%s, course:/:/' % (
                COURSE_NAME, COURSE_NAME))
        actions.logout()

        config.Registry.test_overrides[roles.GCB_ADMIN_LIST.name] = (
            '[%s]' % SITE_ADMIN_EMAIL)

        # pylint: disable-msg=protected-access
        self.old_registered_permission = roles.Roles._REGISTERED_PERMISSIONS
        roles.Roles._REGISTERED_PERMISSIONS = {}

        config.Registry.test_overrides[models.CAN_USE_MEMCACHE.name] = True
Esempio n. 4
0
    def setUp(self):
        super(StudentLabelsTest, self).setUp()
        actions.simple_add_course(COURSE_NAME, ADMIN_EMAIL, COURSE_TITLE)

        with common_utils.Namespace(NAMESPACE):
            self.foo_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Foo',
                       'descripton': 'foo',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.bar_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Bar',
                       'descripton': 'bar',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.baz_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Baz',
                       'descripton': 'baz',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.quux_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Quux',
                       'descripton': 'quux',
                       'type': models.LabelDTO.LABEL_TYPE_GENERAL}))

        actions.login(REGISTERED_STUDENT_EMAIL)
        actions.register(self, REGISTERED_STUDENT_NAME, COURSE_NAME)
        actions.logout()
 def test_not_logged_in(self):
     actions.logout()
     response = self.get(UNIT_PROGRESS_URL +
                         '?key=%s' % self._unit_one.unit_id)
     self._expect_response(
         response, 403,
         'Bad XSRF token. Please reload the page and try again')
Esempio n. 6
0
    def test_enrollment(self):
        actions.logout()

        response = self.get_response(
            '{course(id: "%s") {enrollment {email enrolled}}}' % (
                self.course_id))
        enrollment = response['data']['course']['enrollment']
        self.assertEquals({'enrolled': False, 'email': None}, enrollment)

        actions.login(STUDENT_EMAIL)

        response = self.get_response(
            '{course(id: "%s") {enrollment {email enrolled}}}' % (
                self.course_id))
        enrollment = response['data']['course']['enrollment']
        self.assertEquals({'enrolled': False, 'email': None}, enrollment)

        actions.register(self, STUDENT_NAME)

        response = self.get_response(
            '{course (id: "%s") { enrollment { email enrolled}}}' % (
                self.course_id))
        enrollment = response['data']['course']['enrollment']
        self.assertEquals(
            {'enrolled': True, 'email': STUDENT_EMAIL}, enrollment)
Esempio n. 7
0
    def test_guide_enabled_course(self):
        with actions.OverriddenEnvironment(self.GUIDE_ENABLED_COURSE):
            actions.logout()
            self.assert_guide_accesssible("Alpha")
            self.assert_guide_accesssible("Bravo")
            self.assert_guide_not_accesssible("Charlie", is_guides_accessible=True)
            self.assert_guide_not_accesssible("Delta", is_guides_accessible=True)

            actions.login("*****@*****.**")
            self.assert_guide_accesssible("Alpha")
            self.assert_guide_accesssible("Bravo")
            self.assert_guide_not_accesssible("Charlie", is_guides_accessible=True)
            self.assert_guide_not_accesssible("Delta", is_guides_accessible=True)

            self.register("Charlie")
            self.assert_guide_accesssible("Alpha")
            self.assert_guide_accesssible("Bravo")
            self.assert_guide_accesssible("Charlie")
            self.assert_guide_not_accesssible("Delta", is_guides_accessible=True)

            actions.login("*****@*****.**", is_admin=True)
            for name in ["Alpha", "Bravo", "Charlie", "Delta"]:
                self.assert_guide_accesssible(name)

            # check course labels as admin sees them
            response = self.get("/modules/guides")
            self.assertEquals(200, response.status_int)
            self.assertIn('category="Power Searching with Google [Alpha]', response.body)
            self.assertIn('category="Power Searching with Google [Bravo]', response.body)
            self.assertIn('category="Power Searching with Google [Charlie] ' "(Registration required)", response.body)
            self.assertIn('category="Power Searching with Google [Delta] (Private)', response.body)
    def test_not_enough_assignments_to_allocate(self):
        """Test for the case when there are too few assignments in the pool."""

        email = '*****@*****.**'
        name = 'Student 1'
        submission = transforms.dumps([
            {'index': 0, 'type': 'regex', 'value': 'S1-1', 'correct': True},
            {'index': 1, 'type': 'choices', 'value': 3, 'correct': False},
            {'index': 2, 'type': 'regex', 'value': 'is-S1', 'correct': True},
        ])
        payload = {
            'answers': submission, 'assessment_type': LEGACY_REVIEW_UNIT_ID}

        actions.login(email)
        actions.register(self, name)
        response = actions.submit_assessment(
            self, LEGACY_REVIEW_UNIT_ID, payload)

        # The student goes to the review dashboard and requests an assignment
        # to review -- but there is nothing to review.
        response = actions.request_new_review(
            self, LEGACY_REVIEW_UNIT_ID, expected_status_code=200)
        actions.assert_does_not_contain('Assignment to review', response.body)
        actions.assert_contains(
            'Sorry, there are no new submissions ', response.body)
        actions.assert_contains('disabled="true"', response.body)

        actions.logout()
    def test_student_cannot_see_reviews_prematurely(self):
        """Test that students cannot see others' reviews prematurely."""

        email = '*****@*****.**'
        name = 'Student 1'
        submission = transforms.dumps([
            {'index': 0, 'type': 'regex', 'value': 'S1-1', 'correct': True},
            {'index': 1, 'type': 'choices', 'value': 3, 'correct': False},
            {'index': 2, 'type': 'regex', 'value': 'is-S1', 'correct': True},
        ])
        payload = {
            'answers': submission, 'assessment_type': LEGACY_REVIEW_UNIT_ID}

        actions.login(email)
        actions.register(self, name)
        response = actions.submit_assessment(
            self, LEGACY_REVIEW_UNIT_ID, payload)

        # Student 1 cannot see the reviews for his assignment yet, because he
        # has not submitted the two required reviews.
        response = self.get('assessment?name=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_equals(response.status_int, 200)
        actions.assert_contains('Due date for this assignment', response.body)
        actions.assert_contains(
            'After you have completed the required number of peer reviews',
            response.body)

        actions.logout()
Esempio n. 10
0
    def setUp(self):
        super(StudentTracksTest, self).setUp()

        # Add a course that will show up.
        actions.simple_add_course(COURSE_NAME, ADMIN_EMAIL, COURSE_TITLE)

        # Add labels
        with common_utils.Namespace(NAMESPACE):
            self.foo_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Foo',
                       'descripton': 'foo',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.bar_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Bar',
                       'descripton': 'bar',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.baz_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Baz',
                       'descripton': 'baz',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.quux_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Quux',
                       'descripton': 'quux',
                       'type': models.LabelDTO.LABEL_TYPE_GENERAL}))

        # Register a student for that course.
        actions.login(REGISTERED_STUDENT_EMAIL)
        actions.register(self, REGISTERED_STUDENT_NAME, COURSE_NAME)
        actions.logout()

        # Add some units to the course.
        self._course = courses.Course(
            None, app_context=sites.get_all_courses()[0])
        self._unit_no_labels = self._course.add_unit()
        self._unit_no_labels.title = 'Unit No Labels'
        self._unit_no_labels.availability = courses.AVAILABILITY_AVAILABLE
        self._course.add_lesson(self._unit_no_labels)
        self._unit_labels_foo = self._course.add_unit()
        self._unit_labels_foo.title = 'Unit Labels: Foo'
        self._unit_labels_foo.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_foo.labels = str(self.foo_id)
        self._course.add_lesson(self._unit_labels_foo)
        self._unit_labels_foo_bar = self._course.add_unit()
        self._unit_labels_foo_bar.title = 'Unit Labels: Bar, Foo'
        self._unit_labels_foo_bar.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_foo_bar.labels = '%s %s' % (self.bar_id, self.foo_id)
        self._course.add_lesson(self._unit_labels_foo_bar)
        self._unit_labels_quux = self._course.add_unit()
        self._unit_labels_quux.title = 'Unit Labels: Quux'
        self._unit_labels_quux.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_quux.labels = str(self.quux_id)
        self._course.add_lesson(self._unit_labels_quux)
        self._unit_labels_foo_quux = self._course.add_unit()
        self._unit_labels_foo_quux.title = 'Unit Labels: Foo Quux'
        self._unit_labels_foo_quux.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_foo_quux.labels = '%s %s' % (str(self.foo_id),
                                                       str(self.quux_id))
        self._course.add_lesson(self._unit_labels_foo_quux)
        self._course.save()
Esempio n. 11
0
    def test_availability_course(self):
        course = self._init_course('test')
        env = self.enabled(availability=courses.AVAILABILITY_COURSE)

        for availability in [
                courses.COURSE_AVAILABILITY_PUBLIC,
                courses.COURSE_AVAILABILITY_REGISTRATION_OPTIONAL]:
            course.set_course_availability(availability)
            with actions.OverriddenEnvironment(env):
                actions.logout()
                self.assertPage('/test/foo/index.html', 'Web Server')
                self.assertPage('/test/foo/markdown.md', 'Web Server')
                self.assertPage('/test/foo/main.css', 'Web Server')

                actions.login('*****@*****.**')
                self.assertPage('/test/foo/index.html', 'Web Server')
                self.assertPage('/test/foo/markdown.md', 'Web Server')
                self.assertPage('/test/foo/main.css', 'Web Server')

                if availability == (
                        courses.COURSE_AVAILABILITY_REGISTRATION_OPTIONAL):
                    self.register()
                    self.assertPage('/test/foo/index.html', ' Web Server')
                    self.assertPage('/test/foo/markdown.md', ' Web Server')
                    self.assertPage('/test/foo/main.css', ' Web Server')
                    self.unregister()

                actions.login('*****@*****.**', is_admin=True)
                self.assertPage('/test/foo/index.html', ' Web Server')
                self.assertPage('/test/foo/markdown.md', ' Web Server')
                self.assertPage('/test/foo/main.css', ' Web Server')

        for availability in [
                courses.COURSE_AVAILABILITY_REGISTRATION_REQUIRED,
                courses.COURSE_AVAILABILITY_PRIVATE]:
            course.set_course_availability(availability)
            with actions.OverriddenEnvironment(env):
                actions.logout()
                self.assertNoPage('/test/foo/index.html')
                self.assertNoPage('/test/foo/markdown.md')
                self.assertNoPage('/test/foo/main.css')

                actions.login('*****@*****.**')
                self.assertNoPage('/test/foo/index.html')
                self.assertNoPage('/test/foo/markdown.md')
                self.assertNoPage('/test/foo/main.css')

                if availability == (
                        courses.COURSE_AVAILABILITY_REGISTRATION_REQUIRED):
                    self.register()
                    self.assertPage('/test/foo/index.html', ' Web Server')
                    self.assertPage('/test/foo/markdown.md', ' Web Server')
                    self.assertPage('/test/foo/main.css', ' Web Server')
                    self.unregister()

                actions.login('*****@*****.**', is_admin=True)
                self.assertPage('/test/foo/index.html', ' Web Server')
                self.assertPage('/test/foo/markdown.md', ' Web Server')
                self.assertPage('/test/foo/main.css', ' Web Server')
 def test_unsubscribe_request_with_no_email_prompts_for_login(self):
     actions.logout()
     response = self.get('modules/unsubscribe')
     self.assertEquals(302, response.status_int)
     self.assertEquals(
         'https://www.google.com/accounts/Login'
         '?continue=http%3A//localhost/a/modules/unsubscribe',
         response.headers['Location'])
 def test_handler_rejects_non_super_user(self):
     actions.logout()
     xsrf_token = crypto.XsrfTokenManager.create_xsrf_token(self.XSRF_TOKEN)
     response = self.do_post(xsrf_token, False)
     self.assertEqual(200, response.status_int)
     response_dict = transforms.loads(response.body)
     self.assertEqual(401, response_dict['status'])
     self.assertIn('Access denied.', response_dict['message'])
    def test_banner_without_buttons_shown_to_instructor_on_dashboard(self):
        actions.logout()
        actions.login(self.NOT_SUPER_EMAIL, is_admin=False)

        dom = self.parse_html_string(self.get('dashboard').body)
        banner = dom.find('.//div[@class="consent-banner"]')
        self.assertIsNotNone(banner)
        self.assertIn(self.NOT_SUPER_MESSAGE, banner.findall('.//p')[1].text)
        self.assertEqual(0, len(banner.findall('.//button')))
 def test_not_registered(self):
     actions.logout()
     actions.login(UNREGISTERED_STUDENT_EMAIL)
     xsrf_token = crypto.XsrfTokenManager.create_xsrf_token(
         manual_progress.XSRF_ACTION)
     response = self.get(UNIT_PROGRESS_URL +
                         '?key=%s' % self._unit_one.unit_id +
                         '&xsrf_token=%s' % xsrf_token)
     self._expect_response(response, 401, 'Access Denied.')
 def test_cancel_import_not_admin(self):
     actions.logout()
     response = self.post(self.dashboard_url, {
         'action':
             unit_lesson_editor.UnitLessonEditor.ACTION_POST_CANCEL_IMPORT,
         'xsrf_token': crypto.XsrfTokenManager.create_xsrf_token(
             unit_lesson_editor.UnitLessonEditor.ACTION_POST_CANCEL_IMPORT),
         })
     self.assertEquals(302, response.status_int)
Esempio n. 17
0
    def setUp(self):
        super(StudentTracksTest, self).setUp()

        # Add a course that will show up.
        actions.simple_add_course(COURSE_NAME, ADMIN_EMAIL, COURSE_TITLE)

        # Add labels
        with common_utils.Namespace(NAMESPACE):
            self.foo_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {"title": "Foo", "descripton": "foo", "type": models.LabelDTO.LABEL_TYPE_COURSE_TRACK}
                )
            )
            self.bar_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {"title": "Bar", "descripton": "bar", "type": models.LabelDTO.LABEL_TYPE_COURSE_TRACK}
                )
            )
            self.baz_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {"title": "Baz", "descripton": "baz", "type": models.LabelDTO.LABEL_TYPE_COURSE_TRACK}
                )
            )
            self.quux_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {"title": "Quux", "descripton": "quux", "type": models.LabelDTO.LABEL_TYPE_GENERAL}
                )
            )

        # Register a student for that course.
        actions.login(REGISTERED_STUDENT_EMAIL)
        actions.register(self, REGISTERED_STUDENT_NAME, COURSE_NAME)
        actions.logout()

        # Add some units to the course.
        self._course = courses.Course(None, app_context=sites.get_all_courses()[0])
        self._unit_no_labels = self._course.add_unit()
        self._unit_no_labels.title = "Unit No Labels"
        self._unit_no_labels.now_available = True
        self._unit_labels_foo = self._course.add_unit()
        self._unit_labels_foo.title = "Unit Labels: Foo"
        self._unit_labels_foo.now_available = True
        self._unit_labels_foo.labels = str(self.foo_id)
        self._unit_labels_foo_bar = self._course.add_unit()
        self._unit_labels_foo_bar.title = "Unit Labels: Bar, Foo"
        self._unit_labels_foo_bar.now_available = True
        self._unit_labels_foo_bar.labels = "%s %s" % (self.bar_id, self.foo_id)
        self._unit_labels_quux = self._course.add_unit()
        self._unit_labels_quux.title = "Unit Labels: Quux"
        self._unit_labels_quux.now_available = True
        self._unit_labels_quux.labels = str(self.quux_id)
        self._unit_labels_foo_quux = self._course.add_unit()
        self._unit_labels_foo_quux.title = "Unit Labels: Foo Quux"
        self._unit_labels_foo_quux.now_available = True
        self._unit_labels_foo_quux.labels = "%s %s" % (str(self.foo_id), str(self.quux_id))
        self._course.save()
 def test_unsubscribe_request_with_no_email_prompts_for_login(self):
     actions.logout()
     course = courses.Course(None, app_context=sites.get_all_courses()[0])
     course.set_course_availability(courses.COURSE_AVAILABILITY_PUBLIC)
     response = self.get('modules/unsubscribe')
     self.assertEquals(302, response.status_int)
     self.assertEquals(
         'https://www.google.com/accounts/Login'
         '?continue=http%3A//localhost/a/modules/unsubscribe',
         response.headers['Location'])
 def test_access_assessment(self):
     assessment = self.course.add_assessment()
     assessment.is_draft = True
     self.course.save()
     self.assertEquals(
         self.get('assessment?name=%s' % assessment.unit_id).status_int, 302)
     actions.login(self.USER_EMAIL, is_admin=False)
     self.assertEquals(
         self.get('assessment?name=%s' % assessment.unit_id).status_int, 200)
     actions.logout()
    def test_course_picker(self):
        actions.login(self.USER_EMAIL, is_admin=False)
        picker_options = self._get_all_picker_options()
        self.assertEquals(len(list(picker_options)), 1)
        actions.logout()

        actions.login(self.ADMIN_EMAIL, is_admin=True)
        picker_options = self._get_all_picker_options()
        # Expect 3 courses, as the default one is also considered for the picker
        self.assertEquals(len(picker_options), 3)
        actions.logout()
 def test_edit_lesson_buttons_for_each_lesson(self):
     actions.logout()
     actions.login(ADMIN_EMAIL)
     dom = self.parse_html_string(
         self.get(UNIT_URL_PREFIX + str(self.unit.unit_id)).body)
     # The Edit Lesson buttons all have a data-lesson-id attribute set
     buttons = dom.findall('.//*[@data-lesson-id]')
     self.assertEquals(2, len(buttons))
     self.assertEquals(
         str(self.lesson_one.lesson_id), buttons[0].get('data-lesson-id'))
     self.assertEquals(
         str(self.lesson_two.lesson_id), buttons[1].get('data-lesson-id'))
Esempio n. 22
0
 def setUp(self):
     super(TextFileUploadHandlerTestCase, self).setUp()
     self.contents = "contents"
     self.email = "*****@*****.**"
     self.headers = {"referer": "http://localhost/path?query=value#fragment"}
     self.unit_id = "1"
     actions.login(self.email)
     user = users.get_current_user()
     actions.logout()
     self.user_id = user.user_id()
     self.student = models.Student(is_enrolled=True, key_name=self.email, user_id=self.user_id)
     self.student.put()
     # Allow protected access for tests. pylint: disable=protected-access
     self.xsrf_token = utils.XsrfTokenManager.create_xsrf_token(upload._XSRF_TOKEN_NAME)
 def test_access_lesson(self):
     unit = self.course.add_unit()
     unit.is_draft = True
     lesson = self.course.add_lesson(unit)
     lesson.is_draft = True
     self.course.save()
     self.assertEquals(
         self.get('unit?unit=%s&lesson=%s' % (
         unit.unit_id, lesson.lesson_id)).status_int, 302)
     actions.login(self.USER_EMAIL, is_admin=False)
     self.assertEquals(
         self.get('unit?unit=%s&lesson=%s' % (
         unit.unit_id, lesson.lesson_id)).status_int, 200)
     actions.logout()
Esempio n. 24
0
    def test_guide_disabled(self):
        with actions.OverriddenEnvironment(self.GUIDE_DISABLED):
            for name in ["Alpha", "Bravo", "Charlie", "Delta"]:
                actions.logout()
                self.assert_guide_not_accesssible(name)

                actions.login("*****@*****.**")
                self.assert_guide_not_accesssible(name)

                if name == "Bravo" or name == "Charlie":
                    self.register(name)
                    self.assert_guide_not_accesssible(name)

                actions.login("*****@*****.**", is_admin=True)
                self.assert_guide_not_accesssible(name)
 def setUp(self):
     super(TextFileUploadHandlerTestCase, self).setUp()
     self.contents = 'contents'
     self.email = '*****@*****.**'
     self.headers = {'referer': 'http://localhost/path?query=value#fragment'}
     self.unit_id = '1'
     actions.login(self.email)
     user = users.get_current_user()
     actions.logout()
     self.user_id = user.user_id()
     self.student = models.Student(
         is_enrolled=True, key_name=self.email, user_id=self.user_id)
     self.student.put()
     self.xsrf_token = utils.XsrfTokenManager.create_xsrf_token(
         upload._XSRF_TOKEN_NAME)
 def test_dashboard_access_method(self):
     with utils.Namespace(self.course_with_access.app_context.namespace):
         self.assertFalse(dashboard.DashboardHandler.current_user_has_access(
             self.course_with_access.app_context))
     with utils.Namespace(self.course_without_access.app_context.namespace):
         self.assertFalse(dashboard.DashboardHandler.current_user_has_access(
             self.course_without_access.app_context))
     actions.login(self.USER_EMAIL, is_admin=False)
     with utils.Namespace(self.course_with_access.app_context.namespace):
         self.assertTrue(dashboard.DashboardHandler.current_user_has_access(
             self.course_with_access.app_context))
     with utils.Namespace(self.course_without_access.app_context.namespace):
         self.assertFalse(dashboard.DashboardHandler.current_user_has_access(
             self.course_without_access.app_context))
     actions.logout()
Esempio n. 27
0
    def test_content_permissions(self):
        # as admin, you can access this
        response = self.get('modules/drive/item/content?key=6')
        self.assertEqual(response.status_code, 200)

        # as nobody, you can't
        actions.logout()
        response = self.get(
            'modules/drive/item/content?key=6', expect_errors=True)
        self.assertEqual(response.status_code, 404)

        # unless it's public
        self.set_availability_for_file('6', 'public')
        response = self.get(
            'modules/drive/item/content?key=6', expect_errors=True)
        self.assertEqual(response.status_code, 404)
    def test_banner_not_shown_when_choices_have_been_made(self):
        config.set_report_allowed(False)

        # Check super-user role; global admin
        dom = self.parse_html_string(self.get('/admin/global').body)
        self.assertIsNone(dom.find('.//div[@class="consent-banner"]'))

        # check super-user role; dashboard
        dom = self.parse_html_string(self.get('dashboard').body)
        self.assertIsNone(dom.find('.//div[@class="consent-banner"]'))

        # Check non-super role; dashboadd
        actions.logout()
        actions.login(self.NOT_SUPER_EMAIL, is_admin=False)
        dom = self.parse_html_string(self.get('dashboard').body)
        self.assertIsNone(dom.find('.//div[@class="consent-banner"]'))
Esempio n. 29
0
    def test_banner_not_shown_when_choices_have_been_made(self):
        config.set_report_allowed(False)

        # Check super-user role; global admin
        dom = self.parse_html_string(self.get('/admin/global').body)
        self.assertIsNone(dom.find('.//div[@class="consent-banner"]'))

        # check super-user role; dashboard
        dom = self.parse_html_string(self.get('dashboard').body)
        self.assertIsNone(dom.find('.//div[@class="consent-banner"]'))

        # Check non-super role; dashboadd
        actions.logout()
        actions.login(self.NOT_SUPER_EMAIL, is_admin=False)
        dom = self.parse_html_string(self.get('dashboard').body)
        self.assertIsNone(dom.find('.//div[@class="consent-banner"]'))
    def test_add_reviewer(self):
        """Test that admin can add a reviewer, and cannot re-add reviewers."""

        email = '*****@*****.**'
        name = 'Test Add Reviewer'
        submission = transforms.dumps([
            {'index': 0, 'type': 'regex', 'value': 'First answer to Q1',
             'correct': True},
            {'index': 1, 'type': 'choices', 'value': 3, 'correct': False},
            {'index': 2, 'type': 'regex', 'value': 'First answer to Q3',
             'correct': True},
        ])
        payload = {
            'answers': submission, 'assessment_type': LEGACY_REVIEW_UNIT_ID}

        actions.login(email)
        actions.register(self, name)
        response = actions.submit_assessment(
            self, LEGACY_REVIEW_UNIT_ID, payload)

        # There is nothing to review on the review dashboard.
        response = actions.request_new_review(
            self, LEGACY_REVIEW_UNIT_ID, expected_status_code=200)
        actions.assert_does_not_contain('Assignment to review', response.body)
        actions.assert_contains(
            'Sorry, there are no new submissions ', response.body)
        actions.logout()

        # The admin assigns the student to review his own work.
        actions.login(email, is_admin=True)
        response = actions.add_reviewer(
            self, LEGACY_REVIEW_UNIT_ID, email, email)
        actions.assert_equals(response.status_int, 302)
        response = self.get(response.location)
        actions.assert_does_not_contain(
            'Error 412: The reviewer is already assigned', response.body)
        actions.assert_contains('First answer to Q1', response.body)
        actions.assert_contains(
            'Review 1 from [email protected]', response.body)

        # The admin repeats the 'add reviewer' action. This should fail.
        response = actions.add_reviewer(
            self, LEGACY_REVIEW_UNIT_ID, email, email)
        actions.assert_equals(response.status_int, 302)
        response = self.get(response.location)
        actions.assert_contains(
            'Error 412: The reviewer is already assigned', response.body)
    def test_data_extraction(self):

        # Register a student and save some form values for that student
        student = self.register()

        entity = StudentFormEntity.load_or_default(student, 'form-0')
        entity.value = transforms.dumps({
            u'form_data': self.FORM_0_DATA})
        entity.put()

        entity = StudentFormEntity.load_or_default(student, u'form-1')
        entity.value = transforms.dumps({
            u'form_data': self.FORM_1_DATA})
        entity.put()

        entity = StudentFormEntity.load_or_default(student, u'form-2')
        entity.value = transforms.dumps({
            u'form_data': self.FORM_2_DATA})
        entity.put()

        # Log in as admin for the data query
        actions.logout()
        actions.login(ADMIN_EMAIL, is_admin=True)

        xsrf_token = crypto.XsrfTokenManager.create_xsrf_token(
            data_sources_utils.DATA_SOURCE_ACCESS_XSRF_ACTION)

        pii_secret = crypto.generate_transform_secret_from_xsrf_token(
            xsrf_token, data_sources_utils.DATA_SOURCE_ACCESS_XSRF_ACTION)

        safe_user_id = crypto.hmac_sha_2_256_transform(
            pii_secret, student.user_id)

        response = self.get(
            'rest/data/questionnaire_responses/items?'
            'data_source_token=%s&page_number=0' % xsrf_token)
        data = transforms.loads(response.body)['data']

        self.assertEqual(3, len(data))

        for index in range(3):
            self.assertIn(safe_user_id, data[index]['user_id'])
            self.assertEqual('form-%s' % index, data[index]['questionnaire_id'])

        self.assertEqual(self.FORM_0_DATA, data[0]['form_data'])
        self.assertEqual(self.FORM_1_DATA, data[1]['form_data'])
        self.assertEqual(self.FORM_2_DATA_OUT, data[2]['form_data'])
    def test_unit_access_unavailable(self):
        actions.logout()

        self.unit.availability = courses.AVAILABILITY_UNAVAILABLE
        self.course.save()

        # Access single unit
        response = self.get_response(
            '{course(id: "%s") {unit(id: "%s") {title} }}' %
            (self.course_id, self.unit_id))
        self.assertIsNone(response['data']['course']['unit'])

        # Access unit list
        response = self.get_response(
            '{course(id: "%s") {allUnits {edges {node {id}}}}}' %
            (self.course_id))
        self.assertEquals([], response['data']['course']['allUnits']['edges'])
    def test_not_enough_assignments_to_allocate(self):
        """Test for the case when there are too few assignments in the pool."""

        email = '*****@*****.**'
        name = 'Student 1'
        submission = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S1-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'is-S1',
                'correct': True
            },
        ])
        payload = {
            'answers': submission,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        actions.login(email)
        actions.register(self, name)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload)

        # The student goes to the review dashboard and requests an assignment
        # to review -- but there is nothing to review.
        response = actions.request_new_review(self,
                                              LEGACY_REVIEW_UNIT_ID,
                                              expected_status_code=200)
        actions.assert_does_not_contain('Assignment to review', response.body)
        actions.assert_contains('Sorry, there are no new submissions ',
                                response.body)
        actions.assert_contains('disabled="true"', response.body)

        actions.logout()
    def test_student_cannot_see_reviews_prematurely(self):
        """Test that students cannot see others' reviews prematurely."""

        email = '*****@*****.**'
        name = 'Student 1'
        submission = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S1-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'is-S1',
                'correct': True
            },
        ])
        payload = {
            'answers': submission,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        actions.login(email)
        actions.register(self, name)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload)

        # Student 1 cannot see the reviews for his assignment yet, because he
        # has not submitted the two required reviews.
        response = self.get('assessment?name=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_equals(response.status_int, 200)
        actions.assert_contains('Due date for this assignment', response.body)
        actions.assert_contains(
            'After you have completed the required number of peer reviews',
            response.body)

        actions.logout()
Esempio n. 35
0
 def setUp(self):
     super(TextFileUploadHandlerTestCase, self).setUp()
     self.contents = 'contents'
     self.email = '*****@*****.**'
     self.headers = {
         'referer': 'http://localhost/path?query=value#fragment'
     }
     self.unit_id = '1'
     actions.login(self.email)
     user = users.get_current_user()
     actions.logout()
     self.user_id = user.user_id()
     self.student = models.Student(is_enrolled=True,
                                   key_name=self.email,
                                   user_id=self.user_id)
     self.student.put()
     self.xsrf_token = utils.XsrfTokenManager.create_xsrf_token(
         upload._XSRF_TOKEN_NAME)
    def test_data_extraction(self):

        # Register a student and save some form values for that student
        student = self.register()

        entity = StudentFormEntity.load_or_create(student, 'form-0')
        entity.value = transforms.dumps({u'form_data': self.FORM_0_DATA})
        entity.put()

        entity = StudentFormEntity.load_or_create(student, u'form-1')
        entity.value = transforms.dumps({u'form_data': self.FORM_1_DATA})
        entity.put()

        entity = StudentFormEntity.load_or_create(student, u'form-2')
        entity.value = transforms.dumps({u'form_data': self.FORM_2_DATA})
        entity.put()

        # Log in as admin for the data query
        actions.logout()
        actions.login(ADMIN_EMAIL, is_admin=True)

        xsrf_token = crypto.XsrfTokenManager.create_xsrf_token(
            data_sources_utils.DATA_SOURCE_ACCESS_XSRF_ACTION)

        pii_secret = crypto.generate_transform_secret_from_xsrf_token(
            xsrf_token, data_sources_utils.DATA_SOURCE_ACCESS_XSRF_ACTION)

        safe_user_id = crypto.hmac_sha_2_256_transform(pii_secret,
                                                       student.user_id)

        response = self.get('rest/data/questionnaire_responses/items?'
                            'data_source_token=%s&page_number=0' % xsrf_token)
        data = transforms.loads(response.body)['data']

        self.assertEqual(3, len(data))

        for index in range(3):
            self.assertIn(safe_user_id, data[index]['user_id'])
            self.assertEqual('form-%s' % index,
                             data[index]['questionnaire_id'])

        self.assertEqual(self.FORM_0_DATA, data[0]['form_data'])
        self.assertEqual(self.FORM_1_DATA, data[1]['form_data'])
        self.assertEqual(self.FORM_2_DATA_OUT, data[2]['form_data'])
Esempio n. 37
0
    def setUp(self):
        super(DashboardAccessTestCase, self).setUp()
        actions.login(self.ADMIN_EMAIL, is_admin=True)

        context = actions.simple_add_course(
            self.ACCESS_COURSE_NAME, self.ADMIN_EMAIL, 'Course with access')

        self.course_with_access = courses.Course(None, context)

        with utils.Namespace(self.course_with_access.app_context.namespace):
            role_dto = models.RoleDTO(None, {
                'name': self.ROLE,
                'users': [self.USER_EMAIL],
                'permissions': {dashboard.custom_module.name: [self.PERMISSION]}
            })
            models.RoleDAO.save(role_dto)

        context = actions.simple_add_course(
            self.NO_ACCESS_COURSE_NAME, self.ADMIN_EMAIL,
            'Course with no access'
        )

        self.course_without_access = courses.Course(None, context)

        def test_content(self):
            return self.render_page(
                {'main_content': 'test', 'page_title': 'test'})

        # save properties
        self.old_menu_group = dashboard.DashboardHandler.root_menu_group
        # pylint: disable=W0212
        self.old_get_acitons = dashboard.DashboardHandler._custom_get_actions
        # pylint: enable=W0212

        # put a dummy method in
        menu_group = menus.MenuGroup('test', 'Test Dashboard')
        dashboard.DashboardHandler.root_menu_group = menu_group
        dashboard.DashboardHandler.default_action = self.ACTION
        dashboard.DashboardHandler.add_nav_mapping(self.ACTION, self.ACTION)
        dashboard.DashboardHandler.add_sub_nav_mapping(self.ACTION, self.ACTION,
            self.ACTION, action=self.ACTION, contents=test_content)
        dashboard.DashboardHandler.map_get_action_to_permission(
            self.ACTION, dashboard.custom_module, self.PERMISSION)
        actions.logout()
 def test_dashboard_access_method(self):
     with utils.Namespace(self.course_with_access.app_context.namespace):
         self.assertFalse(
             dashboard.DashboardHandler.current_user_has_access(
                 self.course_with_access.app_context))
     with utils.Namespace(self.course_without_access.app_context.namespace):
         self.assertFalse(
             dashboard.DashboardHandler.current_user_has_access(
                 self.course_without_access.app_context))
     actions.login(self.USER_EMAIL, is_admin=False)
     with utils.Namespace(self.course_with_access.app_context.namespace):
         self.assertTrue(
             dashboard.DashboardHandler.current_user_has_access(
                 self.course_with_access.app_context))
     with utils.Namespace(self.course_without_access.app_context.namespace):
         self.assertFalse(
             dashboard.DashboardHandler.current_user_has_access(
                 self.course_without_access.app_context))
     actions.logout()
Esempio n. 39
0
    def test_data_source(self):

        # Register a student and give some feedback
        user = self.register_student()
        student = models.Student.get_enrolled_student_by_user(user)
        response = self.post_data(
            rating_int=2, additional_comments='Good lesson')
        self.assertEquals(200, response['status'])
        self.assertIn('Thank you for your feedback', response['message'])

        # Log in as admin for the data query
        actions.logout()
        actions.login(ADMIN_EMAIL, is_admin=True)

        xsrf_token = crypto.XsrfTokenManager.create_xsrf_token(
            data_sources_utils.DATA_SOURCE_ACCESS_XSRF_ACTION)

        pii_secret = crypto.generate_transform_secret_from_xsrf_token(
            xsrf_token, data_sources_utils.DATA_SOURCE_ACCESS_XSRF_ACTION)

        safe_user_id = crypto.hmac_sha_2_256_transform(
            pii_secret, student.user_id)

        response = self.get(
            'rest/data/rating_events/items?'
            'data_source_token=%s&page_number=0' % xsrf_token)
        data = transforms.loads(response.body)['data']

        self.assertEqual(1, len(data))
        record = data[0]

        self.assertEqual(7, len(record))
        self.assertEqual(safe_user_id, record['user_id'])
        self.assertEqual('2', record['rating'])
        self.assertEqual('Good lesson', record['additional_comments'])
        self.assertEqual(
            '/rating_course/unit?unit=%s&lesson=%s' % (
                self.unit.unit_id, self.lesson.lesson_id),
            record['content_url'])
        self.assertEqual(str(self.unit.unit_id), record['unit_id'])
        self.assertEqual(str(self.lesson.lesson_id), record['lesson_id'])
        self.assertIn('recorded_on', record)
Esempio n. 40
0
    def test_guide_enabled_course(self):
        with actions.OverriddenEnvironment(self.GUIDE_ENABLED_COURSE):
            actions.logout()
            self.assert_guide_accesssible('Alpha')
            self.assert_guide_accesssible('Bravo')
            self.assert_guide_not_accesssible('Charlie',
                                              is_guides_accessible=True)
            self.assert_guide_not_accesssible('Delta',
                                              is_guides_accessible=True)

            actions.login('*****@*****.**')
            self.assert_guide_accesssible('Alpha')
            self.assert_guide_accesssible('Bravo')
            self.assert_guide_not_accesssible('Charlie',
                                              is_guides_accessible=True)
            self.assert_guide_not_accesssible('Delta',
                                              is_guides_accessible=True)

            self.register('Charlie')
            self.assert_guide_accesssible('Alpha')
            self.assert_guide_accesssible('Bravo')
            self.assert_guide_accesssible('Charlie')
            self.assert_guide_not_accesssible('Delta',
                                              is_guides_accessible=True)

            actions.login('*****@*****.**', is_admin=True)
            for name in ['Alpha', 'Bravo', 'Charlie', 'Delta']:
                self.assert_guide_accesssible(name)

            # check course labels as admin sees them
            response = self.get('/modules/guides')
            self.assertEquals(200, response.status_int)
            self.assertIn('category="Power Searching with Google [Alpha]',
                          response.body)
            self.assertIn('category="Power Searching with Google [Bravo]',
                          response.body)
            self.assertIn(
                'category="Power Searching with Google [Charlie] '
                '(Registration required)', response.body)
            self.assertIn(
                'category="Power Searching with Google [Delta] (Private)',
                response.body)
    def test_unit_access_available(self):
        actions.logout()

        self.unit.availability = courses.AVAILABILITY_AVAILABLE
        self.course.save()

        # Access single unit
        response = self.get_response(
            '{course (id: "%s") {unit(id: "%s") { title } }}' %
            (self.course_id, self.unit_id))
        self.assertEquals(self.unit.title,
                          response['data']['course']['unit']['title'])

        # Access unit list
        response = self.get_response(
            '{course(id: "%s") {allUnits {edges {node {'
            '  ... on Unit {id title}}}}}}' % self.course_id)
        edges = response['data']['course']['allUnits']['edges']
        self.assertEquals(1, len(edges))
        self.assertEquals(self.unit.title, edges[0]['node']['title'])
Esempio n. 42
0
    def setUp(self):
        super(WhitelistTest, self).setUp()

        config.Registry.test_overrides[
            course_explorer.GCB_ENABLE_COURSE_EXPLORER_PAGE.name] = True

        actions.login(ADMIN_EMAIL, is_admin=True)
        payload_dict = {
            'name': COURSE_NAME,
            'title': 'Whitelist Test',
            'admin_email': ADMIN_EMAIL}
        request = {
            'payload': transforms.dumps(payload_dict),
            'xsrf_token': crypto.XsrfTokenManager.create_xsrf_token(
                'add-course-put')}
        response = self.testapp.put('/rest/courses/item?%s' % urllib.urlencode(
            {'request': transforms.dumps(request)}), {})
        self.assertEquals(response.status_int, 200)
        sites.setup_courses('course:/%s::ns_%s, course:/:/' % (
                COURSE_NAME, COURSE_NAME))
        actions.logout()
    def test_handling_of_fake_review_step_key(self):
        """Test that bad keys result in the appropriate responses."""

        email = '*****@*****.**'
        name = 'Student 1'
        submission = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S1-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'is-S1',
                'correct': True
            },
        ])
        payload = {
            'answers': submission,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        actions.login(email)
        actions.register(self, name)
        actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID, payload)

        actions.view_review(self,
                            LEGACY_REVIEW_UNIT_ID,
                            'Fake key',
                            expected_status_code=404)

        actions.logout()
    def test_lesson_access_unavailable(self):
        actions.logout()

        self.unit.availability = courses.AVAILABILITY_AVAILABLE
        self.lesson.availability = courses.AVAILABILITY_UNAVAILABLE
        self.lesson.shown_when_unavailable = False
        self.course.save()

        # Access single lesson
        response = self.get_response(
            '{course(id: "%s") {unit(id: "%s") {'
            'lesson(id: "%s") {title body}}}}' %
            (self.course_id, self.unit_id, self.lesson_id))
        self.assertIsNone(response['data']['course']['unit']['lesson'])

        # Access lesson list
        response = self.get_response(
            '{course(id: "%s") {unit(id: "%s") {allLessons {edges {node {'
            '  ... on Lesson{title body}}}}}}}' %
            (self.course_id, self.unit_id))
        self.assertEquals(
            [], response['data']['course']['unit']['allLessons']['edges'])
Esempio n. 45
0
    def setUp(self):
        super(StudentLabelsTest, self).setUp()
        actions.simple_add_course(COURSE_NAME, ADMIN_EMAIL, COURSE_TITLE)

        with common_utils.Namespace(NAMESPACE):
            self.foo_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {
                        'title': 'Foo',
                        'descripton': 'foo',
                        'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK
                    }))
            self.bar_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {
                        'title': 'Bar',
                        'descripton': 'bar',
                        'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK
                    }))
            self.baz_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {
                        'title': 'Baz',
                        'descripton': 'baz',
                        'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK
                    }))
            self.quux_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {
                        'title': 'Quux',
                        'descripton': 'quux',
                        'type': models.LabelDTO.LABEL_TYPE_GENERAL
                    }))

        actions.login(REGISTERED_STUDENT_EMAIL)
        actions.register(self, REGISTERED_STUDENT_NAME, COURSE_NAME)
        actions.logout()
    def setUp(self):
        super(BaseQuestionnaireTests, self).setUp()

        actions.login(ADMIN_EMAIL, is_admin=True)
        self.base = '/' + COURSE_NAME

        test_course = actions.simple_add_course(COURSE_NAME, ADMIN_EMAIL,
                                                'Questionnaire Test Course')

        self.old_namespace = namespace_manager.get_namespace()
        namespace_manager.set_namespace('ns_%s' % COURSE_NAME)

        self.course = courses.Course(None, test_course)
        test_unit = self.course.add_unit()
        test_unit.now_available = True
        test_lesson = self.course.add_lesson(test_unit)
        test_lesson.now_available = True
        test_lesson.title = 'This is a lesson that contains a form.'
        test_lesson.objectives = '%s\n%s' % (TEST_FORM_HTML, QUESTIONNAIRE_TAG)
        self.unit_id = test_unit.unit_id
        self.lesson_id = test_lesson.lesson_id
        self.course.save()

        actions.logout()
    def test_lesson_access_available(self):
        actions.logout()

        self.unit.availability = courses.AVAILABILITY_AVAILABLE
        self.lesson.availability = courses.AVAILABILITY_AVAILABLE
        self.course.save()
        expected_lesson = {'title': self.lesson.title, 'body': 'Lesson body'}

        # Access single lesson
        response = self.get_response(
            '{course(id: "%s") {unit(id: "%s") {'
            'lesson(id: "%s") {title body}}}}' %
            (self.course_id, self.unit_id, self.lesson_id))
        _lesson = response['data']['course']['unit']['lesson']
        self.assertEquals(expected_lesson, _lesson)

        # Access lesson list
        response = self.get_response(
            '{course(id: "%s") {unit(id: "%s") {allLessons {edges {node {'
            '  ... on Lesson{title body}}}}}}}' %
            (self.course_id, self.unit_id))
        edges = response['data']['course']['unit']['allLessons']['edges']
        self.assertEquals(1, len(edges))
        self.assertEquals(expected_lesson, edges[0]['node'])
    def test_submit_assignment(self):
        """Test submission of peer-reviewed assignments."""

        # Override course.yaml settings by patching app_context.
        get_environ_old = sites.ApplicationContext.get_environ

        def get_environ_new(self):
            environ = get_environ_old(self)
            environ['course']['browsable'] = False
            return environ

        sites.ApplicationContext.get_environ = get_environ_new

        email = '*****@*****.**'
        name = 'Test Peer Reviewed Assignment Submission'
        submission = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'First answer to Q1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'First answer to Q3',
                'correct': True
            },
        ])
        second_submission = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'Second answer to Q1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'Second answer to Q3',
                'correct': True
            },
        ])

        actions.login(email)
        actions.register(self, name)

        # Check that the sample peer-review assignment shows up in the course
        # page and that it can be visited.
        response = actions.view_course(self)
        actions.assert_contains('Sample peer review assignment', response.body)
        actions.assert_contains('Review peer assignments', response.body)
        actions.assert_contains(
            '<a href="assessment?name=%s">' % LEGACY_REVIEW_UNIT_ID,
            response.body)
        actions.assert_contains('Review peer assignments </p>',
                                response.body,
                                collapse_whitespace=True)
        actions.assert_does_not_contain('<a href="reviewdashboard',
                                        response.body,
                                        collapse_whitespace=True)

        # Check that the progress circle for this assignment is unfilled.
        actions.assert_contains(
            'progress-notstarted-%s' % LEGACY_REVIEW_UNIT_ID, response.body)
        actions.assert_does_not_contain(
            'progress-completed-%s' % LEGACY_REVIEW_UNIT_ID, response.body)

        # Try to access an invalid assignment.
        response = self.get('assessment?name=FakeAssessment',
                            expect_errors=True)
        actions.assert_equals(response.status_int, 404)

        # The student should not be able to see others' reviews because he/she
        # has not submitted an assignment yet.
        response = self.get('assessment?name=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_does_not_contain('Submitted assignment', response.body)
        actions.assert_contains('Due date for this assignment', response.body)
        actions.assert_does_not_contain('Reviews received', response.body)

        # The student should not be able to access the review dashboard because
        # he/she has not submitted the assignment yet.
        response = self.get('reviewdashboard?unit=%s' % LEGACY_REVIEW_UNIT_ID,
                            expect_errors=True)
        actions.assert_contains('You must submit the assignment for',
                                response.body)

        # The student submits the assignment.
        response = actions.submit_assessment(
            self, LEGACY_REVIEW_UNIT_ID, {
                'answers': submission,
                'assessment_type': LEGACY_REVIEW_UNIT_ID
            })
        actions.assert_contains('Thank you for completing this assignment',
                                response.body)
        actions.assert_contains('Review peer assignments', response.body)

        # The student views the submitted assignment, which has become readonly.
        response = self.get('assessment?name=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_contains('First answer to Q1', response.body)
        actions.assert_contains('Submitted assignment', response.body)

        # The student tries to re-submit the same assignment. This should fail.
        response = actions.submit_assessment(
            self,
            LEGACY_REVIEW_UNIT_ID, {
                'answers': second_submission,
                'assessment_type': LEGACY_REVIEW_UNIT_ID
            },
            presubmit_checks=False)
        actions.assert_contains('You have already submitted this assignment.',
                                response.body)
        actions.assert_contains('Review peer assignments', response.body)

        # The student views the submitted assignment. The new answers have not
        # been saved.
        response = self.get('assessment?name=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_contains('First answer to Q1', response.body)
        actions.assert_does_not_contain('Second answer to Q1', response.body)

        # The student checks the course page and sees that the progress
        # circle for this assignment has been filled, and that the 'Review
        # peer assignments' link is now available.
        response = actions.view_course(self)
        actions.assert_contains(
            'progress-completed-%s' % LEGACY_REVIEW_UNIT_ID, response.body)
        actions.assert_does_not_contain(
            '<span> Review peer assignments </span>',
            response.body,
            collapse_whitespace=True)
        actions.assert_contains('<a href="reviewdashboard?unit=%s">' %
                                LEGACY_REVIEW_UNIT_ID,
                                response.body,
                                collapse_whitespace=True)

        # The student should also be able to now view the review dashboard.
        response = self.get('reviewdashboard?unit=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_contains('Assignments for your review', response.body)
        actions.assert_contains('Review a new assignment', response.body)

        actions.logout()

        # Clean up app_context.
        sites.ApplicationContext.get_environ = get_environ_old
Esempio n. 49
0
    def setUp(self):
        super(StudentTracksTest, self).setUp()

        # Add a course that will show up.
        actions.simple_add_course(COURSE_NAME, ADMIN_EMAIL, COURSE_TITLE)

        # Add labels
        with common_utils.Namespace(NAMESPACE):
            self.foo_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {
                        'title': 'Foo',
                        'descripton': 'foo',
                        'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK
                    }))
            self.bar_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {
                        'title': 'Bar',
                        'descripton': 'bar',
                        'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK
                    }))
            self.baz_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {
                        'title': 'Baz',
                        'descripton': 'baz',
                        'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK
                    }))
            self.quux_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {
                        'title': 'Quux',
                        'descripton': 'quux',
                        'type': models.LabelDTO.LABEL_TYPE_GENERAL
                    }))

        # Register a student for that course.
        actions.login(REGISTERED_STUDENT_EMAIL)
        actions.register(self, REGISTERED_STUDENT_NAME, COURSE_NAME)
        actions.logout()

        # Add some units to the course.
        self._course = courses.Course(None,
                                      app_context=sites.get_all_courses()[0])
        self._unit_no_labels = self._course.add_unit()
        self._unit_no_labels.title = 'Unit No Labels'
        self._unit_no_labels.availability = courses.AVAILABILITY_AVAILABLE
        self._course.add_lesson(self._unit_no_labels)
        self._unit_labels_foo = self._course.add_unit()
        self._unit_labels_foo.title = 'Unit Labels: Foo'
        self._unit_labels_foo.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_foo.labels = str(self.foo_id)
        self._course.add_lesson(self._unit_labels_foo)
        self._unit_labels_foo_bar = self._course.add_unit()
        self._unit_labels_foo_bar.title = 'Unit Labels: Bar, Foo'
        self._unit_labels_foo_bar.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_foo_bar.labels = '%s %s' % (self.bar_id, self.foo_id)
        self._course.add_lesson(self._unit_labels_foo_bar)
        self._unit_labels_quux = self._course.add_unit()
        self._unit_labels_quux.title = 'Unit Labels: Quux'
        self._unit_labels_quux.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_quux.labels = str(self.quux_id)
        self._course.add_lesson(self._unit_labels_quux)
        self._unit_labels_foo_quux = self._course.add_unit()
        self._unit_labels_foo_quux.title = 'Unit Labels: Foo Quux'
        self._unit_labels_foo_quux.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_foo_quux.labels = '%s %s' % (str(
            self.foo_id), str(self.quux_id))
        self._course.add_lesson(self._unit_labels_foo_quux)
        self._course.save()
 def test_logged_out_does_not_use_prefs(self):
     actions.logout()
     response = self.get(BASE_URL)
     response = response.click('Unit 1 - The Unit')
     response = self.get(BASE_URL)
     self.assertEquals(200, response.status_int)
Esempio n. 51
0
 def test_extra_tabs_on_navbar_visible_to_everyone(self):
     actions.logout()
     body = self.get('course').body
     self.assertIn('FAQ', body)
     self.assertNotIn('Resources', body)
Esempio n. 52
0
    def test_availability_course(self):
        course = self._init_course('test')
        env = self.enabled(availability=courses.AVAILABILITY_COURSE)

        for availability in [
                courses.COURSE_AVAILABILITY_PUBLIC,
                courses.COURSE_AVAILABILITY_REGISTRATION_OPTIONAL
        ]:
            course.set_course_availability(availability)
            with actions.OverriddenEnvironment(env):
                actions.logout()
                self.assertPage('/test/foo/index.html', 'Web Server')
                self.assertPage('/test/foo/markdown.md', 'Web Server')
                self.assertPage('/test/foo/main.css', 'Web Server')

                actions.login('*****@*****.**')
                self.assertPage('/test/foo/index.html', 'Web Server')
                self.assertPage('/test/foo/markdown.md', 'Web Server')
                self.assertPage('/test/foo/main.css', 'Web Server')

                if availability == (
                        courses.COURSE_AVAILABILITY_REGISTRATION_OPTIONAL):
                    self.register()
                    self.assertPage('/test/foo/index.html', ' Web Server')
                    self.assertPage('/test/foo/markdown.md', ' Web Server')
                    self.assertPage('/test/foo/main.css', ' Web Server')
                    self.unregister()

                actions.login('*****@*****.**', is_admin=True)
                self.assertPage('/test/foo/index.html', ' Web Server')
                self.assertPage('/test/foo/markdown.md', ' Web Server')
                self.assertPage('/test/foo/main.css', ' Web Server')

        for availability in [
                courses.COURSE_AVAILABILITY_REGISTRATION_REQUIRED,
                courses.COURSE_AVAILABILITY_PRIVATE
        ]:
            course.set_course_availability(availability)
            with actions.OverriddenEnvironment(env):
                actions.logout()
                self.assertNoPage('/test/foo/index.html')
                self.assertNoPage('/test/foo/markdown.md')
                self.assertNoPage('/test/foo/main.css')

                actions.login('*****@*****.**')
                self.assertNoPage('/test/foo/index.html')
                self.assertNoPage('/test/foo/markdown.md')
                self.assertNoPage('/test/foo/main.css')

                if availability == (
                        courses.COURSE_AVAILABILITY_REGISTRATION_REQUIRED):
                    self.register()
                    self.assertPage('/test/foo/index.html', ' Web Server')
                    self.assertPage('/test/foo/markdown.md', ' Web Server')
                    self.assertPage('/test/foo/main.css', ' Web Server')
                    self.unregister()

                actions.login('*****@*****.**', is_admin=True)
                self.assertPage('/test/foo/index.html', ' Web Server')
                self.assertPage('/test/foo/markdown.md', ' Web Server')
                self.assertPage('/test/foo/main.css', ' Web Server')
    def test_draft_review_behaviour(self):
        """Test correctness of draft review visibility."""

        email1 = '*****@*****.**'
        name1 = 'Student 1'
        submission1 = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S1-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'is-S1',
                'correct': True
            },
        ])
        payload1 = {
            'answers': submission1,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        email2 = '*****@*****.**'
        name2 = 'Student 2'
        submission2 = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S2-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'not-S1',
                'correct': True
            },
        ])
        payload2 = {
            'answers': submission2,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        email3 = '*****@*****.**'
        name3 = 'Student 3'
        submission3 = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S3-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'not-S1',
                'correct': True
            },
        ])
        payload3 = {
            'answers': submission3,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        # Student 1 submits the assignment.
        actions.login(email1)
        actions.register(self, name1)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload1)
        actions.logout()

        # Student 2 logs in and submits the assignment.
        actions.login(email2)
        actions.register(self, name2)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload2)

        # Student 2 requests a review, and is given Student 1's assignment.
        response = actions.request_new_review(self, LEGACY_REVIEW_UNIT_ID)
        review_step_key_2_for_1 = get_review_step_key(response)
        actions.assert_contains('S1-1', response.body)

        # Student 2 saves her review as a draft.
        review_2_for_1_payload = get_review_payload('R2for1', is_draft=True)

        response = actions.submit_review(self, LEGACY_REVIEW_UNIT_ID,
                                         review_step_key_2_for_1,
                                         review_2_for_1_payload)
        actions.assert_contains('Your review has been saved.', response.body)

        response = self.get('reviewdashboard?unit=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_equals(response.status_int, 200)
        actions.assert_contains('(Draft)', response.body)

        # Student 2's draft is still changeable.
        response = actions.view_review(self, LEGACY_REVIEW_UNIT_ID,
                                       review_step_key_2_for_1)
        actions.assert_contains('Submit Review', response.body)
        response = actions.submit_review(self, LEGACY_REVIEW_UNIT_ID,
                                         review_step_key_2_for_1,
                                         review_2_for_1_payload)
        actions.assert_contains('Your review has been saved.', response.body)

        # Student 2 logs out.
        actions.logout()

        # Student 3 submits the assignment.
        actions.login(email3)
        actions.register(self, name3)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload3)
        actions.logout()

        # Student 1 logs in and requests two assignments to review.
        actions.login(email1)
        response = self.get('/reviewdashboard?unit=%s' % LEGACY_REVIEW_UNIT_ID)

        response = actions.request_new_review(self, LEGACY_REVIEW_UNIT_ID)
        actions.assert_contains('Assignment to review', response.body)
        actions.assert_contains('not-S1', response.body)

        review_step_key_1_for_someone = get_review_step_key(response)

        response = actions.request_new_review(self, LEGACY_REVIEW_UNIT_ID)
        actions.assert_contains('Assignment to review', response.body)
        actions.assert_contains('not-S1', response.body)

        review_step_key_1_for_someone_else = get_review_step_key(response)

        response = self.get('reviewdashboard?unit=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_equals(response.status_int, 200)
        actions.assert_contains('disabled="true"', response.body)

        # Student 1 submits both reviews, fulfilling his quota.
        review_1_for_other_payload = get_review_payload('R1for')

        response = actions.submit_review(self, LEGACY_REVIEW_UNIT_ID,
                                         review_step_key_1_for_someone,
                                         review_1_for_other_payload)
        actions.assert_contains('Your review has been submitted successfully',
                                response.body)

        response = actions.submit_review(self, LEGACY_REVIEW_UNIT_ID,
                                         review_step_key_1_for_someone_else,
                                         review_1_for_other_payload)
        actions.assert_contains('Your review has been submitted successfully',
                                response.body)

        response = self.get('/reviewdashboard?unit=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_contains('(Completed)', response.body)
        actions.assert_does_not_contain('(Draft)', response.body)

        # Although Student 1 has submitted 2 reviews, he cannot view Student
        # 2's review because it is still in Draft status.
        response = self.get('assessment?name=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_equals(response.status_int, 200)
        actions.assert_contains('You have not received any peer reviews yet.',
                                response.body)
        actions.assert_does_not_contain('R2for1', response.body)

        # Student 1 logs out.
        actions.logout()

        # Student 2 submits her review for Student 1's assignment.
        actions.login(email2)

        response = self.get('review?unit=%s&key=%s' %
                            (LEGACY_REVIEW_UNIT_ID, review_step_key_2_for_1))
        actions.assert_does_not_contain('Submitted review', response.body)

        response = actions.submit_review(self, LEGACY_REVIEW_UNIT_ID,
                                         review_step_key_2_for_1,
                                         get_review_payload('R2for1'))
        actions.assert_contains('Your review has been submitted successfully',
                                response.body)

        # Her review is now read-only.
        response = self.get('review?unit=%s&key=%s' %
                            (LEGACY_REVIEW_UNIT_ID, review_step_key_2_for_1))
        actions.assert_contains('Submitted review', response.body)
        actions.assert_contains('R2for1', response.body)

        # Student 2 logs out.
        actions.logout()

        # Now Student 1 can see the review he has received from Student 2.
        actions.login(email1)
        response = self.get('assessment?name=%s' % LEGACY_REVIEW_UNIT_ID)
        actions.assert_equals(response.status_int, 200)
        actions.assert_contains('R2for1', response.body)
    def test_reviewer_cannot_impersonate_another_reviewer(self):
        """Test that one reviewer cannot use another's review step key."""

        email1 = '*****@*****.**'
        name1 = 'Student 1'
        submission1 = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S1-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'is-S1',
                'correct': True
            },
        ])
        payload1 = {
            'answers': submission1,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        email2 = '*****@*****.**'
        name2 = 'Student 2'
        submission2 = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S2-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'not-S1',
                'correct': True
            },
        ])
        payload2 = {
            'answers': submission2,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        email3 = '*****@*****.**'
        name3 = 'Student 3'
        submission3 = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S3-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'not-S1',
                'correct': True
            },
        ])
        payload3 = {
            'answers': submission3,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        # Student 1 submits the assignment.
        actions.login(email1)
        actions.register(self, name1)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload1)
        actions.logout()

        # Student 2 logs in and submits the assignment.
        actions.login(email2)
        actions.register(self, name2)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload2)

        # Student 2 requests a review, and is given Student 1's assignment.
        response = actions.request_new_review(self, LEGACY_REVIEW_UNIT_ID)
        review_step_key_2_for_1 = get_review_step_key(response)
        actions.assert_contains('S1-1', response.body)
        actions.logout()

        # Student 3 logs in, and submits the assignment.
        actions.login(email3)
        actions.register(self, name3)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload3)

        # Student 3 tries to view Student 1's assignment using Student 2's
        # review step key, but is not allowed to.
        response = actions.view_review(self,
                                       LEGACY_REVIEW_UNIT_ID,
                                       review_step_key_2_for_1,
                                       expected_status_code=404)

        # Student 3 logs out.
        actions.logout()
    def test_independence_of_draft_reviews(self):
        """Test that draft reviews do not interfere with each other."""

        email1 = '*****@*****.**'
        name1 = 'Student 1'
        submission1 = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S1-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'is-S1',
                'correct': True
            },
        ])
        payload1 = {
            'answers': submission1,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        email2 = '*****@*****.**'
        name2 = 'Student 2'
        submission2 = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S2-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'not-S1',
                'correct': True
            },
        ])
        payload2 = {
            'answers': submission2,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        email3 = '*****@*****.**'
        name3 = 'Student 3'
        submission3 = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'S3-1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'not-S1',
                'correct': True
            },
        ])
        payload3 = {
            'answers': submission3,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        # Student 1 submits the assignment.
        actions.login(email1)
        actions.register(self, name1)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload1)
        actions.logout()

        # Student 2 logs in and submits the assignment.
        actions.login(email2)
        actions.register(self, name2)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload2)
        actions.logout()

        # Student 3 logs in and submits the assignment.
        actions.login(email3)
        actions.register(self, name3)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload3)
        actions.logout()

        # Student 1 logs in and requests two assignments to review.
        actions.login(email1)
        response = self.get('/reviewdashboard?unit=%s' % LEGACY_REVIEW_UNIT_ID)

        response = actions.request_new_review(self, LEGACY_REVIEW_UNIT_ID)
        actions.assert_equals(response.status_int, 200)
        actions.assert_contains('Assignment to review', response.body)
        actions.assert_contains('not-S1', response.body)

        review_step_key_1_for_someone = get_review_step_key(response)

        response = actions.request_new_review(self, LEGACY_REVIEW_UNIT_ID)
        actions.assert_equals(response.status_int, 200)
        actions.assert_contains('Assignment to review', response.body)
        actions.assert_contains('not-S1', response.body)

        review_step_key_1_for_someone_else = get_review_step_key(response)

        self.assertNotEqual(review_step_key_1_for_someone,
                            review_step_key_1_for_someone_else)

        # Student 1 submits two draft reviews.
        response = actions.submit_review(
            self, LEGACY_REVIEW_UNIT_ID, review_step_key_1_for_someone,
            get_review_payload('R1forFirst', is_draft=True))
        actions.assert_contains('Your review has been saved.', response.body)

        response = actions.submit_review(
            self, LEGACY_REVIEW_UNIT_ID, review_step_key_1_for_someone_else,
            get_review_payload('R1forSecond', is_draft=True))
        actions.assert_contains('Your review has been saved.', response.body)

        # The two draft reviews should still be different when subsequently
        # accessed.
        response = self.get(
            'review?unit=%s&key=%s' %
            (LEGACY_REVIEW_UNIT_ID, review_step_key_1_for_someone))
        actions.assert_contains('R1forFirst', response.body)

        response = self.get(
            'review?unit=%s&key=%s' %
            (LEGACY_REVIEW_UNIT_ID, review_step_key_1_for_someone_else))
        actions.assert_contains('R1forSecond', response.body)

        # Student 1 logs out.
        actions.logout()
    def test_end_to_end(self):
        """Actually enroll and unenroll students; verify reporting counts."""

        COURSE_NAME_BASE = 'test'
        NUM_COURSES = 2
        NUM_STUDENTS = 3
        THE_TIMESTAMP = 1427245200

        for course_num in range(NUM_COURSES):
            course_name = '%s_%d' % (COURSE_NAME_BASE, course_num)
            actions.simple_add_course(course_name, ADMIN_EMAIL, course_name)
            actions.update_course_config(course_name, {
                'course': {
                    'now_available': True,
                    'browsable': True,
                },
            })
            for student_num in range(NUM_STUDENTS):
                name = '%s_%d_%d' % (COURSE_NAME_BASE, course_num, student_num)
                actions.login(name + '@foo.com')
                actions.register(self, name, course_name)
                if student_num == 0:
                    actions.unregister(self, course_name)
                actions.logout()

        # Expect no messages yet; haven't run job.
        self.assertEquals([], MockSender.get_sent())

        # Run all counting jobs.
        with actions.OverriddenConfig(config.REPORT_ALLOWED.name, True):
            usage_reporting.StartReportingJobs._for_testing_only_get()
        self.execute_all_deferred_tasks(
            models.StudentLifecycleObserver.QUEUE_NAME)
        self.execute_all_deferred_tasks()

        # Verify counts.  (Ignore dates, these are fickle and subject to
        # weirdness on hour boundaries.  Also ignore course/instance IDs;
        # they are non-random and thus all the same.)
        num_enrolled_msgs = 0
        num_unenrolled_msgs = 0
        num_student_count_msgs = 0
        for message in MockSender.get_sent():
            if (message[messaging.Message._METRIC] ==
                    messaging.Message.METRIC_STUDENT_COUNT):
                num_student_count_msgs += 1
                self.assertEquals(NUM_STUDENTS,
                                  message[messaging.Message._VALUE])
            elif (message[messaging.Message._METRIC] ==
                  messaging.Message.METRIC_ENROLLED):
                num_enrolled_msgs += 1
                self.assertEquals(NUM_STUDENTS,
                                  message[messaging.Message._VALUE])
            elif (message[messaging.Message._METRIC] ==
                  messaging.Message.METRIC_UNENROLLED):
                num_unenrolled_msgs += 1
                self.assertEquals(1, message[messaging.Message._VALUE])

        self.assertEquals(NUM_COURSES, num_enrolled_msgs)
        self.assertEquals(NUM_COURSES, num_unenrolled_msgs)
        self.assertEquals(NUM_COURSES, num_student_count_msgs)
        sites.reset_courses()
Esempio n. 57
0
    def test_peer_review_analytics(self):
        """Test analytics page on course dashboard."""

        student1 = '*****@*****.**'
        name1 = 'Test Student 1'
        student2 = '*****@*****.**'
        name2 = 'Test Student 2'

        peer = {'assessment_type': 'ReviewAssessmentExample'}

        # Student 1 submits a peer review assessment.
        actions.login(student1)
        actions.register(self, name1)
        actions.submit_assessment(self, 'ReviewAssessmentExample', peer)
        actions.logout()

        # Student 2 submits the same peer review assessment.
        actions.login(student2)
        actions.register(self, name2)
        actions.submit_assessment(self, 'ReviewAssessmentExample', peer)
        actions.logout()

        email = '*****@*****.**'

        # The admin looks at the analytics page on the dashboard.
        actions.login(email, is_admin=True)
        response = self.get('dashboard?action=peer_review')
        actions.assert_contains(
            'Google &gt; Dashboard &gt; Manage &gt; Peer review',
            response.body)
        actions.assert_contains('have not been calculated yet', response.body)

        response = response.forms['gcb-generate-analytics-data'].submit(
        ).follow()
        assert len(self.taskq.GetTasks('default')) == 1

        actions.assert_contains('is running', response.body)

        self.execute_all_deferred_tasks()

        response = self.get(response.request.url)
        actions.assert_contains('were last updated at', response.body)
        actions.assert_contains('Peer review', response.body)
        actions.assert_contains('Sample peer review assignment', response.body)
        # JSON code for the completion statistics.
        actions.assert_contains('"[{\\"stats\\": [2]', response.body)
        actions.logout()

        # Student2 requests a review.
        actions.login(student2)
        response = actions.request_new_review(
            self, controllers_tests.LEGACY_REVIEW_UNIT_ID)
        review_step_key_2_for_1 = controllers_tests.get_review_step_key(
            response)
        actions.assert_contains('Assignment to review', response.body)

        # Student2 submits the review.
        response = actions.submit_review(
            self, controllers_tests.LEGACY_REVIEW_UNIT_ID,
            review_step_key_2_for_1,
            controllers_tests.get_review_payload('R2for1'))
        actions.assert_contains('Your review has been submitted successfully',
                                response.body)
        actions.logout()

        actions.login(email, is_admin=True)
        response = self.get('dashboard?action=peer_review')
        actions.assert_contains(
            'Google &gt; Dashboard &gt; Manage &gt; Peer review',
            response.body)

        response = response.forms['gcb-generate-analytics-data'].submit(
        ).follow()
        self.execute_all_deferred_tasks()

        response = self.get(response.request.url)
        actions.assert_contains('Peer review', response.body)
        # JSON code for the completion statistics.
        actions.assert_contains('"[{\\"stats\\": [1, 1]', response.body)
        actions.logout()
    def test_add_reviewer(self):
        """Test that admin can add a reviewer, and cannot re-add reviewers."""

        email = '*****@*****.**'
        name = 'Test Add Reviewer'
        submission = transforms.dumps([
            {
                'index': 0,
                'type': 'regex',
                'value': 'First answer to Q1',
                'correct': True
            },
            {
                'index': 1,
                'type': 'choices',
                'value': 3,
                'correct': False
            },
            {
                'index': 2,
                'type': 'regex',
                'value': 'First answer to Q3',
                'correct': True
            },
        ])
        payload = {
            'answers': submission,
            'assessment_type': LEGACY_REVIEW_UNIT_ID
        }

        actions.login(email)
        actions.register(self, name)
        response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID,
                                             payload)

        # There is nothing to review on the review dashboard.
        response = actions.request_new_review(self,
                                              LEGACY_REVIEW_UNIT_ID,
                                              expected_status_code=200)
        actions.assert_does_not_contain('Assignment to review', response.body)
        actions.assert_contains('Sorry, there are no new submissions ',
                                response.body)
        actions.logout()

        # The admin assigns the student to review his own work.
        actions.login(email, is_admin=True)
        response = actions.add_reviewer(self, LEGACY_REVIEW_UNIT_ID, email,
                                        email)
        actions.assert_equals(response.status_int, 302)
        response = self.get(response.location)
        actions.assert_does_not_contain(
            'Error 412: The reviewer is already assigned', response.body)
        actions.assert_contains('First answer to Q1', response.body)
        actions.assert_contains('Review 1 from [email protected]',
                                response.body)

        # The admin repeats the 'add reviewer' action. This should fail.
        response = actions.add_reviewer(self, LEGACY_REVIEW_UNIT_ID, email,
                                        email)
        actions.assert_equals(response.status_int, 302)
        response = self.get(response.location)
        actions.assert_contains('Error 412: The reviewer is already assigned',
                                response.body)