Ejemplo n.º 1
0
 def test_id_to_question_dict_constructed_correctly(self):
     """Tests id_to_question dicts are constructed correctly."""
     course = self._get_sample_v15_course()
     tracker = UnitLessonCompletionTracker(course)
     assert_equals(
         tracker.get_id_to_questions_dict(),
         {
             'u.1.l.2.c.QN': {
                 'answer_counts': [0],
                 'label': 'Unit 1 Lesson 1, Question mcq_new',
                 'location': 'unit?unit=1&lesson=2',
                 'num_attempts': 0,
                 'score': 0
             },
             'u.1.l.2.c.QG.i.0': {
                 'answer_counts': [0],
                 'label': ('Unit 1 Lesson 1, Question Group question_group '
                           'Question mcq_new'),
                 'location': 'unit?unit=1&lesson=2',
                 'num_attempts': 0,
                 'score': 0
             },
             'u.1.l.2.c.QG.i.2': {
                 'answer_counts': [0],
                 'label': ('Unit 1 Lesson 1, Question Group question_group '
                           'Question mcq_new'),
                 'location': 'unit?unit=1&lesson=2',
                 'num_attempts': 0,
                 'score': 0
             }
         }
     )
     assert_equals(
         tracker.get_id_to_assessments_dict(),
         {
             's.4.c.QN2': {
                 'answer_counts': [0],
                 'label': 'New assessment, Question mcq_new',
                 'location': 'assessment?name=4',
                 'num_attempts': 0,
                 'score': 0
             },
             's.4.c.QG2.i.0': {
                 'answer_counts': [0],
                 'label': ('New assessment, Question Group question_group '
                           'Question mcq_new'),
                 'location': 'assessment?name=4',
                 'num_attempts': 0,
                 'score': 0
             },
             's.4.c.QG2.i.2': {
                 'answer_counts': [0],
                 'label': ('New assessment, Question Group question_group '
                           'Question mcq_new'),
                 'location': 'assessment?name=4',
                 'num_attempts': 0,
                 'score': 0
             }
         }
     )
    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()
Ejemplo n.º 3
0
    def test_get_entity_id_wrapper_in_progress_works(self):
        """Tests get_entity_id wrappers in progress.ProgressStats."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])
        progress_stats = ProgressStats(course)
        unit1 = course.add_unit()

        # pylint: disable-msg=protected-access
        assert_equals(
            progress_stats._get_unit_ids_of_type_unit(), [unit1.unit_id])
        assessment1 = course.add_assessment()
        assert_equals(
            progress_stats._get_assessment_ids(), [assessment1.unit_id])
        lesson11 = course.add_lesson(unit1)
        lesson12 = course.add_lesson(unit1)
        assert_equals(
            progress_stats._get_lesson_ids(unit1.unit_id),
            [lesson11.lesson_id, lesson12.lesson_id])
        lesson11.has_activity = True
        course.set_activity_content(lesson11, u'var activity=[]', [])
        assert_equals(
            progress_stats._get_activity_ids(unit1.unit_id, lesson11.lesson_id),
            [0])
        assert_equals(
            progress_stats._get_activity_ids(unit1.unit_id, lesson12.lesson_id),
            [])
    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()
Ejemplo n.º 5
0
 def test_compute_entity_dict_constructs_dict_correctly(self):
     sites.setup_courses('course:/test::ns_test, course:/:/')
     course = courses.Course(None, app_context=sites.get_all_courses()[0])
     progress_stats = ProgressStats(course)
     course_dict = progress_stats.compute_entity_dict('course', [])
     assert_equals(course_dict, {
         'label': 'UNTITLED COURSE', 'u': {}, 's': {}})
Ejemplo n.º 6
0
    def test_empty_student_progress_stats_analytics_displays_nothing(self):
        """Test analytics page on course dashboard when no progress stats."""

        # The admin looks at the analytics page on the board to check right
        # message when no progress has been recorded.

        email = '*****@*****.**'
        actions.login(email, is_admin=True)
        response = self.get('dashboard?action=analytics')
        assert_contains(
            'Google > Dashboard > 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: 0', response.body)
        assert_contains('total: 0', response.body)

        assert_contains('Student Progress Statistics', response.body)
        assert_contains(
            'No student progress has been recorded for this course.',
            response.body)
        actions.logout()
Ejemplo n.º 7
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)
Ejemplo n.º 8
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 = {}
Ejemplo n.º 9
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)
    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()
Ejemplo n.º 11
0
    def test_get_entity_id_wrapper_in_progress_works(self):
        """Tests get_entity_id wrappers in progress.ProgressStats."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])
        progress_stats = ProgressStats(course)
        unit1 = course.add_unit()

        assert_equals(
            progress_stats._get_unit_ids_of_type_unit(), [unit1.unit_id])
        assessment1 = course.add_assessment()
        assert_equals(
            progress_stats._get_assessment_ids(), [assessment1.unit_id])
        lesson11 = course.add_lesson(unit1)
        lesson12 = course.add_lesson(unit1)
        assert_equals(
            progress_stats._get_lesson_ids(unit1.unit_id),
            [lesson11.lesson_id, lesson12.lesson_id])
        lesson11.has_activity = True
        course.set_activity_content(lesson11, u'var activity=[]', [])
        assert_equals(
            progress_stats._get_activity_ids(unit1.unit_id, lesson11.lesson_id),
            [0])
        assert_equals(
            progress_stats._get_activity_ids(unit1.unit_id, lesson12.lesson_id),
            [])
