def setUp(self):
        super(PeerReviewDashboardStudentTest, self).setUp()
        self.base = '/' + self.COURSE_NAME
        context = actions.simple_add_course(
            self.COURSE_NAME, '*****@*****.**', 'Peer Back Button Child')
        self.course = courses.Course(None, context)

        self.assessment = self.course.add_assessment()
        self.assessment.title = 'Assessment'
        self.assessment.html_content = 'assessment content'
        self.assessment.workflow_yaml = (
            '{grader: human,'
            'matcher: peer,'
            'review_due_date: \'2034-07-01 12:00\','
            'review_min_count: 1,'
            'review_window_mins: 20,'
            'submission_due_date: \'2034-07-01 12:00\'}')
        self.assessment.now_available = True

        self.course.save()
        actions.login(self.STUDENT_EMAIL)
        actions.register(self, self.STUDENT_EMAIL)

        actions.submit_assessment(
            self,
            self.assessment.unit_id,
            {'answers': '', 'score': 0,
             'assessment_type': self.assessment.unit_id},
            presubmit_checks=False
        )
Пример #2
0
    def test_registration_closed(self):
        """Test student registration when course is full."""

        email = '*****@*****.**'
        name = 'Test Registration Closed'

        # 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['reg_form']['can_register'] = False
            return environ

        sites.ApplicationContext.get_environ = get_environ_new

        # Try to login and register.
        actions.login(email)
        try:
            actions.register(self, name)
            raise actions.ShouldHaveFailedByNow(
                'Expected to fail: new registrations should not be allowed '
                'when registration is closed.')
        except actions.ShouldHaveFailedByNow as e:
            raise e
        except:
            pass

        # Clean up app_context.
        sites.ApplicationContext.get_environ = get_environ_old
    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)
        assert_equals(response.status_int, 200)
        assert_contains('Due date for this assignment', response.body)
        assert_contains(
            'After you have completed the required number of peer reviews',
            response.body)

        actions.logout()
Пример #4
0
    def test_multiple_course(self):
        """Tests when multiple courses are available."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        name = 'Test completed course'
        email = 'Student'

        # Make the course available.
        get_environ_old = sites.ApplicationContext.get_environ

        def get_environ_new(self):
            environ = get_environ_old(self)
            environ['course']['now_available'] = True
            return environ

        sites.ApplicationContext.get_environ = get_environ_new

        actions.login(email)
        actions.register(self, name)
        response = self.get('/explorer/courses')
        # Assert if 'View course list' text is shown on my course page.
        assert_contains('View course list', response.body)

        # Clean up app_context.
        sites.ApplicationContext.get_environ = get_environ_old
        sites.reset_courses()
    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)
        assert_does_not_contain('Assignment to review', response.body)
        assert_contains('Sorry, there are no new submissions ', response.body)
        assert_contains('disabled="true"', response.body)

        actions.logout()
Пример #6
0
    def test_attempt_activity_event(self):
        """Test activity attempt generates event."""

        email = '*****@*****.**'
        name = 'Test Attempt Activity Event'

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

        # Enable event recording.
        config.Registry.db_overrides[
            lessons.CAN_PERSIST_ACTIVITY_EVENTS.name] = True

        # Prepare event.
        request = {}
        request['source'] = 'test-source'
        request['payload'] = json.dumps({'Alice': 'Bob'})

        # Check XSRF token is required.
        response = self.post('rest/events?%s' % urllib.urlencode(
            {'request': json.dumps(request)}), {})
        assert_equals(response.status_int, 200)
        assert_contains('"status": 403', response.body)

        # Check PUT works.
        request['xsrf_token'] = XsrfTokenManager.create_xsrf_token(
            'event-post')
        response = self.post('rest/events?%s' % urllib.urlencode(
            {'request': json.dumps(request)}), {})
        assert_equals(response.status_int, 200)
        assert not response.body

        # Clean up.
        config.Registry.db_overrides = {}
    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)
        assert_equals(response.status_int, 200)
        assert_contains("Due date for this assignment", response.body)
        assert_contains("After you have completed the required number of peer reviews", response.body)

        actions.logout()
    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)
        assert_does_not_contain("Assignment to review", response.body)
        assert_contains("Sorry, there are no new submissions ", response.body)
        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)
        assert_equals(response.status_int, 200)
        assert_contains('Due date for this assignment', response.body)
        assert_contains(
            'After you have completed the required number of peer reviews',
            response.body)

        actions.logout()
Пример #10
0
    def test_manage_announcements(self):
        """Test course author can manage announcements."""
        email = '*****@*****.**'
        name = 'Test Announcements'

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

        # add new
        response = actions.view_announcements(self)
        add_form = response.forms['gcb-add-announcement']
        response = self.submit(add_form)
        assert_equals(response.status_int, 302)

        # check added
        response = actions.view_announcements(self)
        assert_contains('Sample Announcement (Draft)', response.body)

        # delete draft
        response = actions.view_announcements(self)
        delete_form = response.forms['gcb-delete-announcement-1']
        response = self.submit(delete_form)
        assert_equals(response.status_int, 302)

        # check deleted
        assert_does_not_contain('Welcome to the final class!', response.body)
Пример #11
0
    def setUp(self):
        super(CertificateCriteriaTestCase, self).setUp()

        self.base = '/' + self.COURSE_NAME
        context = actions.simple_add_course(self.COURSE_NAME, self.ADMIN_EMAIL,
                                            'Certificate Criteria')

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

        self.course = courses.Course(None, context)
        self.course.save()
        actions.login(self.STUDENT_EMAIL)
        actions.register(self, self.STUDENT_EMAIL)
        self.student = (
            models.StudentProfileDAO.get_enrolled_student_by_email_for(
                self.STUDENT_EMAIL, context))

        # Override course.yaml settings by patching app_context.
        self.get_environ_old = sites.ApplicationContext.get_environ
        self.certificate_criteria = []

        def get_environ_new(app_context):
            environ = self.get_environ_old(app_context)
            environ['certificate_criteria'] = self.certificate_criteria
            return environ

        sites.ApplicationContext.get_environ = get_environ_new
    def setUp(self):
        super(CertificateCriteriaTestCase, self).setUp()

        self.base = '/' + self.COURSE_NAME
        context = actions.simple_add_course(
            self.COURSE_NAME, self.ADMIN_EMAIL, 'Certificate Criteria')

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

        self.course = courses.Course(None, context)
        self.course.save()
        actions.login(self.STUDENT_EMAIL)
        actions.register(self, self.STUDENT_EMAIL)
        self.student = (
            models.StudentProfileDAO.get_enrolled_student_by_email_for(
                self.STUDENT_EMAIL, context))

        # Override course.yaml settings by patching app_context.
        self.get_environ_old = sites.ApplicationContext.get_environ
        self.certificate_criteria = []

        def get_environ_new(app_context):
            environ = self.get_environ_old(app_context)
            environ['certificate_criteria'] = self.certificate_criteria
            return environ

        sites.ApplicationContext.get_environ = get_environ_new
Пример #13
0
    def test_single_completed_course(self):
        """Tests when a single completed course is present."""
        user = self.make_test_user('*****@*****.**')
        name = 'Test Assessments'

        # Register.
        actions.login(user.email())
        actions.register(self, name)

        response = self.get('/explorer')
        # Before a course is not completed,
        # explorer page should not show 'view score' button.
        assert_does_not_contain('View score', response.body)

        # Assign a grade to the course enrolled to mark it complete.
        profile = PersonalProfile.get_by_key_name(user.user_id())
        info = {'final_grade': 'A'}
        course_info_dict = {'': info}
        profile.course_info = transforms.dumps(course_info_dict)
        profile.put()

        # Check if 'View score' text is visible on profile page.
        response = self.get('/explorer/profile')
        assert_contains('View score', response.body)

        # Check if 'Go to course' button is not visible on explorer page.
        response = self.get('/explorer')
        assert_does_not_contain('Go to course', response.body)

        # Check if 'View score' button is visible on explorer page.
        response = self.get('/explorer')
        assert_contains('View score', 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)
        assert_does_not_contain('Assignment to review', response.body)
        assert_contains('Sorry, there are no new submissions ', response.body)
        assert_contains('disabled="true"', response.body)

        actions.logout()
Пример #15
0
    def test_multiple_course(self):
        """Tests when multiple courses are available."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        name = 'Test completed course'
        email = 'Student'

        # Make the course available.
        get_environ_old = sites.ApplicationContext.get_environ

        def get_environ_new(self):
            environ = get_environ_old(self)
            environ['course']['now_available'] = True
            return environ

        sites.ApplicationContext.get_environ = get_environ_new

        actions.login(email)
        actions.register(self, name)
        response = self.get('/explorer/courses')
        # Assert if 'View course list' text is shown on my course page.
        assert_contains('View course list', response.body)

        # Clean up app_context.
        sites.ApplicationContext.get_environ = get_environ_old
        sites.reset_courses()