Ejemplo n.º 12
0
 def test_compute_entity_dict_constructs_dict_correctly(self):
     sites.setup_courses('course:/test::ns_test, course:/:/')
     course = courses.Course(None, app_context=sites.get_all_courses()[0])
     progress_stats = ProgressStats(course)
     course_dict = progress_stats.compute_entity_dict('course', [])
     assert_equals(course_dict, {
         'label': 'UNTITLED COURSE', 'u': {}, 's': {}})
Ejemplo n.º 13
0
 def test_id_to_question_dict_constructed_correctly(self):
     """Tests id_to_question dicts are constructed correctly."""
     course = self._get_sample_v15_course()
     tracker = UnitLessonCompletionTracker(course)
     assert_equals(
         tracker.get_id_to_questions_dict(),
         {
             'u.1.l.2.c.QN': {
                 'answer_counts': [0],
                 'label': 'Unit 1 Lesson 1, Question mcq_new',
                 'location': 'unit?unit=1&lesson=2',
                 'num_attempts': 0,
                 'score': 0
             },
             'u.1.l.2.c.QG.i.0': {
                 'answer_counts': [0],
                 'label': ('Unit 1 Lesson 1, Question Group question_group '
                           'Question mcq_new'),
                 'location': 'unit?unit=1&lesson=2',
                 'num_attempts': 0,
                 'score': 0
             },
             'u.1.l.2.c.QG.i.2': {
                 'answer_counts': [0],
                 'label': ('Unit 1 Lesson 1, Question Group question_group '
                           'Question mcq_new'),
                 'location': 'unit?unit=1&lesson=2',
                 'num_attempts': 0,
                 'score': 0
             }
         }
     )
     assert_equals(
         tracker.get_id_to_assessments_dict(),
         {
             's.4.c.QN2': {
                 'answer_counts': [0],
                 'label': 'New assessment, Question mcq_new',
                 'location': 'assessment?name=4',
                 'num_attempts': 0,
                 'score': 0
             },
             's.4.c.QG2.i.0': {
                 'answer_counts': [0],
                 'label': ('New assessment, Question Group question_group '
                           'Question mcq_new'),
                 'location': 'assessment?name=4',
                 'num_attempts': 0,
                 'score': 0
             },
             's.4.c.QG2.i.2': {
                 'answer_counts': [0],
                 'label': ('New assessment, Question Group question_group '
                           'Question mcq_new'),
                 'location': 'assessment?name=4',
                 'num_attempts': 0,
                 'score': 0
             }
         }
     )
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
    def test_compute_question_stats_on_empty_course_returns_empty_dicts(self):

        sites.setup_courses('course:/test::ns_test, course:/:/')
        app_context = sites.get_all_courses()[0]

        question_stats_computer = analytics.ComputeQuestionStats(app_context)
        id_to_questions, id_to_assessments = question_stats_computer.run()
        assert_equals({}, id_to_questions)
        assert_equals({}, id_to_assessments)
Ejemplo n.º 16
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)
    def test_compute_question_stats_on_empty_course_returns_empty_dicts(self):

        sites.setup_courses('course:/test::ns_test, course:/:/')
        app_context = sites.get_all_courses()[0]

        question_stats_computer = (
            synchronous_providers.QuestionStatsGenerator(app_context))
        id_to_questions, id_to_assessments = question_stats_computer.run()
        assert_equals({}, id_to_questions)
        assert_equals({}, id_to_assessments)