Пример #16
0
    def setUp(self):
        super(PeerReviewDashboardStudentTest, self).setUp()
        self.base = '/' + self.COURSE_NAME
        context = actions.simple_add_course(self.COURSE_NAME, '*****@*****.**',
                                            'Peer Back Button Child')
        self.course = courses.Course(None, context)

        self.assessment = self.course.add_assessment()
        self.assessment.title = 'Assessment'
        self.assessment.html_content = 'assessment content'
        self.assessment.workflow_yaml = (
            '{grader: human,'
            'matcher: peer,'
            'review_due_date: \'2034-07-01 12:00\','
            'review_min_count: 1,'
            'review_window_mins: 20,'
            'submission_due_date: \'2034-07-01 12:00\'}')
        self.assessment.now_available = True

        self.course.save()
        actions.login(self.STUDENT_EMAIL)
        actions.register(self, self.STUDENT_EMAIL)
        config.Registry.test_overrides[
            utils.CAN_PERSIST_ACTIVITY_EVENTS.name] = True

        actions.submit_assessment(
            self,
            self.assessment.unit_id, {
                'answers': '',
                'score': 0,
                'assessment_type': self.assessment.unit_id
            },
            presubmit_checks=False)
Пример #17
0
    def test_single_completed_course(self):
        """Tests when a single completed course is present."""
        email = '*****@*****.**'
        name = 'Test Assessments'

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

        response = self.get('/explorer')
        # Before a course is not completed,
        # explorer page should not show 'view score' button.
        assert_does_not_contain('View score', response.body)

        # Assign a grade to the course enrolled to mark it complete.
        profile = PersonalProfile.get_by_key_name(email)
        info = {'final_grade': 'A'}
        course_info_dict = {'': info}
        profile.course_info = transforms.dumps(course_info_dict)
        profile.put()

        # Check if 'View score' text is visible on profile page.
        response = self.get('/explorer/profile')
        assert_contains('View score', response.body)

        # Check if 'Go to course' button is not visible on explorer page.
        response = self.get('/explorer')
        assert_does_not_contain('Go to course', response.body)

        # Check if 'View score' button is visible on explorer page.
        response = self.get('/explorer')
        assert_contains('View score', response.body)
Пример #18
0
    def test_manage_announcements(self):
        """Test course author can manage announcements."""
        email = '*****@*****.**'
        name = 'Test Announcements'

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

        # add new
        response = actions.view_announcements(self)
        add_form = response.forms['gcb-add-announcement']
        response = self.submit(add_form)
        assert_equals(response.status_int, 302)

        # check added
        response = actions.view_announcements(self)
        assert_contains('Sample Announcement (Draft)', response.body)

        # delete draft
        response = actions.view_announcements(self)
        delete_form = response.forms['gcb-delete-announcement-1']
        response = self.submit(delete_form)
        assert_equals(response.status_int, 302)

        # check deleted
        assert_does_not_contain('Welcome to the final class!', response.body)
Пример #19
0
    def test_registration_closed(self):
        """Test student registration when course is full."""

        email = '*****@*****.**'
        name = 'Test Registration Closed'

        # 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['reg_form']['can_register'] = False
            return environ

        sites.ApplicationContext.get_environ = get_environ_new

        # Try to ogin and register.
        actions.login(email)
        try:
            actions.register(self, name)
            raise actions.MustFail('Expected to fail.')
        except actions.MustFail as e:
            raise e
        except:
            pass

        # Clean up app_context.
        sites.ApplicationContext.get_environ = get_environ_old
    def test_tracked_lessons(self):
        context = actions.simple_add_course('test', '*****@*****.**',
                                            'Test Course')
        course = courses.Course(None, context)
        actions.login('*****@*****.**')
        actions.register(self, 'Some Admin', 'test')

        with common_utils.Namespace('ns_test'):
            foo_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Foo',
                       'descripton': 'foo',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            bar_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Bar',
                       'descripton': 'bar',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))

        unit1 = course.add_unit()
        unit1.now_available = True
        unit1.labels = str(foo_id)
        lesson11 = course.add_lesson(unit1)
        lesson11.objectives = 'common plugh <gcb-youtube videoid="glados">'
        lesson11.now_available = True
        lesson11.notes = search_unit_test.VALID_PAGE_URL
        lesson11.video = 'portal'
        course.update_unit(unit1)
        unit2 = course.add_unit()
        unit2.now_available = True
        unit1.labels = str(bar_id)
        lesson21 = course.add_lesson(unit2)
        lesson21.objectives = 'common plover'
        lesson21.now_available = True
        course.update_unit(unit2)
        course.save()
        self.index_test_course()

        # Registered, un-tracked student sees all.
        response = self.get('/test/search?query=common')
        self.assertIn('common', response.body)
        self.assertIn('plugh', response.body)
        self.assertIn('plover', response.body)
        response = self.get('/test/search?query=link')  # Do see followed links
        self.assertIn('Partial', response.body)
        self.assertIn('Absolute', response.body)
        response = self.get('/test/search?query=lemon')  # Do see video refs
        self.assertIn('v=glados', response.body)

        # Student with tracks sees filtered view.
        with common_utils.Namespace('ns_test'):
            models.Student.set_labels_for_current(str(foo_id))
        response = self.get('/test/search?query=common')
        self.assertIn('common', response.body)
        self.assertNotIn('plugh', response.body)
        self.assertIn('plover', response.body)
        response = self.get('/test/search?query=link')  # Links are filtered
        self.assertNotIn('Partial', response.body)
        self.assertNotIn('Absolute', response.body)
        response = self.get('/test/search?query=lemon')  # Don't see video refs
        self.assertNotIn('v=glados', response.body)
    def test_student_progress_stats_analytics_displays_on_dashboard(self):
        """Test analytics page on course dashboard."""

        with actions.OverriddenEnvironment(
            {'course': {
                analytics.CAN_RECORD_STUDENT_EVENTS: 'true'
            }}):

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

            # Student 1 completes a unit.
            actions.login(student1)
            actions.register(self, name1)
            actions.view_unit(self)
            actions.logout()

            # Student 2 completes a unit.
            actions.login(student2)
            actions.register(self, name2)
            actions.view_unit(self)
            actions.logout()

            # Admin logs back in and checks if progress exists.
            email = '*****@*****.**'
            actions.login(email, is_admin=True)
            response = self.get('dashboard?action=analytics_students')
            assert_contains('Google &gt; Dashboard &gt; Manage &gt; Students',
                            response.body)
            assert_contains('have not been calculated yet', response.body)

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

            response = self.get('dashboard?action=analytics_students')
            assert_contains('is running', response.body)

            self.execute_all_deferred_tasks()

            response = self.get('dashboard?action=analytics_students')
            assert_contains('were last updated at', response.body)
            assert_contains('currently enrolled: 2', response.body)
            assert_contains('total: 2', response.body)

            assert_contains('Student Progress', response.body)
            assert_does_not_contain(
                'No student progress has been recorded for this course.',
                response.body)
            # JSON code for the completion statistics.
            assert_contains(
                '\\"u.1.l.1\\": {\\"progress\\": 0, \\"completed\\": 2}',
                response.body)
            assert_contains(
                '\\"u.1\\": {\\"progress\\": 2, \\"completed\\": 0}',
                response.body)