Ejemplo n.º 18
0
    def test_compute_question_stats_on_empty_course_returns_empty_dicts(self):

        sites.setup_courses('course:/test::ns_test, course:/:/')
        app_context = sites.get_all_courses()[0]

        question_stats_computer = (
            synchronous_providers.QuestionStatsGenerator(app_context))
        id_to_questions, id_to_assessments = question_stats_computer.run()
        assert_equals({}, id_to_questions)
        assert_equals({}, id_to_assessments)
Ejemplo n.º 19
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
Ejemplo n.º 20
0
    def validate_course_data(self, course):
        """Check course data is valid."""

        old_namespace = namespace_manager.get_namespace()
        namespace_manager.set_namespace(course.namespace)
        try:
            students = models.Student.all().fetch(1000)
            assert len(students) == 1
            for student in students:
                assert_equals(course.email, student.key().name())
                assert_equals(course.name, student.name)
        finally:
            namespace_manager.set_namespace(old_namespace)
Ejemplo n.º 21
0
    def validate_course_data(self, course):
        """Check course data is valid."""

        old_namespace = namespace_manager.get_namespace()
        namespace_manager.set_namespace(course.namespace)
        try:
            students = models.Student.all().fetch(1000)
            assert len(students) == 1
            for student in students:
                assert_equals(course.email, student.key().name())
                assert_equals(course.name, student.name)
        finally:
            namespace_manager.set_namespace(old_namespace)