Пример #22
0
    def test_tracked_lessons(self):
        context = actions.simple_add_course('test', '*****@*****.**',
                                            'Test Course')
        course = courses.Course(None, context)
        actions.login('*****@*****.**')
        actions.register(self, 'Some Admin', 'test')

        with common_utils.Namespace('ns_test'):
            foo_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Foo',
                       'descripton': 'foo',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            bar_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Bar',
                       'descripton': 'bar',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))

        unit1 = course.add_unit()
        unit1.now_available = True
        unit1.labels = str(foo_id)
        lesson11 = course.add_lesson(unit1)
        lesson11.objectives = 'common plugh <gcb-youtube videoid="glados">'
        lesson11.now_available = True
        lesson11.notes = search_unit_test.VALID_PAGE_URL
        lesson11.video = 'portal'
        course.update_unit(unit1)
        unit2 = course.add_unit()
        unit2.now_available = True
        unit1.labels = str(bar_id)
        lesson21 = course.add_lesson(unit2)
        lesson21.objectives = 'common plover'
        lesson21.now_available = True
        course.update_unit(unit2)
        course.save()
        self.index_test_course()

        # Registered, un-tracked student sees all.
        response = self.get('/test/search?query=common')
        self.assertIn('common', response.body)
        self.assertIn('plugh', response.body)
        self.assertIn('plover', response.body)
        response = self.get('/test/search?query=link')  # Do see followed links
        self.assertIn('Partial', response.body)
        self.assertIn('Absolute', response.body)
        response = self.get('/test/search?query=lemon')  # Do see video refs
        self.assertIn('v=glados', response.body)

        # Student with tracks sees filtered view.
        with common_utils.Namespace('ns_test'):
            models.Student.set_labels_for_current(str(foo_id))
        response = self.get('/test/search?query=common')
        self.assertIn('common', response.body)
        self.assertNotIn('plugh', response.body)
        self.assertIn('plover', response.body)
        response = self.get('/test/search?query=link')  # Links are filtered
        self.assertNotIn('Partial', response.body)
        self.assertNotIn('Absolute', response.body)
        response = self.get('/test/search?query=lemon')  # Don't see video refs
        self.assertNotIn('v=glados', response.body)
Пример #23
0
    def test_student_progress_stats_analytics_displays_on_dashboard(self):
        """Test analytics page on course dashboard."""

        self.enable_progress_tracking()

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

        # Student 1 completes a unit.
        actions.login(student1)
        actions.register(self, name1)
        actions.view_unit(self)
        actions.logout()

        # Student 2 completes a unit.
        actions.login(student2)
        actions.register(self, name2)
        actions.view_unit(self)
        actions.logout()

        # Admin logs back in and checks if progress exists.
        email = '*****@*****.**'
        actions.login(email, is_admin=True)
        response = self.get('dashboard?action=analytics')
        assert_contains(
            'Google &gt;<a href="%s"> Dashboard </a>&gt; Analytics' %
                self.canonicalize('dashboard'),
            response.body)
        assert_contains('have not been calculated yet', response.body)

        compute_form = response.forms['gcb-compute-student-stats']
        response = self.submit(compute_form)
        assert_equals(response.status_int, 302)
        assert len(self.taskq.GetTasks('default')) == 5

        response = self.get('dashboard?action=analytics')
        assert_contains('is running', response.body)

        self.execute_all_deferred_tasks()

        response = self.get('dashboard?action=analytics')
        assert_contains('were last updated at', response.body)
        assert_contains('currently enrolled: 2', response.body)
        assert_contains('total: 2', response.body)

        assert_contains('Student Progress Statistics', response.body)
        assert_does_not_contain(
            'No student progress has been recorded for this course.',
            response.body)
        # JSON code for the completion statistics.
        assert_contains(
            '\\"u.1.l.1\\": {\\"progress\\": 0, \\"completed\\": 2}',
            response.body)
        assert_contains(
            '\\"u.1\\": {\\"progress\\": 2, \\"completed\\": 0}',
            response.body)
Пример #24
0
    def test_student_progress_stats_analytics_displays_on_dashboard(self):
        """Test analytics page on course dashboard."""

        with actions.OverriddenEnvironment(
            {'course': {analytics.CAN_RECORD_STUDENT_EVENTS: 'true'}}):

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

            # Student 1 completes a unit.
            actions.login(student1)
            actions.register(self, name1)
            actions.view_unit(self)
            actions.logout()

            # Student 2 completes a unit.
            actions.login(student2)
            actions.register(self, name2)
            actions.view_unit(self)
            actions.logout()

            # Admin logs back in and checks if progress exists.
            email = '*****@*****.**'
            actions.login(email, is_admin=True)
            response = self.get('dashboard?action=analytics_students')
            assert_contains(
                'Google &gt; Dashboard &gt; Manage &gt; Students',
                response.body)
            assert_contains('have not been calculated yet', response.body)

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

            response = self.get('dashboard?action=analytics_students')
            assert_contains('is running', response.body)

            self.execute_all_deferred_tasks()

            response = self.get('dashboard?action=analytics_students')
            assert_contains('were last updated at', response.body)
            assert_contains('currently enrolled: 2', response.body)
            assert_contains('total: 2', response.body)

            assert_contains('Student Progress', response.body)
            assert_does_not_contain(
                'No student progress has been recorded for this course.',
                response.body)
            # JSON code for the completion statistics.
            assert_contains(
                '\\"u.1.l.1\\": {\\"progress\\": 0, \\"completed\\": 2}',
                response.body)
            assert_contains(
                '\\"u.1\\": {\\"progress\\": 2, \\"completed\\": 0}',
                response.body)
Пример #25
0
    def test_student_progress_stats_analytics_displays_on_dashboard(self):
        """Test analytics page on course dashboard."""

        self.enable_progress_tracking()

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

        # Student 1 completes a unit.
        actions.login(student1)
        actions.register(self, name1)
        actions.view_unit(self)
        actions.logout()

        # Student 2 completes a unit.
        actions.login(student2)
        actions.register(self, name2)
        actions.view_unit(self)
        actions.logout()

        # Admin logs back in and checks if progress exists.
        email = '*****@*****.**'
        actions.login(email, is_admin=True)
        response = self.get('dashboard?action=analytics')
        assert_contains(
            'Google &gt; Dashboard &gt; Analytics', response.body)
        assert_contains('have not been calculated yet', response.body)

        compute_form = response.forms['gcb-compute-student-stats']
        response = self.submit(compute_form)
        assert_equals(response.status_int, 302)
        assert len(self.taskq.GetTasks('default')) == 4

        response = self.get('dashboard?action=analytics')
        assert_contains('is running', response.body)

        self.execute_all_deferred_tasks()

        response = self.get('dashboard?action=analytics')
        assert_contains('were last updated at', response.body)
        assert_contains('currently enrolled: 2', response.body)
        assert_contains('total: 2', response.body)

        assert_contains('Student Progress Statistics', response.body)
        assert_does_not_contain(
            'No student progress has been recorded for this course.',
            response.body)
        # JSON code for the completion statistics.
        assert_contains(
            '\\"u.1.l.1\\": {\\"progress\\": 0, \\"completed\\": 2}',
            response.body)
        assert_contains(
            '\\"u.1\\": {\\"progress\\": 2, \\"completed\\": 0}',
            response.body)
Пример #26
0
    def test_announcements_rest(self):
        """Test REST access to announcements."""
        email = '*****@*****.**'
        name = 'Test Announcements Rest'

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

        response = actions.view_announcements(self)
        assert_does_not_contain('My Test Title', response.body)

        # REST GET existing item
        items = AnnouncementEntity.all().fetch(1)
        for item in items:
            response = self.get('rest/announcements/item?key=%s' % item.key())
            json_dict = json.loads(response.body)
            assert json_dict['status'] == 200
            assert 'message' in json_dict
            assert 'payload' in json_dict

            payload_dict = json.loads(json_dict['payload'])
            assert 'title' in payload_dict
            assert 'date' in payload_dict

            # REST PUT item
            payload_dict['title'] = u'My Test Title Мой заголовок теста'
            payload_dict['date'] = '2012/12/31'
            payload_dict['is_draft'] = True
            request = {}
            request['key'] = str(item.key())
            request['payload'] = json.dumps(payload_dict)

            # Check XSRF is required.
            response = self.put('rest/announcements/item?%s' % urllib.urlencode(
                {'request': json.dumps(request)}), {})
            assert_equals(response.status_int, 200)
            assert_contains('"status": 403', response.body)

            # Check PUT works.
            request['xsrf_token'] = json_dict['xsrf_token']
            response = self.put('rest/announcements/item?%s' % urllib.urlencode(
                {'request': json.dumps(request)}), {})
            assert_equals(response.status_int, 200)
            assert_contains('"status": 200', response.body)

            # Confirm change is visible on the page.
            response = self.get('announcements')
            assert_contains(
                u'My Test Title Мой заголовок теста (Draft)', response.body)

        # REST GET not-existing item
        response = self.get('rest/announcements/item?key=not_existent_key')
        json_dict = json.loads(response.body)
        assert json_dict['status'] == 404
Пример #27
0
    def test_trigger_sample_announcements(self):
        """Test course author can trigger adding sample announcements."""
        email = '*****@*****.**'
        name = 'Test Announcements'

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

        response = actions.view_announcements(self)
        assert_contains('Example Announcement', response.body)
        assert_contains('Welcome to the final class!', response.body)
        assert_does_not_contain('No announcements yet.', response.body)
Пример #28
0
    def test_trigger_sample_announcements(self):
        """Test course author can trigger adding sample announcements."""
        email = '*****@*****.**'
        name = 'Test Announcements'

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

        response = actions.view_announcements(self)
        assert_contains('Example Announcement', response.body)
        assert_contains('Welcome to the final class!', response.body)
        assert_does_not_contain('No announcements yet.', response.body)
Пример #29
0
    def test_permissions(self):
        """Test student permissions, and which pages they can view."""
        email = '*****@*****.**'
        name = 'Test Permissions'

        actions.login(email)

        actions.register(self, name)
        actions.Permissions.assert_enrolled(self)

        actions.unregister(self)
        actions.Permissions.assert_unenrolled(self)

        actions.register(self, name)
        actions.Permissions.assert_enrolled(self)
Пример #30
0
    def test_xsrf_defence(self):
        """Test defense against XSRF attack."""

        email = '*****@*****.**'
        name = 'Test Xsrf Defence'

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

        response = self.get('student/home')
        response.form.set('name', 'My New Name')
        response.form.set('xsrf_token', 'bad token')

        response = response.form.submit(expect_errors=True)
        assert_equals(response.status_int, 403)
Пример #31
0
    def setUp(self):
        super(CronCleanupTest, self).setUp()
        admin_email = '*****@*****.**'
        self.course_one = actions.simple_add_course(
            COURSE_ONE, admin_email, 'Course One')
        self.course_two = actions.simple_add_course(
            COURSE_TWO, admin_email, 'Course Two')

        actions.login(admin_email, True)
        actions.register(self, admin_email, COURSE_ONE)
        actions.register(self, admin_email, COURSE_TWO)

        self.save_tz = os.environ.get('TZ')
        os.environ['TZ'] = 'GMT'
        time.tzset()
Пример #32
0
    def test_permissions(self):
        """Test student permissions, and which pages they can view."""
        email = '*****@*****.**'
        name = 'Test Permissions'

        actions.login(email)

        actions.register(self, name)
        actions.Permissions.assert_enrolled(self)

        actions.unregister(self)
        actions.Permissions.assert_unenrolled(self)

        actions.register(self, name)
        actions.Permissions.assert_enrolled(self)
Пример #33
0
    def test_xsrf_defence(self):
        """Test defense against XSRF attack."""

        email = '*****@*****.**'
        name = 'Test Xsrf Defence'

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

        response = self.get('student/home')
        response.form.set('name', 'My New Name')
        response.form.set('xsrf_token', 'bad token')

        response = response.form.submit(expect_errors=True)
        assert_equals(response.status_int, 403)
    def setUp(self):
        super(CronCleanupTest, self).setUp()
        admin_email = '*****@*****.**'
        self.course_one = actions.simple_add_course(COURSE_ONE, admin_email,
                                                    'Course One')
        self.course_two = actions.simple_add_course(COURSE_TWO, admin_email,
                                                    'Course Two')

        actions.login(admin_email, True)
        actions.register(self, admin_email, COURSE_ONE)
        actions.register(self, admin_email, COURSE_TWO)

        self.save_tz = os.environ.get('TZ')
        os.environ['TZ'] = 'GMT'
        time.tzset()
    def test_course_explorer_disabled(self):
        """Tests for disabled course explorer page."""
        # This call should redirect to course page not explorer page.
        response = self.get('/')
        assert_contains('/course', response.location)

        name = 'Test explorer page off'
        email = 'student'

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

        response = self.get('/course')
        # 'My courses' and 'Profile' tab should not be present in tab bar.
        assert_does_not_contain('My Courses', response.body)
        assert_does_not_contain('Profile', response.body)