Ejemplo n.º 22
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)
Ejemplo n.º 23
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 test_get_summarized_question_list_from_event(self):
        """Tests the transform functions per event type."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])

        question_aggregator = (synchronous_providers.QuestionStatsGenerator.
                               MultipleChoiceQuestionAggregator(course))

        event_payloads = open(
            os.path.join(appengine_config.BUNDLE_ROOT,
                         'tests/unit/common/event_payloads.json')).read()

        event_payload_dict = transforms.loads(event_payloads)
        for event_info in event_payload_dict.values():
            questions = question_aggregator._process_event(
                event_info['event_source'], event_info['event_data'])
            assert_equals(questions, event_info['transformed_dict_list'])
Ejemplo n.º 25
0
    def test_anonymous_access(self):
        """Tests for disabled course explorer page."""

        # disable the explorer
        config.Registry.test_overrides[
            course_explorer.GCB_ENABLE_COURSE_EXPLORER_PAGE.name] = False
        self.assertFalse(course_explorer.GCB_ENABLE_COURSE_EXPLORER_PAGE.value)

        # check root URL's properly redirect to login
        response = self.get('/')
        assert_equals(response.status_int, 302)
        assert_contains(
            'http://localhost/admin?action=welcome', response.location)

        response = self.get('/assets/img/your_logo_here.png')
        assert_equals(response.status_int, 302)
        assert_contains('accounts/Login', response.location)

        # check explorer pages are not accessible
        not_accessibles = [
            '/explorer',
            '/explorer/courses',
            '/explorer/profile',
            '/explorer/assets/img/your_logo_here.png']
        for not_accessible in not_accessibles:
            response = self.get(not_accessible, expect_errors=True)
            assert_equals(response.status_int, 404)

        # enable course explorer
        config.Registry.test_overrides[
            course_explorer.GCB_ENABLE_COURSE_EXPLORER_PAGE.name] = True
        self.assertTrue(course_explorer.GCB_ENABLE_COURSE_EXPLORER_PAGE.value)

        # check explorer pages are accessible
        accessibles = [
            '/explorer',
            '/explorer/courses',
            '/explorer/assets/img/your_logo_here.png']
        for accessible in accessibles:
            response = self.get(accessible, expect_errors=True)
            assert_equals(response.status_int, 200)

        # check student pages are not accessible
        response = self.get('/explorer/profile')
        assert_equals(response.status_int, 302)
        self.assertEqual('http://localhost/explorer', response.location)
Ejemplo n.º 26
0
    def test_static_files_cache_control(self):
        """Test static/zip handlers use proper Cache-Control headers."""

        # Check static handler.
        response = self.get('/assets/css/main.css')
        assert_equals(response.status_int, 200)
        assert_contains('max-age=600', response.headers['Cache-Control'])
        assert_contains('public', response.headers['Cache-Control'])
        assert_does_not_contain('no-cache', response.headers['Cache-Control'])

        # Check zip file handler.
        response = self.get(
            '/static/inputex-3.1.0/src/inputex/assets/skins/sam/inputex.css')
        assert_equals(response.status_int, 200)
        assert_contains('max-age=600', response.headers['Cache-Control'])
        assert_contains('public', response.headers['Cache-Control'])
        assert_does_not_contain('no-cache', response.headers['Cache-Control'])
Ejemplo n.º 27
0
    def submit_assessment(self, name, args):
        """Test student taking an assessment."""

        response = self.get('assessment?name=%s' % name)
        assert_contains(
            '<script src="assets/js/assessment-%s.js"></script>' % name,
            response.body)

        # Extract XSRF token from the page.
        match = re.search(r'assessmentXsrfToken = [\']([^\']+)', response.body)
        assert match
        xsrf_token = match.group(1)
        args['xsrf_token'] = xsrf_token

        response = self.post('answer', args)
        assert_equals(response.status_int, 200)
        return response
Ejemplo n.º 28
0
    def test_anonymous_access(self):
        """Tests for disabled course explorer page."""

        # disable the explorer
        config.Registry.test_overrides[
            course_explorer.GCB_ENABLE_COURSE_EXPLORER_PAGE.name] = False
        self.assertFalse(course_explorer.GCB_ENABLE_COURSE_EXPLORER_PAGE.value)

        # check root URL's properly redirect to login
        response = self.get('/')
        assert_equals(response.status_int, 302)
        assert_contains(
            'http://localhost/admin/welcome', response.location)

        response = self.get('/assets/img/your_logo_here.png')
        assert_equals(response.status_int, 302)
        assert_contains('accounts/Login', response.location)

        # check explorer pages are not accessible
        not_accessibles = [
            '/explorer',
            '/explorer/courses',
            '/explorer/profile',
            '/explorer/assets/img/your_logo_here.png']
        for not_accessible in not_accessibles:
            response = self.get(not_accessible, expect_errors=True)
            assert_equals(response.status_int, 404)

        # enable course explorer
        config.Registry.test_overrides[
            course_explorer.GCB_ENABLE_COURSE_EXPLORER_PAGE.name] = True
        self.assertTrue(course_explorer.GCB_ENABLE_COURSE_EXPLORER_PAGE.value)

        # check explorer pages are accessible
        accessibles = [
            '/explorer',
            '/explorer/courses',
            '/explorer/assets/img/your_logo_here.png']
        for accessible in accessibles:
            response = self.get(accessible, expect_errors=True)
            assert_equals(response.status_int, 200)

        # check student pages are not accessible
        response = self.get('/explorer/profile')
        assert_equals(response.status_int, 302)
        self.assertEqual('http://localhost/explorer', response.location)
    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)
Ejemplo n.º 30
0
    def submit_assessment(self, name, args):
        """Test student taking an assessment."""

        response = self.get('assessment?name=%s' % name)
        assert_contains(
            '<script src="assets/js/assessment-%s.js"></script>' % name,
            response.body)

        # Extract XSRF token from the page.
        match = re.search(r'assessmentXsrfToken = [\']([^\']+)', response.body)
        assert match
        xsrf_token = match.group(1)
        args['xsrf_token'] = xsrf_token

        response = self.post('answer', args)
        assert_equals(response.status_int, 200)
        return response
Ejemplo n.º 31
0
    def test_get_summarized_question_list_from_event(self):
        """Tests the transform functions per event type."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])

        question_aggregator = (synchronous_providers.QuestionStatsGenerator
                               .MultipleChoiceQuestionAggregator(course))

        event_payloads = open(os.path.join(
            appengine_config.BUNDLE_ROOT,
            'tests/unit/common/event_payloads.json')).read()

        event_payload_dict = transforms.loads(event_payloads)
        for event_info in event_payload_dict.values():
            questions = question_aggregator._process_event(
                event_info['event_source'], event_info['event_data'])
            assert_equals(questions, event_info['transformed_dict_list'])
    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)
Ejemplo n.º 33
0
    def test_static_files_cache_control(self):
        """Test static/zip handlers use proper Cache-Control headers."""

        # Check static handler.
        response = self.get('/assets/css/main.css')
        assert_equals(response.status_int, 200)
        assert_contains('max-age=600', response.headers['Cache-Control'])
        assert_contains('public', response.headers['Cache-Control'])
        assert_does_not_contain('no-cache', response.headers['Cache-Control'])

        # Check zip file handler.
        response = self.get(
            '/static/inputex-3.1.0/src/inputex/assets/skins/sam/inputex.css')
        assert_equals(response.status_int, 200)
        assert_contains('max-age=600', response.headers['Cache-Control'])
        assert_contains('public', response.headers['Cache-Control'])
        assert_does_not_contain('no-cache', response.headers['Cache-Control'])
Ejemplo n.º 34
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 = {}
Ejemplo n.º 35
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)
Ejemplo n.º 36
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)
Ejemplo n.º 37
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)
Ejemplo n.º 38
0
    def test_get_entity_label_wrapper_in_progress_works(self):
        """Tests get_entity_label wrappers in progress.ProgressStats."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])
        progress_stats = ProgressStats(course)
        unit1 = course.add_unit()

        # pylint: disable-msg=protected-access
        assert_equals(
            progress_stats._get_unit_label(unit1.unit_id),
            'Unit %s' % unit1.index)
        assessment1 = course.add_assessment()
        assert_equals(
            progress_stats._get_assessment_label(assessment1.unit_id),
            assessment1.title)
        lesson11 = course.add_lesson(unit1)
        lesson12 = course.add_lesson(unit1)
        assert_equals(
            progress_stats._get_lesson_label(unit1.unit_id, lesson11.lesson_id),
            lesson11.index)
        lesson11.has_activity = True
        course.set_activity_content(lesson11, u'var activity=[]', [])
        assert_equals(
            progress_stats._get_activity_label(
                unit1.unit_id, lesson11.lesson_id, 0), 'L1.1')
        assert_equals(
            progress_stats._get_activity_label(
                unit1.unit_id, lesson12.lesson_id, 0), 'L1.2')
        lesson12.objectives = """
            <question quid="123" weight="1" instanceid=1></question>
            random_text
            <gcb-youtube videoid="Kdg2drcUjYI" instanceid="VD"></gcb-youtube>
            more_random_text
            <question-group qgid="456" instanceid=2></question-group>
            yet_more_random_text
        """
        cpt_ids = progress_stats._get_component_ids(
            unit1.unit_id, lesson12.lesson_id, 0)
        self.assertEqual(set([u'1', u'2']), set(cpt_ids))
    def test_get_entity_label_wrapper_in_progress_works(self):
        """Tests get_entity_label wrappers in progress.ProgressStats."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])
        progress_stats = ProgressStats(course)
        unit1 = course.add_unit()

        # pylint: disable-msg=protected-access
        assert_equals(progress_stats._get_unit_label(unit1.unit_id),
                      'Unit %s' % unit1.index)
        assessment1 = course.add_assessment()
        assert_equals(
            progress_stats._get_assessment_label(assessment1.unit_id),
            assessment1.title)
        lesson11 = course.add_lesson(unit1)
        lesson12 = course.add_lesson(unit1)
        assert_equals(
            progress_stats._get_lesson_label(unit1.unit_id,
                                             lesson11.lesson_id),
            lesson11.index)
        lesson11.has_activity = True
        course.set_activity_content(lesson11, u'var activity=[]', [])
        assert_equals(
            progress_stats._get_activity_label(unit1.unit_id,
                                               lesson11.lesson_id, 0), 'L1.1')
        assert_equals(
            progress_stats._get_activity_label(unit1.unit_id,
                                               lesson12.lesson_id, 0), 'L1.2')
        lesson12.objectives = """
            <question quid="123" weight="1" instanceid=1></question>
            random_text
            <gcb-youtube videoid="Kdg2drcUjYI" instanceid="VD"></gcb-youtube>
            more_random_text
            <question-group qgid="456" instanceid=2></question-group>
            yet_more_random_text
        """
        cpt_ids = progress_stats._get_component_ids(unit1.unit_id,
                                                    lesson12.lesson_id, 0)
        self.assertEqual(set([u'1', u'2']), set(cpt_ids))
Ejemplo n.º 40
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)
Ejemplo n.º 42
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)
Ejemplo n.º 43
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)
Ejemplo n.º 44
0
    def test_python_console(self):
        """Test access rights to the Python console."""

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

        # Check normal user has no access.
        actions.login(email)
        response = self.testapp.get('/admin?action=console')
        assert_equals(response.status_int, 302)

        response = self.testapp.post('/admin?action=console')
        assert_equals(response.status_int, 302)

        # Check delegated admin has no access.
        os.environ['gcb_admin_user_emails'] = '[%s]' % email
        actions.login(email)
        response = self.testapp.get('/admin?action=console')
        assert_equals(response.status_int, 200)
        assert_contains(
            'You must be an actual admin user to continue.', response.body)

        response = self.testapp.get('/admin?action=console')
        assert_equals(response.status_int, 200)
        assert_contains(
            'You must be an actual admin user to continue.', response.body)

        del os.environ['gcb_admin_user_emails']

        # Check actual admin has access.
        actions.login(email, True)
        response = self.testapp.get('/admin?action=console')
        assert_equals(response.status_int, 200)

        response.form.set('code', 'print "foo" + "bar"')
        response = self.submit(response.form)
        assert_contains('foobar', response.body)