Пример #36
0
    def test_registration(self):
        """Test student registration."""
        email = '*****@*****.**'
        name1 = 'Test Student'
        name2 = 'John Smith'
        name3 = u'Pavel Simakov (тест данные)'

        actions.login(email)

        actions.register(self, name1)
        actions.check_profile(self, name1)

        actions.change_name(self, name2)
        actions.unregister(self)

        actions.register(self, name3)
        actions.check_profile(self, name3)
Пример #37
0
    def test_course_explorer_disabled(self):
        """Tests for disabled course explorer page."""
        # This call should redirect to course page not explorer page.
        response = self.get('/')
        assert_contains('/course', response.location)

        name = 'Test explorer page off'
        email = 'student'

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

        response = self.get('/course')
        # 'My courses' and 'Profile' tab should not be present in tab bar.
        assert_does_not_contain('My Courses', response.body)
        assert_does_not_contain('Profile', response.body)
Пример #38
0
    def test_registration(self):
        """Test student registration."""
        email = '*****@*****.**'
        name1 = 'Test Student'
        name2 = 'John Smith'
        name3 = 'Pavel Simakov'

        actions.login(email)

        actions.register(self, name1)
        actions.check_profile(self, name1)

        actions.change_name(self, name2)
        actions.unregister(self)

        actions.register(self, name3)
        actions.check_profile(self, name3)
    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)
        assert_does_not_contain('Assignment to review', response.body)
        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)
        assert_equals(response.status_int, 302)
        response = self.get(response.location)
        assert_does_not_contain(
            'Error 412: The reviewer is already assigned', response.body)
        assert_contains('First answer to Q1', response.body)
        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)
        assert_equals(response.status_int, 302)
        response = self.get(response.location)
        assert_contains(
            'Error 412: The reviewer is already assigned', response.body)
    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)
        assert_does_not_contain('Assignment to review', response.body)
        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)
        assert_equals(response.status_int, 302)
        response = self.get(response.location)
        assert_does_not_contain(
            'Error 412: The reviewer is already assigned', response.body)
        assert_contains('First answer to Q1', response.body)
        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)
        assert_equals(response.status_int, 302)
        response = self.get(response.location)
        assert_contains(
            'Error 412: The reviewer is already assigned', response.body)
Пример #41
0
    def test_attempt_activity_event(self):
        """Test activity attempt generates event."""

        email = '*****@*****.**'
        name = 'Test Attempt Activity Event'

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

        # Enable event recording.
        config.Registry.db_overrides[
            lessons.CAN_PERSIST_ACTIVITY_EVENTS.name] = True

        # Prepare event.
        request = {}
        request['source'] = 'test-source'
        request['payload'] = json.dumps({'Alice': u'Bob (тест данные)'})

        # Check XSRF token is required.
        response = self.post('rest/events?%s' % urllib.urlencode(
            {'request': json.dumps(request)}), {})
        assert_equals(response.status_int, 200)
        assert_contains('"status": 403', response.body)

        # Check PUT works.
        request['xsrf_token'] = XsrfTokenManager.create_xsrf_token(
            'event-post')
        response = self.post('rest/events?%s' % urllib.urlencode(
            {'request': json.dumps(request)}), {})
        assert_equals(response.status_int, 200)
        assert not response.body

        # Check event is properly recorded.
        old_namespace = namespace_manager.get_namespace()
        namespace_manager.set_namespace(self.namespace)
        try:
            events = models.EventEntity.all().fetch(1000)
            assert 1 == len(events)
            assert_contains(
                u'Bob (тест данные)', json.loads(events[0].data)['Alice'])
        finally:
            namespace_manager.set_namespace(old_namespace)

        # Clean up.
        config.Registry.db_overrides = {}
Пример #42
0
    def test_single_uncompleted_course(self):
        """Tests for a single available course."""
        # This call should redirect to explorer page.
        response = self.get('/')
        assert_contains('/explorer', response.location)

        name = 'Test student courses page'
        email = 'Student'

        actions.login(email)

        # Test the explorer page.
        response = self.get('/explorer')
        assert_equals(response.status_int, 200)
        assert_contains('Register', response.body)

        # Navbar should not contain profile tab.
        assert_does_not_contain('<a href="/explorer/profile">Profile</a>',
                                response.body)

        # Test 'my courses' page when a student is not enrolled in any course.
        response = self.get('/explorer/courses')
        assert_equals(response.status_int, 200)
        assert_contains('You are not currently enrolled in any course',
                        response.body)

        # Test 'my courses' page when a student is enrolled in all courses.
        actions.register(self, name)
        response = self.get('/explorer/courses')
        assert_equals(response.status_int, 200)
        assert_contains('Go to course', response.body)
        assert_does_not_contain('You are not currently enrolled in any course',
                                response.body)

        # After the student registers for a course,
        # profile tab should be visible in navbar.
        assert_contains('<a href="/explorer/profile">Profile</a>',
                        response.body)

        # Test profile page.
        response = self.get('/explorer/profile')
        assert_contains('<td>%s</td>' % email, response.body)
        assert_contains('<td>%s</td>' % name, response.body)
        assert_contains('Progress', response.body)
        assert_does_not_contain('View score', response.body)