Ejemplo n.º 45
0
    def test_python_console(self):
        """Test access rights to the Python console."""

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

        # Check normal user has no access.
        actions.login(email)
        response = self.testapp.get('/admin?action=console')
        assert_equals(response.status_int, 302)

        response = self.testapp.post('/admin?action=console')
        assert_equals(response.status_int, 302)

        # Check delegated admin has no access.
        os.environ['gcb_admin_user_emails'] = '[%s]' % email
        actions.login(email)
        response = self.testapp.get('/admin?action=console')
        assert_equals(response.status_int, 200)
        assert_contains(
            'You must be an actual admin user to continue.', response.body)

        response = self.testapp.get('/admin?action=console')
        assert_equals(response.status_int, 200)
        assert_contains(
            'You must be an actual admin user to continue.', response.body)

        del os.environ['gcb_admin_user_emails']

        # Check actual admin has access.
        actions.login(email, True)
        response = self.testapp.get('/admin?action=console')
        assert_equals(response.status_int, 200)

        response.form.set('code', 'print "foo" + "bar"')
        response = self.submit(response.form)
        assert_contains('foobar', response.body)
Ejemplo n.º 46
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)
Ejemplo n.º 47
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)
Ejemplo n.º 48
0
    def test_admin_list(self):
        """Test delegation of admin access to another user."""

        email = '*****@*****.**'
        actions.login(email)

        # Add environment variable override.
        os.environ['gcb_admin_user_emails'] = '[%s]' % email

        # Add datastore override.
        prop = config.ConfigPropertyEntity(
            key_name='gcb_config_update_interval_sec')
        prop.value = '5'
        prop.is_draft = False
        prop.put()

        # Check user has access now.
        response = self.testapp.get('/admin?action=settings')
        assert_equals(response.status_int, 200)

        # Check overrides are active and have proper management actions.
        assert_contains('gcb_admin_user_emails', response.body)
        assert_contains('[[email protected]]', response.body)
        assert_contains(
            '/admin?action=config_override&name=gcb_admin_user_emails',
            response.body)
        assert_contains(
            '/admin?action=config_edit&name=gcb_config_update_interval_sec',
            response.body)

        # Check editor page has proper actions.
        response = self.testapp.get(
            '/admin?action=config_edit&name=gcb_config_update_interval_sec')
        assert_equals(response.status_int, 200)
        assert_contains('/admin?action=config_reset', response.body)
        assert_contains('name=gcb_config_update_interval_sec', response.body)

        # Remove override.
        del os.environ['gcb_admin_user_emails']

        # Check user has no access.
        response = self.testapp.get('/admin?action=settings')
        assert_equals(response.status_int, 302)
Ejemplo n.º 49
0
    def test_admin_list(self):
        """Test delegation of admin access to another user."""

        email = '*****@*****.**'
        actions.login(email)

        # Add environment variable override.
        os.environ['gcb_admin_user_emails'] = '[%s]' % email

        # Add datastore override.
        prop = config.ConfigPropertyEntity(
            key_name='gcb_config_update_interval_sec')
        prop.value = '5'
        prop.is_draft = False
        prop.put()

        # Check user has access now.
        response = self.testapp.get('/admin?action=settings')
        assert_equals(response.status_int, 200)

        # Check overrides are active and have proper management actions.
        assert_contains('gcb_admin_user_emails', response.body)
        assert_contains('[[email protected]]', response.body)
        assert_contains(
            '/admin?action=config_override&name=gcb_admin_user_emails',
            response.body)
        assert_contains(
            '/admin?action=config_edit&name=gcb_config_update_interval_sec',
            response.body)

        # Check editor page has proper actions.
        response = self.testapp.get(
            '/admin?action=config_edit&name=gcb_config_update_interval_sec')
        assert_equals(response.status_int, 200)
        assert_contains('/admin?action=config_reset', response.body)
        assert_contains('name=gcb_config_update_interval_sec', response.body)

        # Remove override.
        del os.environ['gcb_admin_user_emails']

        # Check user has no access.
        response = self.testapp.get('/admin?action=settings')
        assert_equals(response.status_int, 302)