Пример #43
0
    def test_single_uncompleted_course(self):
        """Tests for a single available course."""
        # This call should redirect to explorer page.
        response = self.get('/')
        assert_contains('/explorer', response.location)

        name = 'Test student courses page'
        email = 'Student'

        actions.login(email)

        # Test the explorer page.
        response = self.get('/explorer')
        assert_equals(response.status_int, 200)
        assert_contains('Register', response.body)

        # Navbar should not contain profile tab.
        assert_does_not_contain(
            '<a href="/explorer/profile">Profile</a>', response.body)

        # Test 'my courses' page when a student is not enrolled in any course.
        response = self.get('/explorer/courses')
        assert_equals(response.status_int, 200)
        assert_contains('You are not currently enrolled in any course',
                        response.body)

        # Test 'my courses' page when a student is enrolled in all courses.
        actions.register(self, name)
        response = self.get('/explorer/courses')
        assert_equals(response.status_int, 200)
        assert_contains('Go to course', response.body)
        assert_does_not_contain('You are not currently enrolled in any course',
                                response.body)

        # After the student registers for a course,
        # profile tab should be visible in navbar.
        assert_contains(
            '<a href="/explorer/profile">Profile</a>', response.body)

        # Test profile page.
        response = self.get('/explorer/profile')
        assert_contains('<td>%s</td>' % email, response.body)
        assert_contains('<td>%s</td>' % name, response.body)
        assert_contains('Progress', response.body)
        assert_does_not_contain('View score', response.body)
Пример #44
0
    def test_lesson_activity_navigation(self):
        """Test navigation between lesson/activity pages."""

        email = '*****@*****.**'
        name = 'Test Lesson Activity Navigation'

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

        response = self.get('unit?unit=1&lesson=1')
        assert_does_not_contain('Previous Page', response.body)
        assert_contains('Next Page', response.body)

        response = self.get('unit?unit=2&lesson=3')
        assert_contains('Previous Page', response.body)
        assert_contains('Next Page', response.body)

        response = self.get('unit?unit=3&lesson=5')
        assert_contains('Previous Page', response.body)
        assert_does_not_contain('Next Page', response.body)
        assert_contains('End', response.body)
Пример #45
0
    def test_course_pass(self):
        """Test student passing final exam."""
        email = '*****@*****.**'
        name = 'Test Pass'

        post = {'assessment_type': 'postcourse', 'score': '100.00'}

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

        # Submit answer.
        response = self.submit_assessment('Post', post)
        assert_equals(response.status_int, 200)
        assert_contains('Your score is 70%', response.body)
        assert_contains('you have passed the course', response.body)

        # Check that the result shows up on the profile page.
        response = actions.check_profile(self, name)
        assert_contains('70', response.body)
        assert_contains('100', response.body)
    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()
Пример #47
0
    def test_lesson_activity_navigation(self):
        """Test navigation between lesson/activity pages."""

        email = '*****@*****.**'
        name = 'Test Lesson Activity Navigation'

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

        response = self.get('unit?unit=1&lesson=1')
        assert_does_not_contain('Previous Page', response.body)
        assert_contains('Next Page', response.body)

        response = self.get('unit?unit=2&lesson=3')
        assert_contains('Previous Page', response.body)
        assert_contains('Next Page', response.body)

        response = self.get('unit?unit=3&lesson=5')
        assert_contains('Previous Page', response.body)
        assert_does_not_contain('Next Page', response.body)
        assert_contains('End', response.body)
Пример #48
0
    def test_course_pass(self):
        """Test student passing final exam."""
        email = '*****@*****.**'
        name = 'Test Pass'

        post = {'assessment_type': 'postcourse', 'score': '100.00'}

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

        # Submit answer.
        response = self.submit_assessment('Post', post)
        assert_equals(response.status_int, 200)
        assert_contains('Your score is 70%', response.body)
        assert_contains('you have passed the course', response.body)

        # Check that the result shows up on the profile page.
        response = actions.check_profile(self, name)
        assert_contains('70', response.body)
        assert_contains('100', response.body)
Пример #49
0
    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_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()
Пример #51
0
    def test_access_to_admin_pages(self):
        """Test access to admin pages."""

        # assert anonymous user has no access
        response = self.testapp.get('/admin?action=settings')
        assert_equals(response.status_int, 302)

        # assert admin user has access
        email = '*****@*****.**'
        name = 'Test Access to Admin Pages'

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

        response = self.testapp.get('/admin')
        assert_contains('Power Searching with Google', response.body)
        assert_contains('All Courses', response.body)

        response = self.testapp.get('/admin?action=settings')
        assert_contains('gcb_admin_user_emails', response.body)
        assert_contains('gcb_config_update_interval_sec', response.body)
        assert_contains('All Settings', response.body)

        response = self.testapp.get('/admin?action=perf')
        assert_contains('gcb-admin-uptime-sec:', response.body)
        assert_contains('In-process Performance Counters', response.body)

        response = self.testapp.get('/admin?action=deployment')
        assert_contains('application_id: testbed-test', response.body)
        assert_contains('About the Application', response.body)

        actions.unregister(self)
        actions.logout()

        # assert not-admin user has no access
        actions.login(email)
        actions.register(self, name)
        response = self.testapp.get('/admin?action=settings')
        assert_equals(response.status_int, 302)