Ejemplo n.º 50
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()
Ejemplo n.º 51
0
    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)
        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)
        assert_contains('Your review has been saved.', response.body)

        response = self.get('reviewdashboard?unit=%s' % LEGACY_REVIEW_UNIT_ID)
        assert_equals(response.status_int, 200)
        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)
        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)
        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)
        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_contains('Assignment to review', response.body)
        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)
        assert_equals(response.status_int, 200)
        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)
        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)
        assert_contains('Your review has been submitted successfully',
                        response.body)

        response = self.get('/reviewdashboard?unit=%s' % LEGACY_REVIEW_UNIT_ID)
        assert_contains('(Completed)', response.body)
        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)
        assert_equals(response.status_int, 200)
        assert_contains('You have not received any peer reviews yet.',
                        response.body)
        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))
        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'))
        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))
        assert_contains('Submitted review', response.body)
        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)
        assert_equals(response.status_int, 200)
        assert_contains('R2for1', response.body)
Ejemplo n.º 52
0
    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
            },
        ])

        # Check that the sample peer-review assignment shows up in the preview
        # page.
        response = actions.view_preview(self)
        assert_contains('Sample peer review assignment', response.body)
        assert_does_not_contain('Review peer assignments', response.body)

        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)
        assert_contains('Sample peer review assignment', response.body)
        assert_contains('Review peer assignments', response.body)
        assert_contains(
            '<a href="assessment?name=%s">' % LEGACY_REVIEW_UNIT_ID,
            response.body)
        assert_contains('<span> Review peer assignments </span>',
                        response.body,
                        collapse_whitespace=True)
        assert_does_not_contain('<a href="reviewdashboard',
                                response.body,
                                collapse_whitespace=True)

        # Check that the progress circle for this assignment is unfilled.
        assert_contains('progress-notstarted-%s' % LEGACY_REVIEW_UNIT_ID,
                        response.body)
        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)
        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)
        assert_does_not_contain('Submitted assignment', response.body)
        assert_contains('Due date for this assignment', response.body)
        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)
        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
            })
        assert_contains('Thank you for completing this assignment',
                        response.body)
        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)
        assert_contains('First answer to Q1', response.body)
        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)
        assert_contains('You have already submitted this assignment.',
                        response.body)
        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)
        assert_contains('First answer to Q1', response.body)
        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)
        assert_contains('progress-completed-%s' % LEGACY_REVIEW_UNIT_ID,
                        response.body)
        assert_does_not_contain('<span> Review peer assignments </span>',
                                response.body,
                                collapse_whitespace=True)
        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)
        assert_contains('Assignments for your review', response.body)
        assert_contains('Review a new assignment', response.body)

        actions.logout()

        # Clean up app_context.
        sites.ApplicationContext.get_environ = get_environ_old
Ejemplo n.º 53
0
 def test_compute_entity_dict_constructs_dict_for_empty_course_correctly(
     self):
     """Tests correct entity_structure is built."""
     sites.setup_courses('course:/test::ns_test, course:/:/')
     course = courses.Course(None, app_context=sites.get_all_courses()[0])
     unit1 = course.add_unit()
     assessment1 = course.add_assessment()
     progress_stats = ProgressStats(course)
     assert_equals(
         progress_stats.compute_entity_dict('course', []),
         {'label': 'UNTITLED COURSE', 'u': {unit1.unit_id: {
             'label': 'Unit %s' % unit1.index, 'l': {}}}, 's': {
                 assessment1.unit_id: {'label': assessment1.title}}})
     lesson11 = course.add_lesson(unit1)
     assert_equals(
         progress_stats.compute_entity_dict('course', []),
         {
             "s": {
                 assessment1.unit_id: {
                     "label": assessment1.title
                 }
             },
             "u": {
                 unit1.unit_id: {
                     "l": {
                         lesson11.lesson_id: {
                             "a": {},
                             "h": {
                                 0: {
                                     "c": {},
                                     "label": "L1.1"
                                 }
                             },
                             "label": lesson11.index
                         }
                     },
                     "label": "Unit %s" % unit1.index
                 }
             },
             'label': 'UNTITLED COURSE'
         })
     lesson11.objectives = """
         <question quid="123" weight="1" instanceid="1"></question>
         random_text
         <gcb-youtube videoid="Kdg2drcUjYI" instanceid="VD"></gcb-youtube>
         more_random_text
         <question-group qgid="456" instanceid="2"></question-group>
         yet_more_random_text
     """
     assert_equals(
         progress_stats.compute_entity_dict('course', []),
         {
             "s": {
                 assessment1.unit_id: {
                     "label": assessment1.title
                 }
             },
             "u": {
                 unit1.unit_id: {
                     "l": {
                         lesson11.lesson_id: {
                             "a": {},
                             "h": {
                                 0: {
                                     "c": {
                                         u'1': {
                                             "label": "L1.1.1"
                                         },
                                         u'2': {
                                             "label": "L1.1.2"
                                         }
                                     },
                                     "label": "L1.1"
                                 }
                             },
                             "label": lesson11.index
                         }
                     },
                     "label": "Unit %s" % unit1.index
                 }
             },
             "label": 'UNTITLED COURSE'
         })
Ejemplo n.º 54
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()
    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},
        ])

        # Check that the sample peer-review assignment shows up in the preview
        # page.
        response = actions.view_preview(self)
        assert_contains('Sample peer review assignment', response.body)
        assert_does_not_contain('Review peer assignments', response.body)

        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)
        assert_contains('Sample peer review assignment', response.body)
        assert_contains('Review peer assignments', response.body)
        assert_contains(
            '<a href="assessment?name=%s">' % LEGACY_REVIEW_UNIT_ID,
            response.body)
        assert_contains('<span> Review peer assignments </span>', response.body,
                        collapse_whitespace=True)
        assert_does_not_contain('<a href="reviewdashboard', response.body,
                                collapse_whitespace=True)

        # Check that the progress circle for this assignment is unfilled.
        assert_contains(
            'progress-notstarted-%s' % LEGACY_REVIEW_UNIT_ID, response.body)
        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)
        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)
        assert_does_not_contain('Submitted assignment', response.body)
        assert_contains('Due date for this assignment', response.body)
        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)
        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}
        )
        assert_contains(
            'Thank you for completing this assignment', response.body)
        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)
        assert_contains('First answer to Q1', response.body)
        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
        )
        assert_contains(
            'You have already submitted this assignment.', response.body)
        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)
        assert_contains('First answer to Q1', response.body)
        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)
        assert_contains(
            'progress-completed-%s' % LEGACY_REVIEW_UNIT_ID, response.body)
        assert_does_not_contain(
            '<span> Review peer assignments </span>', response.body,
            collapse_whitespace=True)
        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)
        assert_contains('Assignments for your review', response.body)
        assert_contains('Review a new assignment', response.body)

        actions.logout()

        # Clean up app_context.
        sites.ApplicationContext.get_environ = get_environ_old
Ejemplo n.º 56
0
 def test_compute_entity_dict_constructs_dict_for_empty_course_correctly(
     self):
     """Tests correct entity_structure is built."""
     sites.setup_courses('course:/test::ns_test, course:/:/')
     course = courses.Course(None, app_context=sites.get_all_courses()[0])
     unit1 = course.add_unit()
     assessment1 = course.add_assessment()
     progress_stats = ProgressStats(course)
     # pylint: disable-msg=g-inconsistent-quotes
     assert_equals(
         progress_stats.compute_entity_dict('course', []),
         {'label': 'UNTITLED COURSE', 'u': {unit1.unit_id: {
             'label': 'Unit %s' % unit1.index, 'l': {}}}, 's': {
                 assessment1.unit_id: {'label': assessment1.title}}})
     lesson11 = course.add_lesson(unit1)
     assert_equals(
         progress_stats.compute_entity_dict('course', []),
         {
             "s": {
                 assessment1.unit_id: {
                     "label": assessment1.title
                 }
             },
             "u": {
                 unit1.unit_id: {
                     "l": {
                         lesson11.lesson_id: {
                             "a": {},
                             "h": {
                                 0: {
                                     "c": {},
                                     "label": "L1.1"
                                 }
                             },
                             "label": lesson11.index
                         }
                     },
                     "label": "Unit %s" % unit1.index
                 }
             },
             'label': 'UNTITLED COURSE'
         })
     lesson11.objectives = """
         <question quid="123" weight="1" instanceid="1"></question>
         random_text
         <gcb-youtube videoid="Kdg2drcUjYI" instanceid="VD"></gcb-youtube>
         more_random_text
         <question-group qgid="456" instanceid="2"></question-group>
         yet_more_random_text
     """
     assert_equals(
         progress_stats.compute_entity_dict('course', []),
         {
             "s": {
                 assessment1.unit_id: {
                     "label": assessment1.title
                 }
             },
             "u": {
                 unit1.unit_id: {
                     "l": {
                         lesson11.lesson_id: {
                             "a": {},
                             "h": {
                                 0: {
                                     "c": {
                                         u'1': {
                                             "label": "L1.1.1"
                                         },
                                         u'2': {
                                             "label": "L1.1.2"
                                         }
                                     },
                                     "label": "L1.1"
                                 }
                             },
                             "label": lesson11.index
                         }
                     },
                     "label": "Unit %s" % unit1.index
                 }
             },
             "label": 'UNTITLED COURSE'
         })