Пример #52
0
    def test_access_to_admin_pages(self):
        """Test access to admin pages."""

        # assert anonymous user has no access
        response = self.testapp.get('/admin?action=settings')
        assert_equals(response.status_int, 302)

        # assert admin user has access
        email = '*****@*****.**'
        name = 'Test Access to Admin Pages'

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

        response = self.testapp.get('/admin')
        assert_contains('Power Searching with Google', response.body)
        assert_contains('All Courses', response.body)

        response = self.testapp.get('/admin?action=settings')
        assert_contains('gcb_admin_user_emails', response.body)
        assert_contains('gcb_config_update_interval_sec', response.body)
        assert_contains('All Settings', response.body)

        response = self.testapp.get('/admin?action=perf')
        assert_contains('gcb-admin-uptime-sec:', response.body)
        assert_contains('In-process Performance Counters', response.body)

        response = self.testapp.get('/admin?action=deployment')
        assert_contains('application_id: testbed-test', response.body)
        assert_contains('About the Application', response.body)

        actions.unregister(self)
        actions.logout()

        # assert not-admin user has no access
        actions.login(email)
        actions.register(self, name)
        response = self.testapp.get('/admin?action=settings')
        assert_equals(response.status_int, 302)
    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)
        assert_does_not_contain("Assignment to review", response.body)
        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)
        assert_equals(response.status_int, 302)
        response = self.get(response.location)
        assert_does_not_contain("Error 412: The reviewer is already assigned", response.body)
        assert_contains("First answer to Q1", response.body)
        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)
        assert_equals(response.status_int, 302)
        response = self.get(response.location)
        assert_contains("Error 412: The reviewer is already assigned", response.body)
Пример #54
0
    def test_view_announcements(self):
        """Test student aspect of announcements."""
        email = '*****@*****.**'
        name = 'Test Announcements'

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

        # Check no announcements yet.
        response = actions.view_announcements(self)
        assert_does_not_contain('Example Announcement', response.body)
        assert_does_not_contain('Welcome to the final class!', response.body)
        assert_contains('No announcements yet.', response.body)
        actions.logout()

        # Login as admin and add announcements.
        actions.login('*****@*****.**', True)
        actions.register(self, 'admin')
        response = actions.view_announcements(self)
        actions.logout()

        # Check we can see non-draft announcements.
        actions.login(email)
        response = actions.view_announcements(self)
        assert_contains('Example Announcement', response.body)
        assert_does_not_contain('Welcome to the final class!', response.body)
        assert_does_not_contain('No announcements yet.', response.body)

        # Check no access to access to draft announcements via REST handler.
        items = AnnouncementEntity.all().fetch(1000)
        for item in items:
            response = self.get('rest/announcements/item?key=%s' % item.key())
            if item.is_draft:
                json_dict = json.loads(response.body)
                assert json_dict['status'] == 401
            else:
                assert_equals(response.status_int, 200)
Пример #55
0
    def test_two_students_dont_see_each_other_pages(self):
        """Test a user can't see another user pages."""
        email1 = '*****@*****.**'
        name1 = 'User 1'
        email2 = '*****@*****.**'
        name2 = 'User 2'

        # Login as one user and view 'unit' and other pages, which are not
        # cached.
        actions.login(email1)
        actions.register(self, name1)
        actions.Permissions.assert_enrolled(self)
        response = actions.view_unit(self)
        assert_contains(email1, response.body)
        actions.logout()

        # Login as another user and check that 'unit' and other pages show
        # the correct new email.
        actions.login(email2)
        actions.register(self, name2)
        actions.Permissions.assert_enrolled(self)
        response = actions.view_unit(self)
        assert_contains(email2, response.body)
        actions.logout()
Пример #56
0
def register():
    if request.method == "POST":
        username = request.form.get('username')
        password = request.form.get('password')
        try:
            if act.register(username, password):
                flash("Welcome {}, to your Personal Finance Assistant!".format(
                    username),
                      category="success")
                return redirect(url_for('dashboard'))
            else:
                flash("User Account already exists", category="danger")
                return redirect(url_for('index'))
        except Exception as e:
            flash("An error occurred: {}".format(str(e)), category="danger")
    else:
        flash("Invalid Action", category="danger")
    return redirect(url_for("index"))
Пример #57
0
    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)
        assert_equals(response.status_int, 200)
        assert_contains('Assignment to review', response.body)
        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)
        assert_equals(response.status_int, 200)
        assert_contains('Assignment to review', response.body)
        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))
        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))
        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))
        assert_contains('R1forFirst', response.body)

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

        # Student 1 logs out.
        actions.logout()
Пример #58
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=analytics')
        assert_contains(
            'Google &gt;<a href="%s"> Dashboard </a>&gt; Analytics' %
                self.canonicalize('dashboard'),
            response.body)
        assert_contains('have not been calculated yet', response.body)

        compute_form = response.forms['gcb-compute-student-stats']
        response = self.submit(compute_form)
        assert_equals(response.status_int, 302)
        assert len(self.taskq.GetTasks('default')) == 5

        response = self.get('dashboard?action=analytics')
        assert_contains('is running', response.body)

        self.execute_all_deferred_tasks()

        response = self.get('dashboard?action=analytics')
        assert_contains('were last updated at', response.body)
        assert_contains('currently enrolled: 2', response.body)
        assert_contains('total: 2', response.body)

        assert_contains('Peer Review Statistics', response.body)
        assert_contains('Sample peer review assignment', response.body)
        # JSON code for the completion statistics.
        assert_contains('"[{\\"stats\\": [2]', response.body)
        actions.logout()

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

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

        actions.login(email, is_admin=True)
        response = self.get('dashboard?action=analytics')
        assert_contains(
            'Google &gt;<a href="%s"> Dashboard </a>&gt; Analytics' %
                self.canonicalize('dashboard'),
            response.body)

        compute_form = response.forms['gcb-compute-student-stats']
        response = self.submit(compute_form)
        self.execute_all_deferred_tasks()

        response = self.get('dashboard?action=analytics')
        assert_contains('Peer Review Statistics', response.body)
        # JSON code for the completion statistics.
        assert_contains('"[{\\"stats\\": [1, 1]', response.body)
        actions.logout()